SharedOS API / @aicoo/sharedos-runtime
@aicoo/sharedos-runtime
A fixed permission envelope with standard and replaceable one-turn agent runtimes.
npm install @aicoo/sharedos-runtime@next
SharedOS is runtime-agnostic, not runtime-less. The package exports two layers:
SharedOSExecutorvalidates and admits a turn, exposes only authorized tools, rechecks every exact call, applies cancellation, and records runtime provenance. Runtime plugins cannot replace this layer.RuntimePluginowns the agent loop inside that envelope.StandardRuntimeis the included reference implementation overAgentTurnDriver.
Standard runtime
import { SharedOSExecutor, StandardRuntime } from "@aicoo/sharedos-runtime";
const runtime = new StandardRuntime(agentDriver);
const turns = new SharedOSExecutor(kernel, runtime, {
defaultMaxSteps: 16,
defaultMaxToolCalls: 16,
defaultTimeoutMs: 120_000,
});
const result = await turns.execute(executionRequest);
The original API remains available as a compatibility shorthand, retained
pending a deprecation decision (docs/open-items.md):
import { TurnExecutor } from "@aicoo/sharedos-runtime";
const turns = new TurnExecutor(kernel, agentDriver);
Escalation
A turn may end by asking a human to decide (ADR 0011, ADR 0017). The ask is a
catalogued tool, sharedos.escalate, so that it is chosen rather than inferred
from prose, and so that it is permission-filtered like every other tool:
import { createEscalationTool } from "@aicoo/sharedos-runtime";
kernel.registerTool(createEscalationTool());
An agent sees it only when its context enables the sharedos tool namespace
and it holds a grant over resource sharedos / ["escalation"], action
request — exported as ESCALATION_TOOL_NAMESPACE, ESCALATION_RESOURCE_PATH,
and ESCALATION_ACTION. A host that issues no such grant has agents that cannot
escalate, which is the intended arrangement.
The tool is never executed. A driver whose turn's catalogue offers it
recognises the name with escalationRequest(tool, arguments) and returns
{ type: "escalate", reason } instead of a tool call; StandardRuntime settles
the turn as escalated, the envelope records escalation.requested, and
nothing is granted while the ask is pending. Without the grant the name is
passed through and refused tool_unavailable, and SharedOSExecutor refuses an
escalate outcome from any plugin on such a turn — the catalogue gates the
name, not the driver's goodwill. The registered handler exists to put the tool in the catalogue and to
fail — escalation_not_terminated — if a driver forwards the call anyway. Over
MCP the bridge answers the ask itself and refuses later calls on that turn with
escalation_pending (ADR 0018).
Custom runtime
import type { RuntimePlugin } from "@aicoo/sharedos-runtime";
const codexRuntime: RuntimePlugin = {
manifest: {
id: "acme.codex",
version: "1.0.0",
protocolVersion: "1",
metadata: { harness: "codex", backend: "vercel-sandbox" },
},
async run(request, host, signal) {
// Translate the harness's native tool definitions to request.tools.
// Every implementation must route actual effects through this broker.
const result = await host.invokeTool({
id: crypto.randomUUID(),
tool: "files.search",
arguments: { path: ["Projects"], query: "status" },
traceId: request.context.traceId,
requestedAt: request.context.now,
});
signal.throwIfAborted();
return { type: "complete", output: { toolStatus: result.status } };
},
};
const turns = new SharedOSExecutor(kernel, codexRuntime);
Embedded hosts can observe events as they are emitted without giving the plugin an authoritative event channel:
await turns.execute(executionRequest, {
signal,
onEvent: (event) => streamController.enqueue(event),
});
The callback receives a frozen snapshot. Callback failure does not replace the turn's protocol outcome; cancel the supplied signal when the consumer closes.
A plugin receives a frozen RuntimeTurnRequest without grants, issuing
authority, or namespace-management state. Its RuntimeHost contains only:
- effective step, tool-call, and deadline limits;
invokeTool, which checks the visible catalog and then re-authorizes through the kernel;emit, which records plugin observations as wrappedruntime.eventevents.
The broker closes when run returns. A plugin cannot use a retained host handle
for later tool calls or emit authoritative turn.* and tool.* events.
Trusted selection
RuntimeRegistry is an instance-scoped registry for trusted boot
configuration:
const runtimes = new RuntimeRegistry([
new StandardRuntime(agentDriver),
codexRuntime,
]);
const runtime = runtimes.resolve(serverPolicy.runtimeId);
const turns = new SharedOSExecutor(kernel, runtime);
Do not resolve a runtime id directly from a message, model output, or unverified request metadata. In-process plugins have the ambient privileges of the host; isolate third-party runtimes behind a process, container, microVM, or remote adapter.
Product heartbeats, multi-turn retries, adaptive routing, benchmark scheduling, and network-level stopping remain host responsibilities.
SharedOS is currently an 0.x prerelease.
Classes
RuntimeNotFoundError
Defined in: packages/runtime/src/runtime-plugin.ts:158
Extends
Error
Constructors
Constructor
new RuntimeNotFoundError(
runtimeId):RuntimeNotFoundError
Defined in: packages/runtime/src/runtime-plugin.ts:159
Parameters
| Parameter | Type |
|---|---|
runtimeId | string |
Returns
Overrides
Error.constructor
Properties
| Property | Modifier | Type | Description | Inherited from | Defined in |
|---|---|---|---|---|---|
<a id="property-cause"></a> cause? | public | unknown | - | Error.cause | node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.error.d.ts:26 |
<a id="property-message"></a> message | public | string | - | Error.message | node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts:1077 |
<a id="property-name"></a> name | public | string | - | Error.name | node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts:1076 |
<a id="property-stack"></a> stack? | public | string | - | Error.stack | node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts:1078 |
<a id="property-stacktracelimit"></a> stackTraceLimit | static | number | The Error.stackTraceLimit property specifies the number of stack frames collected by a stack trace (whether generated by new Error().stack or Error.captureStackTrace(obj)). The default value is 10 but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. | Error.stackTraceLimit | node_modules/.pnpm/@types+node@22.20.1/node_modules/@types/node/globals.d.ts:68 |
Methods
captureStackTrace()
staticcaptureStackTrace(targetObject,constructorOpt?):void
Defined in: node_modules/.pnpm/@types+node@22.20.1/node_modules/@types/node/globals.d.ts:52
Creates a .stack property on targetObject, which when accessed returns
a string representing the location in the code at which
Error.captureStackTrace() was called.
const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack; // Similar to `new Error().stack`
The first line of the trace will be prefixed with
${myObject.name}: ${myObject.message}.
The optional constructorOpt argument accepts a function. If given, all frames
above constructorOpt, including constructorOpt, will be omitted from the
generated stack trace.
The constructorOpt argument is useful for hiding implementation
details of error generation from the user. For instance:
function a() {
b();
}
function b() {
c();
}
function c() {
// Create an error without stack trace to avoid calculating the stack trace twice.
const { stackTraceLimit } = Error;
Error.stackTraceLimit = 0;
const error = new Error();
Error.stackTraceLimit = stackTraceLimit;
// Capture the stack trace above function b
Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
throw error;
}
a();
Parameters
| Parameter | Type |
|---|---|
targetObject | object |
constructorOpt? | Function |
Returns
void
Inherited from
Error.captureStackTrace
prepareStackTrace()
staticprepareStackTrace(err,stackTraces):any
Defined in: node_modules/.pnpm/@types+node@22.20.1/node_modules/@types/node/globals.d.ts:56
Parameters
| Parameter | Type |
|---|---|
err | Error |
stackTraces | CallSite[] |
Returns
any
See
https://v8.dev/docs/stack-trace-api#customizing-stack-traces
Inherited from
Error.prepareStackTrace
RuntimeRegistry
Defined in: packages/runtime/src/runtime-plugin.ts:169
An instance-scoped registry populated by trusted host configuration. Runtime selection is intentionally absent from model-visible execution requests.
Constructors
Constructor
new RuntimeRegistry(
runtimes?):RuntimeRegistry
Defined in: packages/runtime/src/runtime-plugin.ts:172
Parameters
| Parameter | Type | Default value |
|---|---|---|
runtimes | readonly RuntimePlugin[] | [] |
Returns
Methods
has()
has(
runtimeId):boolean
Defined in: packages/runtime/src/runtime-plugin.ts:199
Parameters
| Parameter | Type |
|---|---|
runtimeId | string |
Returns
boolean
list()
list(): readonly
object[]
Defined in: packages/runtime/src/runtime-plugin.ts:211
Returns
readonly object[]
register()
register(
runtime):void
Defined in: packages/runtime/src/runtime-plugin.ts:178
Parameters
| Parameter | Type |
|---|---|
runtime | RuntimePlugin |
Returns
void
resolve()
resolve(
runtimeId):RuntimePlugin
Defined in: packages/runtime/src/runtime-plugin.ts:203
Parameters
| Parameter | Type |
|---|---|
runtimeId | string |
Returns
SharedOSExecutor
Defined in: packages/runtime/src/executor.ts:119
The non-replaceable security envelope around one replaceable RuntimePlugin. Scheduling, retries, and network-level stopping remain host responsibilities.
Implements
Constructors
Constructor
new SharedOSExecutor(
kernel,runtime,options?):SharedOSExecutor
Defined in: packages/runtime/src/executor.ts:131
Parameters
| Parameter | Type |
|---|---|
kernel | TurnKernel |
runtime | RuntimePlugin |
options | SharedOSExecutorOptions |
Returns
Accessors
runtimeManifest
Get Signature
get runtimeManifest():
object
Defined in: packages/runtime/src/executor.ts:174
Returns
object
id
id:
string
metadata?
optionalmetadata?:JsonObject
protocolVersion
protocolVersion:
"1"
version
version:
string
Methods
execute()
execute(
input,options?):Promise<{completedAt:string;events:object[];executionId:string;metadata?:JsonObject;output:JsonValue;startedAt:string;status:"succeeded";traceId:string;version:"1"; } | {completedAt:string;error: {code:string;details?:JsonObject;message:string;retryable?:boolean; };events:object[];executionId:string;metadata?:JsonObject;startedAt:string;status:"denied";traceId:string;version:"1"; } | {completedAt:string;error: {code:string;details?:JsonObject;message:string;retryable?:boolean; };events:object[];executionId:string;metadata?:JsonObject;startedAt:string;status:"failed";traceId:string;version:"1"; } | {completedAt:string;error?: {code:string;details?:JsonObject;message:string;retryable?:boolean; };events:object[];executionId:string;metadata?:JsonObject;startedAt:string;status:"cancelled";traceId:string;version:"1"; } | {completedAt:string;escalation: {reason:string;requestedAt:string;requestedAuthority?: {capabilities:object[];constraints?: {delegationDepth?:number;expiresAt?:string;maxUses?:number;notBefore?:string;purposes?:string[]; };id:string;metadata?:JsonObject;namespaceId:string;owner: {kind:"human";userId:string; } | {agentId:string;kind:"agent"; } | {conversationId:string;kind:"group"; } | {kind:"service";serviceId:string; };purpose:string;requestedAt:string;requester: {kind:"human";userId:string; } | {agentId:string;kind:"agent"; } | {conversationId:string;kind:"group"; } | {kind:"service";serviceId:string; }; };reviewer: {kind:"human";userId:string; } | {agentId:string;kind:"agent"; } | {conversationId:string;kind:"group"; } | {kind:"service";serviceId:string; };status:"pending"; };events:object[];executionId:string;metadata?:JsonObject;startedAt:string;status:"escalated";traceId:string;version:"1"; }>
Defined in: packages/runtime/src/executor.ts:178
Parameters
| Parameter | Type |
|---|---|
input | { agent: { agentId: string; kind: "agent"; }; context: { actor: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; authority: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; enabledToolNamespaces: string[]; namespaceId: string; now: string; owner: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; purpose: string; traceId: string; }; executionId: string; message: { createdAt: string; id: string; payload: JsonValue; provenance?: { metadata?: JsonObject; parentIds: string[]; source: string; }; purpose: string; receiver: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; replyTo?: string; sender: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; traceId: string; version: "1"; }; metadata?: JsonObject; options?: { maxSteps?: number; maxToolCalls?: number; timeoutMs?: number; }; state?: JsonObject; tools: object[]; version: "1"; } |
input.agent | { agentId: string; kind: "agent"; } |
input.agent.agentId | string |
input.agent.kind | "agent" |
input.context | { actor: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; authority: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; enabledToolNamespaces: string[]; namespaceId: string; now: string; owner: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; purpose: string; traceId: string; } |
input.context.actor | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } |
input.context.authority | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } |
input.context.enabledToolNamespaces | string[] |
input.context.namespaceId | string |
input.context.now | string |
input.context.owner | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } |
input.context.purpose | string |
input.context.traceId | string |
input.executionId | string |
input.message | { createdAt: string; id: string; payload: JsonValue; provenance?: { metadata?: JsonObject; parentIds: string[]; source: string; }; purpose: string; receiver: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; replyTo?: string; sender: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; traceId: string; version: "1"; } |
input.message.createdAt | string |
input.message.id | string |
input.message.payload | JsonValue |
input.message.provenance? | { metadata?: JsonObject; parentIds: string[]; source: string; } |
input.message.provenance.metadata? | JsonObject |
input.message.provenance.parentIds | string[] |
input.message.provenance.source | string |
input.message.purpose | string |
input.message.receiver | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } |
input.message.replyTo? | string |
input.message.sender | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } |
input.message.traceId | string |
input.message.version | "1" |
input.metadata? | JsonObject |
input.options? | { maxSteps?: number; maxToolCalls?: number; timeoutMs?: number; } |
input.options.maxSteps? | number |
input.options.maxToolCalls? | number |
input.options.timeoutMs? | number |
input.state? | JsonObject |
input.tools | object[] |
input.version | "1" |
options | ExecuteTurnOptions |
Returns
Promise<{ completedAt: string; events: object[]; executionId: string; metadata?: JsonObject; output: JsonValue; startedAt: string; status: "succeeded"; traceId: string; version: "1"; } | { completedAt: string; error: { code: string; details?: JsonObject; message: string; retryable?: boolean; }; events: object[]; executionId: string; metadata?: JsonObject; startedAt: string; status: "denied"; traceId: string; version: "1"; } | { completedAt: string; error: { code: string; details?: JsonObject; message: string; retryable?: boolean; }; events: object[]; executionId: string; metadata?: JsonObject; startedAt: string; status: "failed"; traceId: string; version: "1"; } | { completedAt: string; error?: { code: string; details?: JsonObject; message: string; retryable?: boolean; }; events: object[]; executionId: string; metadata?: JsonObject; startedAt: string; status: "cancelled"; traceId: string; version: "1"; } | { completedAt: string; escalation: { reason: string; requestedAt: string; requestedAuthority?: { capabilities: object[]; constraints?: { delegationDepth?: number; expiresAt?: string; maxUses?: number; notBefore?: string; purposes?: string[]; }; id: string; metadata?: JsonObject; namespaceId: string; owner: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; purpose: string; requestedAt: string; requester: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; }; reviewer: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; status: "pending"; }; events: object[]; executionId: string; metadata?: JsonObject; startedAt: string; status: "escalated"; traceId: string; version: "1"; }>
Implementation of
StandardRuntime
Defined in: packages/runtime/src/standard-runtime.ts:127
The reference SharedOS loop. Hosts may replace it with another RuntimePlugin.
Implements
Constructors
Constructor
new StandardRuntime(
driver,options?):StandardRuntime
Defined in: packages/runtime/src/standard-runtime.ts:133
Parameters
| Parameter | Type |
|---|---|
driver | AgentTurnDriver |
options | StandardRuntimeOptions |
Returns
Properties
| Property | Modifier | Type | Default value | Defined in |
|---|---|---|---|---|
<a id="property-manifest"></a> manifest | readonly | object | STANDARD_RUNTIME_MANIFEST | packages/runtime/src/standard-runtime.ts:128 |
manifest.id | public | string | undefined | packages/contracts/dist/runtime.d.ts:9 |
manifest.metadata? | public | JsonObject | undefined | packages/contracts/dist/runtime.d.ts:12 |
manifest.protocolVersion | public | "1" | undefined | packages/contracts/dist/runtime.d.ts:11 |
manifest.version | public | string | undefined | packages/contracts/dist/runtime.d.ts:10 |
Methods
run()
run(
request,host,signal):Promise<{metadata?:JsonObject;output:JsonValue;type:"complete"; } | {error: {code:string;details?:JsonObject;message:string;retryable?:boolean; };metadata?:JsonObject;type:"fail"; } | {metadata?:JsonObject;reason:string;type:"escalate"; }>
Defined in: packages/runtime/src/standard-runtime.ts:142
Parameters
| Parameter | Type |
|---|---|
request | RuntimeTurnRequest |
host | RuntimeHost |
signal | AbortSignal |
Returns
Promise<{ metadata?: JsonObject; output: JsonValue; type: "complete"; } | { error: { code: string; details?: JsonObject; message: string; retryable?: boolean; }; metadata?: JsonObject; type: "fail"; } | { metadata?: JsonObject; reason: string; type: "escalate"; }>
Implementation of
TurnExecutor
Defined in: packages/runtime/src/executor.ts:625
Compatibility facade for the original driver-based API. New harnesses should implement RuntimePlugin and use SharedOSExecutor directly.
Retained pending a deprecation decision; see docs/open-items.md.
Implements
Constructors
Constructor
new TurnExecutor(
kernel,driver,options?):TurnExecutor
Defined in: packages/runtime/src/executor.ts:628
Parameters
| Parameter | Type |
|---|---|
kernel | TurnKernel |
driver | AgentTurnDriver |
options | TurnExecutorOptions |
Returns
Accessors
runtimeManifest
Get Signature
get runtimeManifest():
object
Defined in: packages/runtime/src/executor.ts:658
Returns
object
id
id:
string
metadata?
optionalmetadata?:JsonObject
protocolVersion
protocolVersion:
"1"
version
version:
string
Methods
execute()
execute(
input,options?):Promise<{completedAt:string;events:object[];executionId:string;metadata?:JsonObject;output:JsonValue;startedAt:string;status:"succeeded";traceId:string;version:"1"; } | {completedAt:string;error: {code:string;details?:JsonObject;message:string;retryable?:boolean; };events:object[];executionId:string;metadata?:JsonObject;startedAt:string;status:"denied";traceId:string;version:"1"; } | {completedAt:string;error: {code:string;details?:JsonObject;message:string;retryable?:boolean; };events:object[];executionId:string;metadata?:JsonObject;startedAt:string;status:"failed";traceId:string;version:"1"; } | {completedAt:string;error?: {code:string;details?:JsonObject;message:string;retryable?:boolean; };events:object[];executionId:string;metadata?:JsonObject;startedAt:string;status:"cancelled";traceId:string;version:"1"; } | {completedAt:string;escalation: {reason:string;requestedAt:string;requestedAuthority?: {capabilities:object[];constraints?: {delegationDepth?:number;expiresAt?:string;maxUses?:number;notBefore?:string;purposes?:string[]; };id:string;metadata?:JsonObject;namespaceId:string;owner: {kind:"human";userId:string; } | {agentId:string;kind:"agent"; } | {conversationId:string;kind:"group"; } | {kind:"service";serviceId:string; };purpose:string;requestedAt:string;requester: {kind:"human";userId:string; } | {agentId:string;kind:"agent"; } | {conversationId:string;kind:"group"; } | {kind:"service";serviceId:string; }; };reviewer: {kind:"human";userId:string; } | {agentId:string;kind:"agent"; } | {conversationId:string;kind:"group"; } | {kind:"service";serviceId:string; };status:"pending"; };events:object[];executionId:string;metadata?:JsonObject;startedAt:string;status:"escalated";traceId:string;version:"1"; }>
Defined in: packages/runtime/src/executor.ts:662
Parameters
| Parameter | Type |
|---|---|
input | { agent: { agentId: string; kind: "agent"; }; context: { actor: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; authority: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; enabledToolNamespaces: string[]; namespaceId: string; now: string; owner: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; purpose: string; traceId: string; }; executionId: string; message: { createdAt: string; id: string; payload: JsonValue; provenance?: { metadata?: JsonObject; parentIds: string[]; source: string; }; purpose: string; receiver: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; replyTo?: string; sender: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; traceId: string; version: "1"; }; metadata?: JsonObject; options?: { maxSteps?: number; maxToolCalls?: number; timeoutMs?: number; }; state?: JsonObject; tools: object[]; version: "1"; } |
input.agent | { agentId: string; kind: "agent"; } |
input.agent.agentId | string |
input.agent.kind | "agent" |
input.context | { actor: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; authority: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; enabledToolNamespaces: string[]; namespaceId: string; now: string; owner: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; purpose: string; traceId: string; } |
input.context.actor | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } |
input.context.authority | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } |
input.context.enabledToolNamespaces | string[] |
input.context.namespaceId | string |
input.context.now | string |
input.context.owner | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } |
input.context.purpose | string |
input.context.traceId | string |
input.executionId | string |
input.message | { createdAt: string; id: string; payload: JsonValue; provenance?: { metadata?: JsonObject; parentIds: string[]; source: string; }; purpose: string; receiver: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; replyTo?: string; sender: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; traceId: string; version: "1"; } |
input.message.createdAt | string |
input.message.id | string |
input.message.payload | JsonValue |
input.message.provenance? | { metadata?: JsonObject; parentIds: string[]; source: string; } |
input.message.provenance.metadata? | JsonObject |
input.message.provenance.parentIds | string[] |
input.message.provenance.source | string |
input.message.purpose | string |
input.message.receiver | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } |
input.message.replyTo? | string |
input.message.sender | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } |
input.message.traceId | string |
input.message.version | "1" |
input.metadata? | JsonObject |
input.options? | { maxSteps?: number; maxToolCalls?: number; timeoutMs?: number; } |
input.options.maxSteps? | number |
input.options.maxToolCalls? | number |
input.options.timeoutMs? | number |
input.state? | JsonObject |
input.tools | object[] |
input.version | "1" |
options | ExecuteTurnOptions |
Returns
Promise<{ completedAt: string; events: object[]; executionId: string; metadata?: JsonObject; output: JsonValue; startedAt: string; status: "succeeded"; traceId: string; version: "1"; } | { completedAt: string; error: { code: string; details?: JsonObject; message: string; retryable?: boolean; }; events: object[]; executionId: string; metadata?: JsonObject; startedAt: string; status: "denied"; traceId: string; version: "1"; } | { completedAt: string; error: { code: string; details?: JsonObject; message: string; retryable?: boolean; }; events: object[]; executionId: string; metadata?: JsonObject; startedAt: string; status: "failed"; traceId: string; version: "1"; } | { completedAt: string; error?: { code: string; details?: JsonObject; message: string; retryable?: boolean; }; events: object[]; executionId: string; metadata?: JsonObject; startedAt: string; status: "cancelled"; traceId: string; version: "1"; } | { completedAt: string; escalation: { reason: string; requestedAt: string; requestedAuthority?: { capabilities: object[]; constraints?: { delegationDepth?: number; expiresAt?: string; maxUses?: number; notBefore?: string; purposes?: string[]; }; id: string; metadata?: JsonObject; namespaceId: string; owner: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; purpose: string; requestedAt: string; requester: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; }; reviewer: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; status: "pending"; }; events: object[]; executionId: string; metadata?: JsonObject; startedAt: string; status: "escalated"; traceId: string; version: "1"; }>
Implementation of
Interfaces
AgentTurnDriver
Defined in: packages/runtime/src/standard-runtime.ts:96
Model/provider-specific code implements this port inside the standard runtime.
Methods
open()
open(
request,signal):Promise<AgentTurnSession>>
Defined in: packages/runtime/src/standard-runtime.ts:97
Parameters
| Parameter | Type |
|---|---|
request | RuntimeTurnRequest |
signal | AbortSignal |
Returns
Promise<AgentTurnSession>
AgentTurnSession
Defined in: packages/runtime/src/standard-runtime.ts:90
Methods
close()?
optionalclose(outcome,signal):void|Promise<void>>
Defined in: packages/runtime/src/standard-runtime.ts:92
Parameters
| Parameter | Type |
|---|---|
outcome | "succeeded" | "denied" | "failed" | "cancelled" | "escalated" |
signal | AbortSignal |
Returns
void | Promise<void>
next()
next(
input,signal):Promise<AgentTurnDecision>>
Defined in: packages/runtime/src/standard-runtime.ts:91
Parameters
| Parameter | Type |
|---|---|
input | AgentTurnInput |
signal | AbortSignal |
Returns
Promise<AgentTurnDecision>
DescribeReachOptions
Defined in: packages/runtime/src/reach.ts:3
Properties
| Property | Modifier | Type | Description | Defined in |
|---|---|---|---|---|
<a id="property-limit"></a> limit? | readonly | number | How many entries are written out before the rest are counted instead. A reach may carry thousands of entries, and a prompt that lists them all is a prompt the model reads instead of the task. Past the limit the text says how many were left out, so a truncated description never reads as a complete one. Defaults to DEFAULT_DESCRIBED_REACH_LIMIT. | packages/runtime/src/reach.ts:12 |
ExecuteTurnOptions
Defined in: packages/runtime/src/executor.ts:81
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
<a id="property-onevent"></a> onEvent? | (event) => void | Synchronous observation hook for streaming an immutable event snapshot. | packages/runtime/src/executor.ts:84 |
<a id="property-signal"></a> signal? | AbortSignal | - | packages/runtime/src/executor.ts:82 |
RuntimeHost
Defined in: packages/runtime/src/runtime-plugin.ts:138
The only effectful surface supplied to a runtime plugin. Every tool call is checked against the effective catalog and re-authorized by the kernel.
Properties
| Property | Modifier | Type | Defined in |
|---|---|---|---|
<a id="property-limits"></a> limits | readonly | RuntimeLimits | packages/runtime/src/runtime-plugin.ts:139 |
Methods
emit()
emit(
event):void
Defined in: packages/runtime/src/runtime-plugin.ts:141
Parameters
| Parameter | Type |
|---|---|
event | { data: JsonValue; type: string; } |
event.data | JsonValue |
event.type | string |
Returns
void
invokeTool()
invokeTool(
call,options?):Promise<{callId:string;completedAt:string;metadata?:JsonObject;output:JsonValue;status:"succeeded";tool:string; } | {callId:string;completedAt:string;error: {code:string;details?:JsonObject;message:string;retryable?:boolean; };metadata?:JsonObject;status:"denied";tool:string; } | {callId:string;completedAt:string;error: {code:string;details?:JsonObject;message:string;retryable?:boolean; };metadata?:JsonObject;status:"failed";tool:string; }>
Defined in: packages/runtime/src/runtime-plugin.ts:140
Parameters
| Parameter | Type |
|---|---|
call | { arguments: JsonObject; id: string; requestedAt: string; tool: string; traceId: string; } |
call.arguments | JsonObject |
call.id? | string |
call.requestedAt? | string |
call.tool? | string |
call.traceId? | string |
options? | RuntimeToolInvocationOptions |
Returns
Promise<{ callId: string; completedAt: string; metadata?: JsonObject; output: JsonValue; status: "succeeded"; tool: string; } | { callId: string; completedAt: string; error: { code: string; details?: JsonObject; message: string; retryable?: boolean; }; metadata?: JsonObject; status: "denied"; tool: string; } | { callId: string; completedAt: string; error: { code: string; details?: JsonObject; message: string; retryable?: boolean; }; metadata?: JsonObject; status: "failed"; tool: string; }>
RuntimeLimits
Defined in: packages/runtime/src/runtime-plugin.ts:116
Properties
| Property | Modifier | Type | Defined in |
|---|---|---|---|
<a id="property-maxsteps"></a> maxSteps | readonly | number | packages/runtime/src/runtime-plugin.ts:117 |
<a id="property-maxtoolcalls"></a> maxToolCalls | readonly | number | packages/runtime/src/runtime-plugin.ts:118 |
<a id="property-timeoutms"></a> timeoutMs | readonly | number | packages/runtime/src/runtime-plugin.ts:119 |
RuntimePlugin
Defined in: packages/runtime/src/runtime-plugin.ts:149
A replaceable one-turn harness running inside the SharedOS security envelope.
Implementations must keep per-turn state inside run and support concurrent
calls when one plugin instance is shared by a RuntimeRegistry.
Properties
| Property | Modifier | Type | Defined in |
|---|---|---|---|
<a id="property-manifest-1"></a> manifest | readonly | object | packages/runtime/src/runtime-plugin.ts:150 |
manifest.id | public | string | packages/contracts/dist/runtime.d.ts:9 |
manifest.metadata? | public | JsonObject | packages/contracts/dist/runtime.d.ts:12 |
manifest.protocolVersion | public | "1" | packages/contracts/dist/runtime.d.ts:11 |
manifest.version | public | string | packages/contracts/dist/runtime.d.ts:10 |
Methods
run()
run(
request,host,signal):Promise<{metadata?:JsonObject;output:JsonValue;type:"complete"; } | {error: {code:string;details?:JsonObject;message:string;retryable?:boolean; };metadata?:JsonObject;type:"fail"; } | {metadata?:JsonObject;reason:string;type:"escalate"; }>
Defined in: packages/runtime/src/runtime-plugin.ts:151
Parameters
| Parameter | Type |
|---|---|
request | RuntimeTurnRequest |
host | RuntimeHost |
signal | AbortSignal |
Returns
Promise<{ metadata?: JsonObject; output: JsonValue; type: "complete"; } | { error: { code: string; details?: JsonObject; message: string; retryable?: boolean; }; metadata?: JsonObject; type: "fail"; } | { metadata?: JsonObject; reason: string; type: "escalate"; }>
RuntimeToolInvocationOptions
Defined in: packages/runtime/src/runtime-plugin.ts:122
Properties
| Property | Modifier | Type | Description | Defined in |
|---|---|---|---|---|
<a id="property-step"></a> step? | readonly | number | Position within the runtime's own loop. Optional, and enforced when present: the execution envelope refuses a call declaring a step at or past RuntimeLimits.maxSteps, and refuses a new step once that many distinct ones have been seen. A plugin that omits it is bounded by maxToolCalls alone. | packages/runtime/src/runtime-plugin.ts:131 |
RuntimeVisibleContext
Defined in: packages/runtime/src/runtime-plugin.ts:74
Properties
| Property | Modifier | Type | Description | Defined in |
|---|---|---|---|---|
<a id="property-actor"></a> actor | readonly | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } | - | packages/runtime/src/runtime-plugin.ts:75 |
<a id="property-namespaceid"></a> namespaceId | readonly | string | - | packages/runtime/src/runtime-plugin.ts:77 |
<a id="property-now"></a> now | readonly | string | - | packages/runtime/src/runtime-plugin.ts:80 |
<a id="property-owner"></a> owner | readonly | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } | - | packages/runtime/src/runtime-plugin.ts:76 |
<a id="property-purpose"></a> purpose | readonly | string | - | packages/runtime/src/runtime-plugin.ts:78 |
<a id="property-reach"></a> reach | readonly | { reach: object[]; status: "computed"; } | { reasonCode: "authority_unavailable" | "usage_store_unavailable"; status: "unavailable"; } | Where this turn may operate, with the authority stripped out. The catalogue says which tools exist; this says which resources they are worth pointing at. Without it a runtime can only guess paths and collect denials, or the host reads raw grants to describe the boundary in a prompt -- at exactly the seam designed to keep grants away from the model. computed is derived by SharedOSKernel.reach from the grants the turn's decisions are made against, then narrowed to the namespaces this turn's catalogue operates on. It carries no grant id, issuer, expiry, or budget, and a bounded grant whose budget is spent does not appear. unavailable means the reach could not be established, and reasonCode says why: usage_store_unavailable when a bounded budget could not be read, or authority_unavailable when the authority could not be loaded again after admission. Either is handed over as such rather than as an empty list that would read as "nothing", which is a true answer for some turns and not for this one. The turn still runs: every call is decided on its own, and a call that depends on what could not be read fails closed under the same code. Descriptive, never permissive: every call is authorized independently, so an entry here is not a permission and a stale one cannot open anything. | packages/runtime/src/runtime-plugin.ts:105 |
<a id="property-traceid"></a> traceId | readonly | string | - | packages/runtime/src/runtime-plugin.ts:79 |
SharedOSExecutorOptions
Defined in: packages/runtime/src/executor.ts:51
Extended by
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
<a id="property-clock"></a> clock? | () => string | - | packages/runtime/src/executor.ts:52 |
<a id="property-createid"></a> createId? | () => string | - | packages/runtime/src/executor.ts:53 |
<a id="property-defaultmaxsteps"></a> defaultMaxSteps? | number | - | packages/runtime/src/executor.ts:54 |
<a id="property-defaultmaxtoolcalls"></a> defaultMaxToolCalls? | number | - | packages/runtime/src/executor.ts:55 |
<a id="property-defaulttimeoutms"></a> defaultTimeoutMs? | number | - | packages/runtime/src/executor.ts:56 |
<a id="property-onturnerror"></a> onTurnError? | TurnErrorReporter | Notification for a throw the turn body did not convert into an outcome. The envelope contains such a throw and ends the turn failed with runtime_failed; the error itself comes here rather than being discarded. See TurnErrorReporter for what it may and may not be used for. Not only the plugin's. The turn body also calls openTurnAuthority, admitTurn, reach, and listTools, and a host port that throws arrives here too under the same terminal code. That conflation is in the wire vocabulary and is not fixed by this hook; the error's own stack is what separates them, which is the reason for handing it over rather than classifying it here. | packages/runtime/src/executor.ts:78 |
<a id="property-spans"></a> spans? | SpanSink | Where the envelope reports what it cost, when a host is measuring. A second clock, and deliberately not the one clock supplies: that one names instants for a record and a conformance run freezes it. See SpanSink. | packages/runtime/src/executor.ts:64 |
StandardRuntimeOptions
Defined in: packages/runtime/src/standard-runtime.ts:100
Extended by
Properties
| Property | Type | Description | Defined in |
|---|---|---|---|
<a id="property-closetimeoutms"></a> closeTimeoutMs? | number | - | packages/runtime/src/standard-runtime.ts:101 |
<a id="property-onturnerror-1"></a> onTurnError? | TurnErrorReporter | Notification for a throw the loop contained rather than propagated. A driver that throws ends the turn driver_failed, which is a cooperative outcome the envelope never sees as an exception -- so the executor's own hook cannot report it and this one exists. Same contract either way; see TurnErrorReporter. | packages/runtime/src/standard-runtime.ts:110 |
TurnErrorContext
Defined in: packages/runtime/src/runtime-plugin.ts:18
Which turn a TurnErrorReporter notification is about.
Properties
| Property | Modifier | Type | Defined in |
|---|---|---|---|
<a id="property-executionid"></a> executionId | readonly | string | packages/runtime/src/runtime-plugin.ts:19 |
<a id="property-traceid-1"></a> traceId | readonly | string | packages/runtime/src/runtime-plugin.ts:20 |
TurnExecutionPort
Defined in: packages/runtime/src/executor.ts:87
Methods
execute()
execute(
input,options?):Promise<{completedAt:string;events:object[];executionId:string;metadata?:JsonObject;output:JsonValue;startedAt:string;status:"succeeded";traceId:string;version:"1"; } | {completedAt:string;error: {code:string;details?:JsonObject;message:string;retryable?:boolean; };events:object[];executionId:string;metadata?:JsonObject;startedAt:string;status:"denied";traceId:string;version:"1"; } | {completedAt:string;error: {code:string;details?:JsonObject;message:string;retryable?:boolean; };events:object[];executionId:string;metadata?:JsonObject;startedAt:string;status:"failed";traceId:string;version:"1"; } | {completedAt:string;error?: {code:string;details?:JsonObject;message:string;retryable?:boolean; };events:object[];executionId:string;metadata?:JsonObject;startedAt:string;status:"cancelled";traceId:string;version:"1"; } | {completedAt:string;escalation: {reason:string;requestedAt:string;requestedAuthority?: {capabilities:object[];constraints?: {delegationDepth?:number;expiresAt?:string;maxUses?:number;notBefore?:string;purposes?:string[]; };id:string;metadata?:JsonObject;namespaceId:string;owner: {kind:"human";userId:string; } | {agentId:string;kind:"agent"; } | {conversationId:string;kind:"group"; } | {kind:"service";serviceId:string; };purpose:string;requestedAt:string;requester: {kind:"human";userId:string; } | {agentId:string;kind:"agent"; } | {conversationId:string;kind:"group"; } | {kind:"service";serviceId:string; }; };reviewer: {kind:"human";userId:string; } | {agentId:string;kind:"agent"; } | {conversationId:string;kind:"group"; } | {kind:"service";serviceId:string; };status:"pending"; };events:object[];executionId:string;metadata?:JsonObject;startedAt:string;status:"escalated";traceId:string;version:"1"; }>
Defined in: packages/runtime/src/executor.ts:88
Parameters
| Parameter | Type |
|---|---|
input | { agent: { agentId: string; kind: "agent"; }; context: { actor: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; authority: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; enabledToolNamespaces: string[]; namespaceId: string; now: string; owner: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; purpose: string; traceId: string; }; executionId: string; message: { createdAt: string; id: string; payload: JsonValue; provenance?: { metadata?: JsonObject; parentIds: string[]; source: string; }; purpose: string; receiver: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; replyTo?: string; sender: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; traceId: string; version: "1"; }; metadata?: JsonObject; options?: { maxSteps?: number; maxToolCalls?: number; timeoutMs?: number; }; state?: JsonObject; tools: object[]; version: "1"; } |
input.agent | { agentId: string; kind: "agent"; } |
input.agent.agentId? | string |
input.agent.kind? | "agent" |
input.context? | { actor: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; authority: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; enabledToolNamespaces: string[]; namespaceId: string; now: string; owner: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; purpose: string; traceId: string; } |
input.context.actor? | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } |
input.context.authority? | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } |
input.context.enabledToolNamespaces? | string[] |
input.context.namespaceId? | string |
input.context.now? | string |
input.context.owner? | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } |
input.context.purpose? | string |
input.context.traceId? | string |
input.executionId? | string |
input.message? | { createdAt: string; id: string; payload: JsonValue; provenance?: { metadata?: JsonObject; parentIds: string[]; source: string; }; purpose: string; receiver: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; replyTo?: string; sender: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; traceId: string; version: "1"; } |
input.message.createdAt? | string |
input.message.id? | string |
input.message.payload? | JsonValue |
input.message.provenance? | { metadata?: JsonObject; parentIds: string[]; source: string; } |
input.message.provenance.metadata? | JsonObject |
input.message.provenance.parentIds? | string[] |
input.message.provenance.source? | string |
input.message.purpose? | string |
input.message.receiver? | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } |
input.message.replyTo? | string |
input.message.sender? | { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; } |
input.message.traceId? | string |
input.message.version? | "1" |
input.metadata? | JsonObject |
input.options? | { maxSteps?: number; maxToolCalls?: number; timeoutMs?: number; } |
input.options.maxSteps? | number |
input.options.maxToolCalls? | number |
input.options.timeoutMs? | number |
input.state? | JsonObject |
input.tools? | object[] |
input.version? | "1" |
options? | ExecuteTurnOptions |
Returns
Promise<{ completedAt: string; events: object[]; executionId: string; metadata?: JsonObject; output: JsonValue; startedAt: string; status: "succeeded"; traceId: string; version: "1"; } | { completedAt: string; error: { code: string; details?: JsonObject; message: string; retryable?: boolean; }; events: object[]; executionId: string; metadata?: JsonObject; startedAt: string; status: "denied"; traceId: string; version: "1"; } | { completedAt: string; error: { code: string; details?: JsonObject; message: string; retryable?: boolean; }; events: object[]; executionId: string; metadata?: JsonObject; startedAt: string; status: "failed"; traceId: string; version: "1"; } | { completedAt: string; error?: { code: string; details?: JsonObject; message: string; retryable?: boolean; }; events: object[]; executionId: string; metadata?: JsonObject; startedAt: string; status: "cancelled"; traceId: string; version: "1"; } | { completedAt: string; escalation: { reason: string; requestedAt: string; requestedAuthority?: { capabilities: object[]; constraints?: { delegationDepth?: number; expiresAt?: string; maxUses?: number; notBefore?: string; purposes?: string[]; }; id: string; metadata?: JsonObject; namespaceId: string; owner: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; purpose: string; requestedAt: string; requester: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; }; reviewer: { kind: "human"; userId: string; } | { agentId: string; kind: "agent"; } | { conversationId: string; kind: "group"; } | { kind: "service"; serviceId: string; }; status: "pending"; }; events: object[]; executionId: string; metadata?: JsonObject; startedAt: string; status: "escalated"; traceId: string; version: "1"; }>
TurnExecutorOptions
Defined in: packages/runtime/src/executor.ts:91
Extends
Properties
| Property | Type | Description | Inherited from | Defined in |
|---|---|---|---|---|
<a id="property-clock-1"></a> clock? | () => string | - | SharedOSExecutorOptions.clock | packages/runtime/src/executor.ts:52 |
<a id="property-closetimeoutms-1"></a> closeTimeoutMs? | number | - | StandardRuntimeOptions.closeTimeoutMs | packages/runtime/src/standard-runtime.ts:101 |
<a id="property-createid-1"></a> createId? | () => string | - | SharedOSExecutorOptions.createId | packages/runtime/src/executor.ts:53 |
<a id="property-defaultmaxsteps-1"></a> defaultMaxSteps? | number | - | SharedOSExecutorOptions.defaultMaxSteps | packages/runtime/src/executor.ts:54 |
<a id="property-defaultmaxtoolcalls-1"></a> defaultMaxToolCalls? | number | - | SharedOSExecutorOptions.defaultMaxToolCalls | packages/runtime/src/executor.ts:55 |
<a id="property-defaulttimeoutms-1"></a> defaultTimeoutMs? | number | - | SharedOSExecutorOptions.defaultTimeoutMs | packages/runtime/src/executor.ts:56 |
<a id="property-onturnerror-2"></a> onTurnError? | TurnErrorReporter | Notification for a throw the turn body did not convert into an outcome. The envelope contains such a throw and ends the turn failed with runtime_failed; the error itself comes here rather than being discarded. See TurnErrorReporter for what it may and may not be used for. Not only the plugin's. The turn body also calls openTurnAuthority, admitTurn, reach, and listTools, and a host port that throws arrives here too under the same terminal code. That conflation is in the wire vocabulary and is not fixed by this hook; the error's own stack is what separates them, which is the reason for handing it over rather than classifying it here. | SharedOSExecutorOptions.onTurnError | packages/runtime/src/executor.ts:78 |
<a id="property-spans-1"></a> spans? | SpanSink | Where the envelope reports what it cost, when a host is measuring. A second clock, and deliberately not the one clock supplies: that one names instants for a record and a conformance run freezes it. See SpanSink. | SharedOSExecutorOptions.spans | packages/runtime/src/executor.ts:64 |
Type Aliases
AgentTurnDecision
AgentTurnDecision = {
call:ToolCall;step?:number;type:"tool_call"; } | {metadata?:JsonObject;output:JsonValue;type:"complete"; } | {error:ProtocolError;metadata?:JsonObject;type:"fail"; } | {metadata?:JsonObject;reason:string;type:"escalate"; }
Defined in: packages/runtime/src/standard-runtime.ts:30
Union Members
Type Literal
{ call: ToolCall; step?: number; type: "tool_call"; }
call
readonlycall:ToolCall
step?
readonlyoptionalstep?:number
The step this call is made at, when the driver wants to say.
The loop declares the position it is at, which is the right answer for
a driver that simply asks for one call per turn of the loop. It is the
wrong answer for a driver deliberately reaching past its budget: the
loop's own index can never exceed maxSteps, because the loop stops
there, so the envelope's step ceiling was unreachable from inside this
runtime and every driven column reported the row as unavailable.
Declaring it here makes the ceiling reachable and keeps it enforced:
the envelope refuses a call at or past maxSteps whoever named the
step, so a driver can claim a step it has no right to and be refused
for it. A driver that says nothing is bounded exactly as before.
It reaches forward only. The loop knows where it is, and a declared step behind that position is not a reach past the budget but a claim the loop can see is false; it is refused as a malformed decision rather than written into the record as the position the call was made at.
type
readonlytype:"tool_call"
Type Literal
{ metadata?: JsonObject; output: JsonValue; type: "complete"; }
Type Literal
{ error: ProtocolError; metadata?: JsonObject; type: "fail"; }
metadata rides on a failure exactly as it does on a completion. A turn
that failed still ran: the model that answered, what it cost, and why it
stopped are facts about the turn rather than about its ending, and a record
that dropped them on failure would know least about the turns that most
need explaining.
Type Literal
{ metadata?: JsonObject; reason: string; type: "escalate"; }
End the turn by asking a human to decide.
RuntimeTurnOutcome has carried an escalate variant from the start, but
nothing running inside this loop could produce one: a driver could complete
or fail and that was all. Escalation was therefore reachable only by a
plugin that replaced the loop entirely, which is why every driven column
reported the escalation row as structurally unavailable -- a limit of this
type, not of any vendor.
The reason is the driver's own words and is recorded verbatim, up to the
512 characters the outcome's contract carries; a driver reading it off a
model or a harness cuts it there rather than replacing it (see
escalationRequest), and one that hands the loop more than that has its
decision refused. Nothing here advances the escalation: SharedOS records
that a decision was asked for and grants nothing while it is pending.
AgentTurnInput
AgentTurnInput = {
type:"start"; } | {result:ToolResult;type:"tool_result"; }
Defined in: packages/runtime/src/standard-runtime.ts:27
AgentTurnRequest
AgentTurnRequest =
RuntimeTurnRequest
Defined in: packages/runtime/src/standard-runtime.ts:88
Backwards-compatible name for the request visible to a standard driver.
AgentVisibleContext
AgentVisibleContext =
RuntimeVisibleContext
Defined in: packages/runtime/src/standard-runtime.ts:85
Backwards-compatible name for the context visible to a standard driver.
RuntimeTurnRequest
RuntimeTurnRequest =
Omit<ExecutionRequest,"context"> > &object
Defined in: packages/runtime/src/runtime-plugin.ts:112
A runtime sees task input and the effective tool catalog, but never grants, issuing authority, or namespace-management state.
Type Declaration
context
readonlycontext:RuntimeVisibleContext
TurnErrorReporter
TurnErrorReporter = (
error,turn) =>void
Defined in: packages/runtime/src/runtime-plugin.ts:48
A host's sink for a throw the turn contained rather than propagated.
Both layers that contain one take it: SharedOSExecutor, whose catch ends
the turn runtime_failed, and StandardRuntime, whose catch ends it
driver_failed. A terminal code says a turn stopped and does not say why;
the thrown error is the only thing that does, so it is handed over whole and
unwrapped, because its stack is what names the origin.
It reaches nothing else. A ProtocolError.message is read by the model, and
an ExecutionEvent becomes part of an ExecutionRecord, which travels
further than an audit sink; a thrown message may carry anything the thrower
had in scope. This is a host-side sink for host-side logs, in the position
SharedOSKernel.onAuditError occupies for the same reason.
Observational. One that throws is ignored -- it cannot replace an outcome
already decided -- and a turn behaves identically with none installed.
Cancellation never reaches it: a turn stopped by the deadline or by the
caller's signal ends cancelled, which is a decision rather than a defect.
The kernel makes the same promise about a provider's throw, under
SharedOSKernelOptions.onProviderError. A host wanting both installs both;
they are separate because they are about different things failing, and the
turn's identifiers are not the ones a mediated call has.
Parameters
| Parameter | Type |
|---|---|
error | unknown |
turn | TurnErrorContext |
Returns
void
TurnKernel
TurnKernel =
Pick<SharedOSKernel,"admitTurn"|"reach"|"listTools"|"invokeTool"> > &Partial<Pick<SharedOSKernel,"openTurnAuthority"|"recordEscalation"|"recordTurnEnd"|"recordRefusedCall">>>>
Defined in: packages/runtime/src/executor.ts:100
The minimal deny-by-default kernel surface required by a turn executor.
Hosts normally pass a SharedOSKernel. Keeping this port explicit also permits narrow test doubles without granting a runtime direct access to registries, namespace settings, or other host policy state.
Variables
DEFAULT_DESCRIBED_REACH_LIMIT
constDEFAULT_DESCRIBED_REACH_LIMIT:128=128
Defined in: packages/runtime/src/reach.ts:15
ESCALATION_ACTION
constESCALATION_ACTION:"request"="request"
Defined in: packages/runtime/src/escalation.ts:13
ESCALATION_ASKED_EVENT
constESCALATION_ASKED_EVENT:"escalation.asked"="escalation.asked"
Defined in: packages/runtime/src/escalation.ts:42
The runtime event a delegate announces the ask under.
Every path that honours the affordance ends the turn without forwarding the
call -- a driver in the standard loop returns an escalate decision, the MCP
latch settles the harness's outcome -- so a working ask leaves no operation
in the record. Neither would an ask the envelope then failed to honour, and
the two would be indistinguishable from a delegate that never asked: a
conformance row graded on the ending could not tell "SharedOS was never
asked" from "SharedOS was asked and did the wrong thing". So the ask is
announced through RuntimeHost.emit at the moment it is recognised, before
anything acts on it, and lands in the record as a runtime.event whatever
the turn then does.
It is the delegate's own claim, which is the safe direction of trust. A
reader can only grade a turn harder on it -- an ask announced and not
honoured is a failure -- and never credit one, because a pass still needs
the turn to have ended escalated. Distinct from the escalation.requested
audit event, which the kernel writes when the envelope records an escalation
it honoured.
ESCALATION_REASON_MAX_LENGTH
constESCALATION_REASON_MAX_LENGTH:512=512
Defined in: packages/runtime/src/escalation.ts:19
The longest reason an escalation can carry, restating the contract's bound on
RuntimeTurnOutcome.reason and Escalation.reason rather than importing a
schema this package does not validate with.
ESCALATION_RESOURCE_PATH
constESCALATION_RESOURCE_PATH: readonlystring[]
Defined in: packages/runtime/src/escalation.ts:12
The resource an escalation grant is written over.
ESCALATION_TOOL_DEFINITION
constESCALATION_TOOL_DEFINITION:ToolDefinition
Defined in: packages/runtime/src/escalation.ts:82
The affordance a driver offers so escalation can be chosen rather than inferred.
A turn that ends by asking a human to decide is a claim about SharedOS -- the request is recorded, audited, and grants nothing while it is pending -- and until now no driver inside the standard loop could make it. Adding the decision variant alone would not have been enough: the model still needs a way to say it, and reading intent out of prose ("I should ask a human") would make the row measure a phrase rather than a choice.
So it is published as a tool. It is permission-filtered like every other tool, which is the point -- escalation is an affordance a host grants, and an agent with no grant over it does not see it in the catalogue at all.
It is nonetheless never invoked. A driver whose turn was offered the tool recognises the name and returns an escalate decision instead of a tool call, so nothing reaches the kernel; see escalationRequest. The kernel-side handler a host registers exists to put the tool in the catalogue and to fail loudly if some driver forwards it anyway, because a call that quietly succeeded would record an escalation the envelope never terminated on.
The filtering is what gates the affordance, and a driver has to honour it
itself: ending a turn on the name skips the envelope, and with it the
envelope's check that the tool was published to this agent. So every driver
that recognises the name reads its turn's catalogue first, and a name the
catalogue does not hold is passed through to be refused tool_unavailable
like any other unpublished tool.
ESCALATION_TOOL_NAME
constESCALATION_TOOL_NAME:"sharedos.escalate"="sharedos.escalate"
Defined in: packages/runtime/src/escalation.ts:10
ESCALATION_TOOL_NAMESPACE
constESCALATION_TOOL_NAMESPACE:"sharedos"="sharedos"
Defined in: packages/runtime/src/escalation.ts:9
STANDARD_RUNTIME_MANIFEST
constSTANDARD_RUNTIME_MANIFEST:RuntimeManifest
Defined in: packages/runtime/src/standard-runtime.ts:116
STANDARD_RUNTIME_VERSION
constSTANDARD_RUNTIME_VERSION:"0.1.0-alpha.5"="0.1.0-alpha.5"
Defined in: packages/runtime/src/standard-runtime.ts:114
Kept equal to the synchronized package version by the release gate.
Functions
createEscalationTool()
createEscalationTool():
ToolHandler
Defined in: packages/runtime/src/escalation.ts:128
The handler a host registers so the affordance is catalogued.
It exists to put ESCALATION_TOOL_DEFINITION in the permission-filtered
catalogue, where an agent sees it only when its context enables the
sharedos tool namespace and it holds a grant over sharedos /
["escalation"] / request. It is never meant to run: a driver whose turn's
catalogue offers it recognises the name (see escalationRequest) and
ends the turn escalated instead of forwarding a call. If a driver forwards it anyway, the handler
fails with escalation_not_terminated rather than succeeding, because a call
that quietly succeeded would leave a record of an escalation tool that ran
and a turn that completed normally -- the confusion the affordance exists to
remove.
Arguments pass through unparsed on purpose. A malformed forwarded call is
still a forwarded call, and reporting it as invalid_tool_arguments would
record the wrong defect.
Returns
describeReach()
describeReach(
reach,options?):string
Defined in: packages/runtime/src/reach.ts:49
RuntimeVisibleContext.reach, as the words a model is shown.
The runtime is handed where the turn may operate so a model can be told
where to look rather than search / and collect denials. This is the telling.
It is the one rendering the shipped runtimes share -- the model driver puts
it in a system message, the MCP harness runtime hands it over as the
server's initialize instructions -- and it is exported so a host writing its
own driver says the same thing the same way.
Every branch of the result is spoken, because each is a different answer:
computedwith entries lists each as a place some grant covers, in the shape the tools take -- the namespace, the path as the JSON array apathargument is, and whether the entry covers what lies beneath it.computedwith none says so. That is a true answer for a turn that reaches nothing, and saying nothing would leave the model to guess.unavailablesays the reach could not be established and names the contract's reason code. It is deliberately not written as an empty list: the executor went to the trouble of handing overunavailableso that "nothing" and "unknown" stay distinguishable (ADR 0021), and a renderer that collapsed them would rebuild the silent case at the last hop. A call that depends on what could not be read fails closed under the same code, so the code is what lets the model correlate the two.
Every rendering says that the text is descriptive: each call is still
decided on its own, so an entry here is not a permission and a missing one
is not a refusal. Actions are listed as the grants state them, not as the
offered tools could exercise them -- reachThroughTools narrows by
namespace and leaves actions alone -- which is one more reason the model is
told the list decides nothing.
Parameters
| Parameter | Type |
|---|---|
reach | { reach: object[]; status: "computed"; } | { reasonCode: "authority_unavailable" | "usage_store_unavailable"; status: "unavailable"; } |
options | DescribeReachOptions |
Returns
string
escalationArguments()
escalationArguments(
reason):JsonObject
Defined in: packages/runtime/src/escalation.ts:203
The arguments an escalation is requested with, for a driver writing the call.
Parameters
| Parameter | Type |
|---|---|
reason | string |
Returns
escalationAskedEvent()
escalationAskedEvent(
reason):object
Defined in: packages/runtime/src/escalation.ts:50
The announcement a delegate emits when it recognises the affordance.
Emitted for the record, not for the turn: a delegate that cannot announce the ask still ends the turn on it, and only the trace is lost.
Parameters
| Parameter | Type |
|---|---|
reason | string |
Returns
object
data
data:
JsonValue
type
type:
string
escalationOffered()
escalationOffered(
tools):boolean
Defined in: packages/runtime/src/escalation.ts:237
Whether a turn's catalogue offers the affordance.
The gate on honouring the name (ADR 0017, "The catalogue gates the name"):
a driver reads it from the same tools it offered the seat's occupant, and
the executor from the catalogue the turn was actually served.
Parameters
| Parameter | Type |
|---|---|
tools | readonly object[] |
Returns
boolean
escalationReason()
escalationReason(
value):string|undefined
Defined in: packages/runtime/src/escalation.ts:220
A reason string bounded exactly as RuntimeTurnOutcome's is.
Checked here rather than with a schema because this package carries no validator of its own; the bounds are the contract's and are restated, not loosened, so a decision that parses here still parses as an outcome.
Strict where escalationRequest cuts, on purpose. That function reads a model's or a harness's words, which are input; this one checks a driver's decision, which is code. A driver that hands the loop an overlong reason has a bug, and the loop refusing the decision is how the bug is found rather than quietly trimmed away.
Parameters
| Parameter | Type |
|---|---|
value | unknown |
Returns
string | undefined
escalationRequest()
escalationRequest(
tool,arguments_):string|undefined
Defined in: packages/runtime/src/escalation.ts:170
Read an escalation out of a call a driver is about to make, if that is what it is.
Returns the reason when the call names the affordance and carries a usable
one, and undefined for anything else -- which a driver passes on unchanged,
so a tool that merely resembles this one is still re-authorized by the kernel
like any other.
This recognises the name and nothing else. Whether the turn was offered the
tool is the caller's check to make, from its own RuntimeTurnRequest.tools,
before asking; a caller that honours the name unconditionally has given
every agent the affordance regardless of grant.
A call that names the affordance with unreadable arguments still escalates, under a reason saying so. The alternative is to forward it to a kernel that will refuse it, which turns "the driver asked for a human" into "the agent made a malformed call" -- the wrong record of what happened.
A reason longer than the outcome can carry is cut to ESCALATION_REASON_MAX_LENGTH, not replaced. It is the occupant's own words, and the first 512 characters of what was said are a truer record than a sentence saying nothing was.
Parameters
| Parameter | Type |
|---|---|
tool | string |
arguments_ | unknown |
Returns
string | undefined
reportTurnError()
reportTurnError(
reporter,error,turn):void
Defined in: packages/runtime/src/runtime-plugin.ts:66
Call one turn-error sink without letting it change what happened.
The turn-shaped name for reportContainedError, which is where the guard
itself lives: a sink that throws is swallowed, because a diagnostic that can
turn one failure into two is a liability rather than a diagnostic.
It delegates rather than repeating the rule. The kernel contains a provider's throw and the runtime contains a plugin's, and the same promise is made to a host about both; two implementations of one promise is how it stops being true in one of them. Core owns it because the dependency runs runtime → core and cannot run back.
Exported deliberately, for a host writing its own RuntimePlugin that offers the same hook.
Parameters
| Parameter | Type |
|---|---|
reporter | TurnErrorReporter | undefined |
error | unknown |
turn | TurnErrorContext |
Returns
void