Skip to content

Build · execution ownership

SDK integrations

Keep your SDK's model loop in the app and ask for tool decisions, or move that loop into a Runkite runner and create managed Threads/Runs. Choose the boundary your caller needs. The frontend can remain in Next, Nuxt or another app.

Availability checked 2026-11-08. The latest published tag is v0.6.1, the first Apache-2.0 release. Published v0.6.0 artifacts retain BUSL-1.1. The decision API shipped in v0.5.3. The managed AI SDK runner ships in runkite-runner from v0.5.8 (optional peer ai@7.0.155). Repository helper guards and Microsoft function middleware remain unpublished as runkite-governance packages. See CHANGELOG before selecting a package version.

Published Python profiles: the v0.6.1 runkite-runner wheel includes managed Microsoft Agent Framework, OpenAI Agents SDK, Pydantic AI and Google ADK adapters, installed through optional extras with dedicated commands. The stock Python image keeps its LangGraph default and does not install these optional SDK dependencies.

Jump to LangGraph / LangGraph.js, Vercel AI SDK, Microsoft Agent Framework, OpenAI Agents SDK, Pydantic AI, Google ADK, managed chat and reconnect or app-owned tool decisions.

Choose the execution boundary

CallerApp keeps its loopRunkite dispatches the loop
Entry pointPOST /governance/decideAgent Protocol thread/run routes
Who executes a tool?Your app, after allow or later approvalThe SDK inside a runner; actual connector gates govern connector calls
Admin Threads/RunsNo records for this callerReal managed records
Run controlsNo run kill switch, break-glass or spend capExisting admission, queueing, cancellation and reported-usage path
Pending continuationApp-owned saved operationFramework-dependent; initial AI SDK runner has no native approval/resume

v0.6.0 runner identity fixes: TypeScript status checks now include the assignment tenant, and both helpers encode custom run IDs as one URL component. Unicode/legacy header-unsafe identities use new base64url headers and require a plane-first upgrade. New run IDs reject controls and outer whitespace. Named LangGraph tenants must use HTTP proxy checkpoints; direct Postgres now rejects every non-default tenant before factory/state access because legacy history has no ownership attestation. Default cron threads need proxy mode too. Review the native boundary and explicit history resolution before continuing. Managed Python SDK profiles and AI SDK opaque history continue using the exact scoped HTTP checkpoint boundary.

App-owned tool governance

A normal AI SDK tool.execute or a Microsoft local function can ask Runkite once before execution. Use a server-side key with the explicit governance:decide permission; read/write and agent-run permissions do not imply it. The key selects the tenant. Policy identities and the target arguments must come from trusted server code.

  1. Submit agent, connector, tool and exact arguments to /governance/decide.
  2. Execute only after allow. An allow is permission, not evidence that the tool executed.
  3. For pending, persist the action ID and original operation in the app, then return promptly.
  4. On a later authenticated request, poll GET /governance/actions/{action_id} and execute the saved operation only after approved.
  5. Reject fresh replacement arguments and use an application transaction, downstream idempotency key or outbox to prevent duplicate effects.

run_id on this door is a stable application correlation value, not a managed Runkite run or an execution-idempotency guarantee. Polling does not consume approval. Rejected or consumed actions must not execute. Embedded pending rows expire after 24 hours on SQL; expired rows cannot be approved. Admin approval updates the pending row and does not execute or resume your app.

The v0.6.0 argument parser preserves the submitted JSON type. This door still accepts any JSON argument value, but a string containing JSON remains a string rather than being parsed again. Submit an object when your policy predicates inspect its fields; ambiguous duplicate keys or invalid Unicode receive HTTP 400.

v0.6.0 approval upgrade: pending or approved actions created before the v2 argument binding now poll as rejected with approval_binding_legacy, and Admin refuses to approve them. Do not execute the saved operation from that result. Resubmit for a new decision and fresh approval when required. There is no migration or automatic replay; see approval upgrades.

The repository's TypeScript createGovernedExecute decides once and never polls or retries. It supports ordinary single-result JSON tools inside generateText and streamText; async-iterable tool outputs are outside that helper. The optional Python Microsoft GovernanceFunctionMiddleware uses the same door for local function tools, tested with agent-framework-core==1.23.0. It is not a Microsoft managed runner and creates no Admin run.

Managed LangGraph and LangGraph.js

The default Python and TypeScript runkite-runner commands execute LangGraph and LangGraph.js in separate workers. Install with pip install runkite-runner or npm install -g runkite-runner, then load a graph from your runner config. These profiles create managed Threads/Runs and support their documented native interrupt/resume and checkpoint paths. Start with the first-agent walkthrough, agent registration and runner commands and capability matrix.

Named tenants and default cron:<name> threads must use HTTP proxy checkpoints. Direct Postgres checkpoints are limited to guarded default-tenant IDs; switching modes does not import old native history. The four older CrewAI, LlamaIndex, AutoGen and plain LangChain adapters remain checkout-only integrations.

Managed Vercel AI SDK runs

The new TypeScript backend executes public AI SDK ToolLoopAgent code inside the runner. Your app creates a Runkite run and consumes its stream instead of calling the model loop in its HTTP handler. Runkite owns operational dispatch and records; the SDK still owns the model loop. No upstream fork, second scheduler, policy engine or SDK runtime inside the Go binary is needed.

{
  "runner_kind": "typescript-ai-sdk",
  "graphs": { "managed_ai_sdk": "./agent.ts:createAgent" }
}

Each export is a per-run factory returning AiSdkAgentDefinition settings. The runner constructs the native SDK agent using those settings. This supported factory shape lets it supply trusted run context and check allowed_tools before local execution. An arbitrary opaque agent object is not automatically fully governable.

# From a v0.5.8+ checkout or installed runkite-runner; no provider key for this example
cd typescript/runkite-runner
npm ci
npm run build
cd ../../examples/managed_ai_sdk
npm ci
cd ../..

# Local development plane, separate terminal
runkite dev --config examples/managed_ai_sdk/langgraph.json

# Matching runner
node typescript/runkite-runner/dist/cli.js --framework ai-sdk \
  --config examples/managed_ai_sdk/langgraph.json \
  --grpc-address localhost:50051 --http-address http://localhost:2026

ai@7.0.155 is the tested optional peer. The updated runner package exposes runkite-runner/ai-sdk. The example keeps the existing langgraph.json filename and graph mapping; the protocol does not require the agent to use LangGraph. For production, use the normal auth, runner-token, TLS and deployment profile.

Keep the AI SDK chat UI

AI SDK useChat reads its own UI message protocol. The example's app-side bridge converts the runner's custom:ai_sdk events through the SDK's public UI APIs and waits for durable Runkite completion before UI finish. Your existing app authenticates the user, checks chat ownership, maps chat IDs to server-owned threads, and keeps the Runkite key on the server. Use managed-run read/write permissions for that route; a governance-only key cannot create, read and cancel managed runs.

Only the new user text enters the runner. Browser history is presentation state and cannot replace its stored native model/tool history. A different attempt after rendering begins causes a delivery error rather than mixing two assistant replies. Automatic reconnect, regeneration and browser tool approvals are not part of this initial bridge.

v0.6.0 checkout bridge update: the app can explicitly detach delivery, reattach its owned run through an authenticated GET, and request run cancellation through a separate app POST. Create still cancels on disconnect by default; detach requires the app's persisted run ID. Reattach uses complete retained replay from the same attempt without dispatching the model or tools again. Persist the first assistant ID with onMessageStart before display and pass it back as expectedMessageId, so a replacement attempt cannot silently become a second assistant after reconnect. Missing history fails explicitly. This is manual reattachment, not an automatic retry loop; see the example's reconnect and Stop contract.

Durability and limits

make test-managed-ai-sdk exercises native SDK calls, the UI consumer and a real Go plane. Set RUNKITE_TEST_POSTGRES_DSN and RUNKITE_TEST_REDIS_URL together to select its Postgres + Redis profile, including crash-after-commit receipt replay without duplicate tool work or usage. This suite uses one plane process; it is not a multi-replica HA soak.

Source and runnable example: examples/managed_ai_sdk. Existing CrewAI, LlamaIndex, AutoGen and plain LangChain adapters remain checkout integrations, not published adapter packages. See the framework matrix and limitations before claiming feature parity.

Managed Python SDK profiles (v0.6.1)

Microsoft factories return a public agent_framework.Agent for python-agent-framework. OpenAI factories return a public agents.Agent for python-openai-agents. Both run the native loop in a Python worker and create ordinary Runkite Threads/Runs. The plane owns dispatch and durable records through existing protocols; it does not embed an SDK runtime or use a hosted agent-session service.

Install the published v0.6.1 profiles with pip install 'runkite-runner[agent-framework]' or pip install 'runkite-runner[openai-agents]' in a clean environment. Source installs from ./python remain available for contributors. Run runkite-runner-agent-framework or runkite-runner-openai-agents with the matching config. The SDKs are pinned to agent-framework-core==1.23.0 and openai-agents==0.24.0. Repository PYTHONPATH is not needed after installation. The ordinary Python command and stock image retain their LangGraph defaults; the image does not install these extras.

Initial support is successful text turns and ordinary local tools. Conditional opaque state and receipts preserve native history and avoid repeated model/tool work after a confirmed commit. Interrupted and failed turns retain prior committed history. External effects before commit still require idempotency. Native approval/resume is unsupported, and local tools need the actual connector path to receive connector grants and HITL. The OpenAI profile also rejects native handoffs, hosted/MCP tools and structured final outputs. Its native SDK trace exporter is disabled; Runkite OTLP run tracing remains available.

The managed Python profiles enforce dispatched allowed_tools before local execution: omitted is unrestricted, [] denies all, and a list permits those names. Microsoft uses native function middleware and rejects a configured restriction before model execution if a custom client lacks that invocation boundary. This cooperative check is not a sandbox or a replacement for connector policy.

Microsoft Agent Framework

Select python-agent-framework in the plane config and run runkite-runner-agent-framework. A per-run factory returns agent_framework.Agent; the adapter preserves successful native AgentSession history. Workflows, .NET, non-text input and native approval/resume remain outside this profile. Follow the managed Microsoft example and installed-runner tests.

OpenAI Agents SDK

Select python-openai-agents and run runkite-runner-openai-agents. A per-run factory returns agents.Agent; the adapter streams text and persists native successful-turn history. Native approval/resume, handoffs, hosted/MCP tools and structured final output are unsupported. Follow the managed OpenAI Agents example and installed-runner tests.

Use the shared UI bridge

The application retains its UI authentication and presentation history. The v0.6.1 shared application bridge can translate these Python profiles' ordinary Agent Protocol text for the same AI SDK UI transport. Choose the profile on the server and use the Next/Nuxt route recipes. It validates the current turn and durable framework/generation before finishing; Pydantic final JSON remains a separate result part. Python profiles do not add native tool UI, reasoning display or approval resume. Attach expects a bridge-created single-user string turn with full retained replay and a persisted assistant identity. The tests use offline native models with a real plane on SQLite/in-process and Postgres/Redis, not an external model provider or a multi-replica HA soak.

Managed Pydantic AI (v0.6.1)

Native pydantic_ai.Agent factories run as python-pydantic-ai through the existing generic worker. Text can stream, while typed final results are validated by the SDK and stored as JSON in output.result. Only completed execution commits success; partial JSON is not a durable result.

Install with pip install 'runkite-runner[pydantic-ai]' and run runkite-runner-pydantic-ai. Published PyPI v0.6.1 includes this adapter. The optional extra pins pydantic-ai-slim==2.63.0; install your chosen provider separately. Source installs from ./python[pydantic-ai] remain available. The stock image does not install this SDK, and the default CLI remains LangGraph.

Native conversations retain metadata and successful history through opaque CAS state. Per-run usage excludes earlier conversation turns; a committed receipt replays without repeating the factory, model or tools. Local tool allowlisting is separate from synthetic output-schema calls. Connector policy requires the existing connector path. Native deferred approvals, output functions, multimodal input and additional workflow engines are outside this profile.

The app keeps UI authentication and presentation history. Use the ordinary Agent Protocol result stream, then read the durable result. See the offline example and adapter contract and tests.

Managed Google ADK (v0.6.1)

A fresh ordinary LlmAgent runs as python-google-adk through the Python worker. The public ADK runner keeps the model loop; Runkite owns Threads/Runs, dispatch, cancel, received usage and durable records. No hosted Agent Engine or additional session database is required.

Install with pip install 'runkite-runner[google-adk]', then run runkite-runner-google-adk with the same config loaded in the plane. Published PyPI v0.6.1 includes this adapter; the optional extra pins google-adk==2.13.0. Source installs from ./python[google-adk] remain available. The default CLI and stock image keep their LangGraph defaults, and the image does not install this SDK.

Send exactly one new user text message per run. Native events, tool results and session-local state persist through opaque CAS writes and successful receipts. Partial text is reconciled with the final aggregate, and a final response marker alone does not prove success. Reclaim after commit replays without another model/tool cycle. The app owns UI authentication and presentation history and consumes ordinary Agent Protocol events.

Shared app:/user: state is rejected rather than silently made thread-local. Temporary state lasts for the invocation. Workflows, delegation, native confirmation/resume, long-running tools, memory/artifacts, structured output and live audio are outside the first slice. Local tools need the existing connector path for connector grants, secret injection and HITL. Native confirmation blocks the local body, although its model proposal can already have consumed tokens.

See the offline example and adapter contract and tests for session scope, token accounting, telemetry privacy and installed-package checks.