SEIF Docs

Integration API — seif.context-runtime.v1

Small, stable, provider-neutral, language-neutral HTTP + JSON. Full schema: openapi.json in every bundle (GET /openapi.json).

POST /v1/context/resolve

{ "consumer": "support-agent", "objective": "answer-customer", "environment": "development",
  "correlationId": "ticket-1234",
  "input": { "message": "How do I get a refund on our annual Pro plan?", "customerId": "CUST-1042" } }

Only consumer is required. objective defaults to the consumer's default objective. environment, when given, must match the Build. input carries the facts your layers use (message/query for retrieval, filter keys such as customerId).

{ "contract": "seif.context-runtime.v1", "status": "RESOLVED",
  "buildRef": "support-agent-context@1", "buildDigest": "sha256:…",
  "contextRef": "ctx_…", "traceRef": "tr_…",
  "consumer": "support-agent", "objective": "answer-customer", "environment": "development", "profile": "support-answer",
  "messages": [{ "role": "system", "content": "You are … # Context … ## Support policy …" }],
  "renderedDigest": "sha256:…",
  "materials": [{ "ref": "mat_…", "layer": "product-docs", "source": "knowledge-base", "locator": "docs/refunds.md",
                  "title": "Refunds and cancellations", "digest": "sha256:…", "revision": "git:32ba5f9…",
                  "estimatedTokens": 176, "reason": "RETRIEVED_RELEVANT", "rendered": true }],
  "expandable": [{ "ref": "mat_…", "layer": "history", "title": "Onboarding call request", "estimatedTokens": 16, "reason": "BEYOND_MAX_ITEMS" }],
  "layers": [{ "layer": "engineering-notes", "available": "AVAILABLE", "applicable": "APPLICABLE", "desired": "EXCLUDE",
               "selected": "NOT_SELECTED", "rendered": 0, "currentness": "NO_RULE", "reason": "EXCLUDED_BY_PROFILE" }],
  "unknowns": [], "provenance": [{ "source": "knowledge-base", "revision": "git:…", "materialBasis": "BUILD_EMBEDDED" }],
  "budget": { "unit": "estimated_tokens", "estimator": "ceil(chars/4)", "used": 1330, "limit": 3000, "byLayer": {…}, "trimmed": [] },
  "plan": { "status": "executable" }, "consumed": "UNKNOWN" }

status: RESOLVED, RESOLVED_WITH_UNKNOWNS (inspect unknowns), or BLOCKED (reason: MISSING_REQUIRED_CONTEXT, RENDERING_INCOMPLETE, REQUIRED_CONTEXT_TRIMMED (an item of a required layer did not fit the budget), REQUIRED_TOOL_UNAVAILABLE, BUDGET_EXCEEDED, PROFILE_UNRESOLVED, OBJECTIVE_UNRESOLVED). Errors: 400 BAD_REQUEST, 404 UNKNOWN_CONSUMER | UNKNOWN_OBJECTIVE, 409 ENVIRONMENT_MISMATCH, 415; each error response carries the traceRef of the recorded failure.

Use it:

context = resolve(...)
reply = model.generate(context["messages"] + [{"role": "user", "content": question}])

POST /v1/context/expand

{ "contextRef": "ctx_…", "ref": "mat_…" } → one bounded material plus a message to append. Only refs offered in expandable are accepted; a ref issued by another Build or for changed material is 409 STALE_REF (SEIF stale-ref rule). Recorded in the trace.

POST /v1/context/consumption (optional)

Report what you actually sent to your model:

{ "contextRef": "ctx_…", "consumer": "support-agent",
  "consumed": { "messages": [ …the context messages you sent… ] },
  "provider": { "name": "your-provider", "model": "your-model" }, "outcome": { "status": "completed" } }

or "consumed": { "digest": "sha256:<hex>" }, where the digest is SHA-256 over canonical JSON of [{"content": …, "role": …}] (sorted keys, no whitespace; Python: json.dumps(msgs, sort_keys=True, separators=(",", ":"), ensure_ascii=False)). The runtime records MATCHES_RENDERED or DIFFERS_FROM_RENDERED. A contextRef that is unknown (404) or belongs to another trace or consumer (409) is rejected, never guessed. Without a report, consumption stays UNKNOWN.

Observation

GET /v1/health, GET /v1/build (consumers, objectives, layers, unpinned dependencies), GET /v1/traces?after=&limit=, GET /v1/traces/{traceRef} (seif.observation-trace.v1).

Examples: examples/curl/resolve.sh, examples/python/support_agent.py (standard library only), examples/typescript/support-agent.ts.

Through a Registry environment (0.4.0)

Applications hold an application credential (Service identities) and call the stable environment endpoint instead of a runtime URL:

POST {registry}/v1/projects/{project}/environments/{environment}/context/resolve      (same body as above)
POST …/context/expand · …/context/consumption · …/context/outcome
SDK base URL: {registry}/v1/projects/{project}/environments/{environment}/runtime

New resolutions go only to the active ready deployment; the response adds deploymentId, environment, bindingRevision and providers (per live provider: status, code, item count, currentness, duration). Send deploymentId back on expand/consumption/outcome so a report reaches its originating deployment during a roll-forward. Add reportId (8–64 URL-safe characters) to make consumption and outcome idempotent: a retry returns the original record with duplicate: true. Errors: 403 capability/scope, 503 NO_ACTIVE_DEPLOYMENT/RUNTIME_UNAVAILABLE, 504 RUNTIME_TIMEOUT, 410 DEPLOYMENT_RETIRED. A live provider failure is not an error: the response is 200 with the layer UNAVAILABLE, an unknown, and providers[].status (e.g. TIMEOUT).