Skip to content

Latest commit

 

History

History
141 lines (109 loc) · 6.1 KB

File metadata and controls

141 lines (109 loc) · 6.1 KB

Official SDKs

Client libraries for the AgentContextOS gateway, in five languages. This page is the public reference (install + usage) and the technical reference (generation pipeline + status) for all of them.

Overview

SDK Package Path Status
Python agentcontextos sdks/python hand-written, tested
TypeScript @agentcontextos/sdk sdks/typescript hand-written, tested
Go agentcontextos sdks/go generated
Java com.agentcontextos:agentcontextos-sdk sdks/java generated
.NET AgentContextOS.Sdk sdks/dotnet generated

All five are produced from two contracts:

  • REST — the OpenAPI 3.1 spec at dist/openapi.json (covers /v1/query, /v1/retrieve, /v1/corpora, /v1/ingest/document, /v1/embeddings, /v1/chat/completions, /v1/models, /v1/agent).
  • gRPCproto/rag.proto's RagService.

Identity

Every SDK applies identity the way each route expects, so callers configure it once:

  • Body identity/v1/query, /v1/retrieve, /v1/agent carry tenant_id / principal_id in the request body.
  • Header identity/v1/corpora, /v1/embeddings, /v1/chat/completions, /v1/models read Authorization: Bearer <token> (production) or X-Tenant-Id / X-Principal-Id (dev) headers.

Configure tenant_id + principal_id for the dev/demo path, or api_key (+ tenant_id) for production. The SDK sends the bearer token in preference to the dev X-Principal-Id header when an api_key is set.

Usage — Python

from agentcontextos import Client, AsyncClient

with Client("http://localhost:8000", tenant_id="acme", principal_id="svc") as rag:
    hits = rag.retrieve("How do I rotate signing keys?", top_k=5)
    resp = rag.query("How do I rotate signing keys?", generate=True)
    chat = rag.chat([{"role": "user", "content": "Summarise the policy"}])
    for chunk in rag.stream_chat([{"role": "user", "content": "Explain HNSW"}]):
        print(chunk.choices[0].delta.content or "", end="")
    result = rag.agent("Find and summarise the on-call runbook")

async with AsyncClient(url, tenant_id="acme", principal_id="svc") as rag:
    resp = await rag.query("...")
    async for ev in rag.stream_agent("..."):
        print(ev.kind, ev.phase)

Errors raise an ApiError subclass keyed by status (BadRequestError, AuthenticationError, PermissionDeniedError, NotFoundError, RateLimitError, ServerError), each carrying .code, .message, .request_id. A failed agent run raises AgentRunError. Wire models are re-exported from agentcontextos.models.

Usage — TypeScript

import { AgentContextOSClient } from '@agentcontextos/sdk';

const rag = new AgentContextOSClient('http://localhost:8000', {
  tenantId: 'acme',
  principalId: 'svc',
});

const resp = await rag.query('How do I rotate signing keys?', { generate: true });
for await (const chunk of rag.streamChat([{ role: 'user', content: 'hi' }])) {
  process.stdout.write(chunk.choices[0]?.delta.content ?? '');
}
const result = await rag.agent('Find the on-call runbook');

Works in Node 18+ and browsers (platform fetch + ReadableStream, no runtime dependency). Errors reject with the same ApiError subclasses.

Usage — Go / Java / .NET

These are generated on demand (see below). After task sdk:gen, import the generated client from each SDK's package; the operation set mirrors the REST routes, and identity follows the same model. See each SDK's README: Go, Java, .NET.

Internals — generation pipeline

dist/openapi.json ──(openapi-generator-cli)──▶ sdks/{go,java,dotnet}/generated/   (REST client)
proto/rag.proto   ──(buf generate)───────────▶ sdks/{go,java,dotnet}/.../gen      (gRPC stubs)

Commands (repo root):

task openapi:gen        # re-export dist/openapi.{json,yaml} from the live app
task openapi:check-drift # CI gate: fail if the committed spec is stale
task sdk:gen            # both halves, all generated languages
task sdk:gen-proto      # gRPC stubs only (needs buf)
task sdk:gen-openapi    # REST clients only (needs openapi-generator-cli + a JRE)

scripts/export_openapi.py runs build_app().openapi() with default noop SPIs (no infrastructure) and writes a byte-stable, sorted spec. scripts/gen_sdks.py orchestrates buf + openapi-generator-cli, detects a missing toolchain and prints an install hint (skip by default, --strict to fail). The generator version is pinned in openapitools.json.

Internals — why two strategies

See ADR-0016. In short: Python and TypeScript are hand-written flagships (idiomatic ergonomics, full streaming, tested against a live gateway); Go/Java/.NET are generated to keep marginal maintenance near zero. The committed spec is drift-gated; the generated SDK source is a gitignored build artifact.

Extension points

  • Add a generated language — add its openapi-generator generator name to OPENAPI_GENERATORS in scripts/gen_sdks.py, a buf.gen.yaml plugin block, an sdks/<lang>/openapi-generator-config.yaml, and a scaffold README + .gitignore.
  • Evolve the REST surface — the spec is auto-derived from FastAPI routes + rag_core models; run task openapi:gen and commit. Regenerate the SDKs with task sdk:gen.
  • Evolve the hand-written SDKs — request builders live in agentcontextos._core (Python) / client.ts (TS); add a method per new route and a test against the in-process gateway (Python) / a fetch stub (TS).

See also