@theokit/agents 7.6.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-handle-BX4oFqfb.d.ts → agent-handle-Dgi4ZGbg.d.ts} +11 -1
- package/dist/ask.d.ts +190 -0
- package/dist/ask.js +167 -0
- package/dist/ask.js.map +1 -0
- package/dist/auth.d.ts +95 -1
- package/dist/auth.js +83 -0
- package/dist/auth.js.map +1 -1
- package/dist/{bridge-entry-CvmBrmc9.d.ts → bridge-entry-BEniSXWE.d.ts} +223 -700
- package/dist/bridge.d.ts +6 -3
- package/dist/bridge.js +16 -8
- package/dist/chunk-4VHCH6IZ.js +181 -0
- package/dist/chunk-4VHCH6IZ.js.map +1 -0
- package/dist/{chunk-22IPZFVT.js → chunk-C7UXZWVY.js} +167 -207
- package/dist/chunk-C7UXZWVY.js.map +1 -0
- package/dist/{chunk-2BAFKRXT.js → chunk-M6HMASZC.js} +9 -4
- package/dist/chunk-M6HMASZC.js.map +1 -0
- package/dist/client-react.d.ts +2 -1
- package/dist/client-react.js +1 -1
- package/dist/client.d.ts +3 -2
- package/dist/client.js +1 -1
- package/dist/commands.d.ts +120 -0
- package/dist/commands.js +145 -0
- package/dist/commands.js.map +1 -0
- package/dist/define-agent-3Kuf6iKM.d.ts +633 -0
- package/dist/doctor.d.ts +119 -0
- package/dist/doctor.js +84 -0
- package/dist/doctor.js.map +1 -0
- package/dist/hook-handlers-Cw2FsnE5.d.ts +56 -0
- package/dist/hooks.d.ts +225 -0
- package/dist/hooks.js +286 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +170 -26
- package/dist/index.js +90 -22
- package/dist/index.js.map +1 -1
- package/dist/mcp-health.d.ts +69 -0
- package/dist/mcp-health.js +42 -0
- package/dist/mcp-health.js.map +1 -0
- package/dist/session.d.ts +238 -0
- package/dist/session.js +338 -0
- package/dist/session.js.map +1 -0
- package/dist/testing.d.ts +90 -1
- package/dist/testing.js +76 -1
- package/dist/testing.js.map +1 -1
- package/dist/tool-scope.d.ts +133 -0
- package/dist/tool-scope.js +61 -0
- package/dist/tool-scope.js.map +1 -0
- package/dist/usage.d.ts +98 -0
- package/dist/usage.js +55 -0
- package/dist/usage.js.map +1 -0
- package/package.json +34 -2
- package/dist/chunk-22IPZFVT.js.map +0 -1
- package/dist/chunk-2BAFKRXT.js.map +0 -1
|
@@ -1,178 +1,12 @@
|
|
|
1
1
|
import { ExecutionContext } from '@theokit/http';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { d as AgentOptions, T as ToolOptions, z as ProjectContextOptions, C as CompiledAgentOptions, H as HumanInTheLoopOptions, A as AgentDefinition, a as CompiledTool, R as ReasoningEffort, G as Guardrail, p as SkillsSelection, S as SettingSourcesSelection, l as McpServersMap, M as MainLoopMeta } from './define-agent-3Kuf6iKM.js';
|
|
3
|
+
import { SkillsSettings, ContextSettings, SystemPromptResolver, ModelSelection, PluginsSettings, Plugin, ProviderRoutingSettings, AgentDefinition as AgentDefinition$1, BudgetTracker, CustomTool, RunEventSink, MemorySettings } from '@theokit/sdk';
|
|
4
|
+
import { SandboxPosture } from '@theokit/sdk/sandbox';
|
|
4
5
|
import { WireChunk } from '@theokit/presenter/wire';
|
|
5
|
-
import {
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { H as HookHandlers } from './hook-handlers-Cw2FsnE5.js';
|
|
6
8
|
import { TheokitAgentError } from '@theokit/sdk/errors';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Provider-agnostic extended-thinking knob (M1 reasoning-visibility). The common set autocompletes;
|
|
10
|
-
* `(string & {})` accepts provider-specific values forward-compat (mirrors `AgentRunErrorCode`) — the
|
|
11
|
-
* SDK validates the value against the model's catalog. Defined in this leaf module so every layer
|
|
12
|
-
* (`@Agent` config, compiler, runner, sdk-adapter) imports it without an import cycle.
|
|
13
|
-
*/
|
|
14
|
-
type ReasoningEffort = 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | (string & {});
|
|
15
|
-
/** Scalar agent configuration. */
|
|
16
|
-
interface AgentOptions {
|
|
17
|
-
/** Unique agent name (kebab-case). */
|
|
18
|
-
name: string;
|
|
19
|
-
/** HTTP route prefix (e.g., '/api/agents/support'). */
|
|
20
|
-
route: string;
|
|
21
|
-
/** LLM model identifier (e.g., 'claude-sonnet-4-5-20250929'). */
|
|
22
|
-
model?: string;
|
|
23
|
-
/** Extended-thinking effort; mapped to the SDK `ModelSelection.params` so the provider reasons. */
|
|
24
|
-
reasoningEffort?: ReasoningEffort;
|
|
25
|
-
/**
|
|
26
|
-
* Opt-in (default false): convert inline `<think>…</think>` in the text stream into `thinking`
|
|
27
|
-
* events (M2) — for models that emit reasoning as inline tags (qwen/deepseek) rather than via a
|
|
28
|
-
* native reasoning param. Off by default since a code assistant may emit literal `<think>` in text.
|
|
29
|
-
*/
|
|
30
|
-
parseThinkTags?: boolean;
|
|
31
|
-
/**
|
|
32
|
-
* Opt-in (default false): strip a leaked Hermes `<function=…></tool_call>` tool-call dialect out of
|
|
33
|
-
* the visible text (theocode#32) — for models (qwen/qwen3-coder) that intermittently emit tool calls
|
|
34
|
-
* as text instead of native `tool_calls`. Off by default since a code assistant may emit a literal
|
|
35
|
-
* `<function=` in answer/code text. Sibling of {@link parseThinkTags}.
|
|
36
|
-
*/
|
|
37
|
-
stripToolDialect?: boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Opt-in (default false): recover a leaked Hermes `<function=…></tool_call>` tool-call dialect so the
|
|
40
|
-
* call actually EXECUTES (theokit#58 follow-up). Where {@link stripToolDialect} only hides the leaked
|
|
41
|
-
* block from the visible text, this enables the SDK's `extractToolCallsFromContent` on the chat route,
|
|
42
|
-
* so a `chat_completions` finish with ZERO native `tool_calls` has its text scanned for the dialect and
|
|
43
|
-
* any recovered calls are dispatched by the loop. For models (qwen/qwen3-coder via OpenRouter) that
|
|
44
|
-
* leak tool calls as text. Off by default (a code assistant may print a literal `<function=`); fail-open.
|
|
45
|
-
* Has effect only when {@link AgentOptions} routes a provider via `providers.routes`. Sibling of
|
|
46
|
-
* {@link stripToolDialect} — typically enabled together.
|
|
47
|
-
*/
|
|
48
|
-
recoverLeakedToolCalls?: boolean;
|
|
49
|
-
/** Enable SSE streaming (default: true). */
|
|
50
|
-
stream?: boolean;
|
|
51
|
-
/** Maximum loop iterations before forcing a terminal response. */
|
|
52
|
-
maxIterations?: number;
|
|
53
|
-
/** Timeout in milliseconds for the entire agent run. */
|
|
54
|
-
timeoutMs?: number;
|
|
55
|
-
/**
|
|
56
|
-
* System prompt for the agent. Either a static string OR a
|
|
57
|
-
* {@link SystemPromptResolver} computed per request (V4-L.1, Axis-B) — the SDK
|
|
58
|
-
* invokes the resolver each send with the run's `SystemPromptContext` (cwd, etc.).
|
|
59
|
-
*/
|
|
60
|
-
systemPrompt?: string | SystemPromptResolver;
|
|
61
|
-
}
|
|
62
|
-
/** Configuration stored by @MainLoop() decorator. */
|
|
63
|
-
interface MainLoopOptions {
|
|
64
|
-
/** Execution strategy. */
|
|
65
|
-
strategy?: 'simple-chat' | 'plan-act-reflect' | 'react';
|
|
66
|
-
/** Maximum iterations for this loop. */
|
|
67
|
-
maxIterations?: number;
|
|
68
|
-
/** Timeout in milliseconds. */
|
|
69
|
-
timeoutMs?: number;
|
|
70
|
-
}
|
|
71
|
-
/** Internal representation of a resolved @MainLoop. */
|
|
72
|
-
interface MainLoopMeta {
|
|
73
|
-
propertyKey: string | symbol;
|
|
74
|
-
strategy: 'simple-chat' | 'plan-act-reflect' | 'react';
|
|
75
|
-
maxIterations?: number;
|
|
76
|
-
timeoutMs?: number;
|
|
77
|
-
}
|
|
78
|
-
/** Configuration stored by @Toolbox() decorator. */
|
|
79
|
-
interface ToolboxOptions {
|
|
80
|
-
/** Namespace prefix for all tools in this toolbox (e.g., 'support'). */
|
|
81
|
-
namespace?: string;
|
|
82
|
-
}
|
|
83
|
-
/** Configuration stored by @Tool() decorator. */
|
|
84
|
-
interface ToolOptions {
|
|
85
|
-
/** Tool name (surfaced to LLM). */
|
|
86
|
-
name: string;
|
|
87
|
-
/** LLM-facing description. */
|
|
88
|
-
description: string;
|
|
89
|
-
/** Zod input schema — compiled to JSON Schema via defineTool(). */
|
|
90
|
-
input: z.ZodType;
|
|
91
|
-
/** Risk level (informational — feeds manifest + UI). */
|
|
92
|
-
risk?: 'low' | 'medium' | 'high';
|
|
93
|
-
}
|
|
94
|
-
/** Budget configuration for @Budget() decorator. */
|
|
95
|
-
interface BudgetOptions {
|
|
96
|
-
/** Maximum cost in USD for this scope. */
|
|
97
|
-
maxCostUsd: number;
|
|
98
|
-
/** Rolling window for budget tracking. */
|
|
99
|
-
window?: 'daily' | 'monthly';
|
|
100
|
-
}
|
|
101
|
-
/** Approval configuration for @RequiresApproval() decorator. */
|
|
102
|
-
interface ApprovalOptions {
|
|
103
|
-
/** Reason shown to the approver. */
|
|
104
|
-
reason: string;
|
|
105
|
-
}
|
|
106
|
-
/** Policy handler function type. */
|
|
107
|
-
type PolicyHandler = (user: {
|
|
108
|
-
roles: string[];
|
|
109
|
-
}) => boolean;
|
|
110
|
-
/**
|
|
111
|
-
* M53 — moved here from the `@HumanInTheLoop` decorator, which is being deleted: the type is
|
|
112
|
-
* consumed by `compileHitlGates` and the toolbox capability, not by the decorator alone.
|
|
113
|
-
*/
|
|
114
|
-
type TimeoutAction = 'abort' | 'proceed' | 'retry';
|
|
115
|
-
interface HumanInTheLoopOptions {
|
|
116
|
-
/** Question shown to the human approver. */
|
|
117
|
-
question: string;
|
|
118
|
-
/** Timeout in milliseconds before onTimeout fires (default: 300_000 = 5 min). */
|
|
119
|
-
timeout?: number;
|
|
120
|
-
/** Action when timeout expires (default: 'abort'). */
|
|
121
|
-
onTimeout?: TimeoutAction;
|
|
122
|
-
/** Show the tool input to the approver (default: true). */
|
|
123
|
-
showInput?: boolean;
|
|
124
|
-
/**
|
|
125
|
-
* M20 — an optional JSON-schema descriptor of the custom payload the approver may attach (edited
|
|
126
|
-
* args, a review note). Carried into the `approval_required` event + `GET /approvals` so the UI
|
|
127
|
-
* knows what to collect. A plain JSON object, not a live Zod schema (keeps the wire serializable).
|
|
128
|
-
*/
|
|
129
|
-
payloadSchema?: Record<string, unknown>;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
type McpServersMap = Record<string, McpServerConfig>;
|
|
133
|
-
/** M53 — moved from the `@ProjectContext` decorator being deleted; read by the compiler. */
|
|
134
|
-
type IndexStrategy = 'tree-sitter' | 'regex' | 'none';
|
|
135
|
-
type RelevanceStrategy = 'git-history' | 'import-graph' | 'semantic' | 'manual';
|
|
136
|
-
interface ProjectContextOptions {
|
|
137
|
-
/** Files that mark the project root (searched upward from cwd). */
|
|
138
|
-
rootMarkers?: string[];
|
|
139
|
-
/** How to index the codebase for structural understanding. */
|
|
140
|
-
indexStrategy?: IndexStrategy;
|
|
141
|
-
/** Maximum files to include in context per request. */
|
|
142
|
-
maxFilesInContext?: number;
|
|
143
|
-
/** How to rank file relevance when selecting context. */
|
|
144
|
-
relevanceStrategy?: RelevanceStrategy;
|
|
145
|
-
/** Glob patterns to exclude from indexing and context. */
|
|
146
|
-
ignorePatterns?: string[];
|
|
147
|
-
/** File extensions to include in indexing (default: all text files). */
|
|
148
|
-
includeExtensions?: string[];
|
|
149
|
-
}
|
|
150
|
-
type CheckpointStrategy = 'after-tool-call' | 'after-iteration' | 'manual';
|
|
151
|
-
type CheckpointStorage = 'memory' | 'filesystem' | 'drizzle' | 'redis';
|
|
152
|
-
interface CheckpointOptions {
|
|
153
|
-
/** Where to persist checkpoints. */
|
|
154
|
-
storage?: CheckpointStorage;
|
|
155
|
-
/** When to auto-checkpoint (default: 'after-tool-call'). */
|
|
156
|
-
strategy?: CheckpointStrategy;
|
|
157
|
-
/** Maximum checkpoints to retain per run (rolling window). */
|
|
158
|
-
maxCheckpoints?: number;
|
|
159
|
-
/** Time-to-live in ms before checkpoints expire (default: 3_600_000 = 1h). */
|
|
160
|
-
ttl?: number;
|
|
161
|
-
}
|
|
162
|
-
type MemoryProvider = 'built-in' | 'honcho' | 'supermemory' | 'mem0';
|
|
163
|
-
type MemoryScope = 'per-user' | 'per-agent' | 'per-tenant' | 'global';
|
|
164
|
-
interface MemoryOptions {
|
|
165
|
-
/** Memory provider backend. */
|
|
166
|
-
provider?: MemoryProvider;
|
|
167
|
-
/** Enable semantic search via embeddings. */
|
|
168
|
-
embeddings?: boolean;
|
|
169
|
-
/** Enable full-text search (FTS5). */
|
|
170
|
-
fts?: boolean;
|
|
171
|
-
/** Memory isolation scope (default: 'per-user'). */
|
|
172
|
-
scope?: MemoryScope;
|
|
173
|
-
/** Maximum facts to retain per scope (0 = unlimited). */
|
|
174
|
-
maxFacts?: number;
|
|
175
|
-
}
|
|
9
|
+
import { RetryOptions } from '@theokit/sdk/retry';
|
|
176
10
|
|
|
177
11
|
/**
|
|
178
12
|
* AgentExecutionContext — extends http-decorators' ExecutionContext with agent-specific methods.
|
|
@@ -200,215 +34,6 @@ declare function createAgentExecutionContext(base: ExecutionContext, agent: Agen
|
|
|
200
34
|
/** Narrow an ExecutionContext to AgentExecutionContext if it is one. */
|
|
201
35
|
declare function isAgentContext(ctx: ExecutionContext): ctx is AgentExecutionContext;
|
|
202
36
|
|
|
203
|
-
/**
|
|
204
|
-
* M9 (theokit-ai-first) — guardrail contract + typed errors.
|
|
205
|
-
*
|
|
206
|
-
* ADR-0040 § D2: guardrails are a HOME/BOUNDARY concern (filter user input before the SDK,
|
|
207
|
-
* filter model output before the client). They REUSE the SDK runtime — this module makes zero
|
|
208
|
-
* LLM calls. A guard reports one of three actions; the pipeline (`pipeline.ts`) enforces them.
|
|
209
|
-
*/
|
|
210
|
-
/** What a guard decided for a piece of text. */
|
|
211
|
-
type GuardrailAction = 'allow' | 'block' | 'redact';
|
|
212
|
-
/**
|
|
213
|
-
* The result of a single guard check.
|
|
214
|
-
* - `allow` — text passes untouched.
|
|
215
|
-
* - `block` — the pipeline throws {@link GuardrailViolationError}; the run stops fail-fast.
|
|
216
|
-
* - `redact` — the pipeline replaces the text with {@link GuardrailResult.text} and continues.
|
|
217
|
-
*/
|
|
218
|
-
interface GuardrailResult {
|
|
219
|
-
action: GuardrailAction;
|
|
220
|
-
/** Human-readable reason — required in spirit for `block`, surfaced in the thrown error. */
|
|
221
|
-
reason?: string;
|
|
222
|
-
/** The transformed text — present (and used) only when `action === 'redact'`. */
|
|
223
|
-
text?: string;
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* A guardrail. A guard MAY inspect input (before the model), output (after the model), or both.
|
|
227
|
-
* A guard that omits a phase hook is skipped for that phase.
|
|
228
|
-
*/
|
|
229
|
-
interface Guardrail {
|
|
230
|
-
readonly name: string;
|
|
231
|
-
checkInput?(text: string): GuardrailResult | Promise<GuardrailResult>;
|
|
232
|
-
checkOutput?(text: string): GuardrailResult | Promise<GuardrailResult>;
|
|
233
|
-
}
|
|
234
|
-
/** Which boundary phase a violation happened in. */
|
|
235
|
-
type GuardrailPhase = 'input' | 'output';
|
|
236
|
-
/** Thrown (fail-fast) when a guard returns `action: 'block'`. Typed per error-handling.md. */
|
|
237
|
-
declare class GuardrailViolationError extends Error {
|
|
238
|
-
readonly guardName: string;
|
|
239
|
-
readonly phase: GuardrailPhase;
|
|
240
|
-
readonly reason: string;
|
|
241
|
-
constructor(guardName: string, phase: GuardrailPhase, reason: string);
|
|
242
|
-
}
|
|
243
|
-
/** Thrown when {@link costGuard}'s cumulative token budget is exceeded. */
|
|
244
|
-
declare class CostBudgetExceededError extends Error {
|
|
245
|
-
readonly usedTokens: number;
|
|
246
|
-
readonly maxTokens: number;
|
|
247
|
-
constructor(usedTokens: number, maxTokens: number);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* M13 (theokit-ai-first) — per-request skills resolution (ADR-0040 § D2, home/boundary concern).
|
|
252
|
-
*
|
|
253
|
-
* The static `skills.enabled` filter already works (`compile-skills` maps `include` → the SDK's
|
|
254
|
-
* `enabled`). This adds a PER-REQUEST resolver so multi-tenant apps expose different skill sets to
|
|
255
|
-
* different users. A selection is either a static list or a function of the request context (the M7
|
|
256
|
-
* run-context). Discovery + injection stay in the SDK; this only CHOOSES the enabled set per call.
|
|
257
|
-
*/
|
|
258
|
-
|
|
259
|
-
/** The request context handed to a skills resolver (the M7 run-context — opaque per-request data). */
|
|
260
|
-
type SkillsRequestContext = Record<string, unknown>;
|
|
261
|
-
/**
|
|
262
|
-
* How the skill set is chosen:
|
|
263
|
-
* - a static array of `string` (filesystem skill NAMES → `skills.enabled`) and/or `InlineSkill`
|
|
264
|
-
* objects from `createSkill` (code-defined skills → `skills.inline`, injected into the `<skills>`
|
|
265
|
-
* block). A mixed list is split at compile time.
|
|
266
|
-
* - a function — resolved per request from the {@link SkillsRequestContext} (sync or async). The
|
|
267
|
-
* resolver returns filesystem skill NAMES (inline skills are static — declared on the agent).
|
|
268
|
-
*/
|
|
269
|
-
type SkillsSelection = readonly (string | InlineSkill)[] | ((ctx: SkillsRequestContext) => readonly string[] | Promise<readonly string[]>);
|
|
270
|
-
/**
|
|
271
|
-
* Resolve the enabled skill names for a request. Returns `undefined` when no selection is given (the
|
|
272
|
-
* SDK then enables every discovered skill). Fails fast if a resolver returns a non-array. The static
|
|
273
|
-
* array is compiled ahead of time (see `compileSkillsSelection`), so this is exercised for the
|
|
274
|
-
* resolver form; a static array is defensively narrowed to its string (name) members.
|
|
275
|
-
*/
|
|
276
|
-
declare function resolveEnabledSkills(selection: SkillsSelection | undefined, ctx: SkillsRequestContext): Promise<string[] | undefined>;
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* Agent compiler — transforms decorator metadata into SDK calls.
|
|
280
|
-
*
|
|
281
|
-
* Per ADR D1: @Agent is a macro over Agent.create().
|
|
282
|
-
* Per ADR D3: @Tool compiles to defineTool().
|
|
283
|
-
*
|
|
284
|
-
* EC-3: throws if toolbox instance is missing from the instances map.
|
|
285
|
-
*/
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* M53 — the input shape `compileTools`/`compileHitlGates` consume, declared WITH them now that the
|
|
289
|
-
* metadata walk that used to own it is gone. `ToolboxCapability` builds this from a class'
|
|
290
|
-
* `static tools` declaration.
|
|
291
|
-
*/
|
|
292
|
-
/** A guard/interceptor class token — identity only (the DI container instantiates it). */
|
|
293
|
-
type ClassToken = abstract new (...args: never[]) => object;
|
|
294
|
-
interface ToolWalkResult {
|
|
295
|
-
propertyKey: string | symbol;
|
|
296
|
-
config: ToolOptions;
|
|
297
|
-
guards: ClassToken[];
|
|
298
|
-
approval?: ApprovalOptions;
|
|
299
|
-
capabilities?: string[];
|
|
300
|
-
budget?: BudgetOptions;
|
|
301
|
-
trace: boolean;
|
|
302
|
-
audit: boolean;
|
|
303
|
-
/** HITL config when the tool is gated (M4); absent ⇒ not gated. */
|
|
304
|
-
hitl?: HumanInTheLoopOptions;
|
|
305
|
-
}
|
|
306
|
-
interface ToolboxWalkResult {
|
|
307
|
-
/** The toolbox class — used as the identity key into `toolboxInstances`. */
|
|
308
|
-
class: ClassToken;
|
|
309
|
-
namespace: string;
|
|
310
|
-
tools: ToolWalkResult[];
|
|
311
|
-
guards: ClassToken[];
|
|
312
|
-
}
|
|
313
|
-
/** Minimal interface matching defineTool() result shape. */
|
|
314
|
-
interface CompiledTool {
|
|
315
|
-
name: string;
|
|
316
|
-
description: string;
|
|
317
|
-
inputSchema: unknown;
|
|
318
|
-
/**
|
|
319
|
-
* M7 — the optional 2nd `ctx` arg carries the SDK run context: `ctx.context` is the
|
|
320
|
-
* `defineAgent({ context })` / per-run value, `ctx.signal` the abort signal. Optional so the
|
|
321
|
-
* decorator `@Tool` handlers (which ignore it) stay assignable. The SDK calls the tool with
|
|
322
|
-
* both args; a handler that needs run-context (e.g. a filesystem tool reading `projectRoot`)
|
|
323
|
-
* reads `ctx?.context`.
|
|
324
|
-
*/
|
|
325
|
-
handler: (input: unknown, ctx?: {
|
|
326
|
-
signal?: AbortSignal;
|
|
327
|
-
context?: unknown;
|
|
328
|
-
}) => string | Promise<string>;
|
|
329
|
-
}
|
|
330
|
-
/**
|
|
331
|
-
* Compile @Tool metadata into tool definitions.
|
|
332
|
-
*
|
|
333
|
-
* @param toolboxes - Walked toolbox metadata
|
|
334
|
-
* @param toolboxInstances - Map of Toolbox class → instantiated object (for `this` binding)
|
|
335
|
-
*/
|
|
336
|
-
declare function compileTools(toolboxes: ToolboxWalkResult[], toolboxInstances: Map<ClassToken, object>): CompiledTool[];
|
|
337
|
-
/** Compiled sub-agent definition matching SDK AgentDefinition shape. */
|
|
338
|
-
interface CompiledSubAgent {
|
|
339
|
-
model?: string;
|
|
340
|
-
/**
|
|
341
|
-
* V4-L.1: typed as the union for consistency with `AgentOptions.systemPrompt`,
|
|
342
|
-
* so `compileSubAgents` carries whatever the sub-agent declared. Sub-agent
|
|
343
|
-
* resolver EXECUTION is out of scope this slice (ADR D3): `compiled.agents` is
|
|
344
|
-
* not spread into `Agent.create` by `createSdkAgentStream`; a resolver here is
|
|
345
|
-
* carried, not invoked. Top-level agent resolvers are the supported path.
|
|
346
|
-
*/
|
|
347
|
-
systemPrompt?: string | SystemPromptResolver;
|
|
348
|
-
}
|
|
349
|
-
/** Compiled agent options ready for SDK Agent.create(). */
|
|
350
|
-
interface CompiledAgentOptions {
|
|
351
|
-
model?: string;
|
|
352
|
-
/** Extended-thinking effort; mapped to SDK ModelSelection.params. */
|
|
353
|
-
reasoningEffort?: ReasoningEffort;
|
|
354
|
-
/** Opt-in `<think>`-tag extraction (M2); wraps the stream when true. */
|
|
355
|
-
parseThinkTags?: boolean;
|
|
356
|
-
/** Opt-in tool-dialect stripping (theocode#32); strips leaked `<function=…></tool_call>` from text when true. */
|
|
357
|
-
stripToolDialect?: boolean;
|
|
358
|
-
/** Opt-in leaked-dialect recovery (theokit#58); enables the SDK route's `extractToolCallsFromContent` so leaked tool calls EXECUTE when true. */
|
|
359
|
-
recoverLeakedToolCalls?: boolean;
|
|
360
|
-
/** Static prompt OR a per-request {@link SystemPromptResolver} (V4-L.1, Axis-B). */
|
|
361
|
-
systemPrompt?: string | SystemPromptResolver;
|
|
362
|
-
/**
|
|
363
|
-
* theokit-file-based-config — opt-in `.theokit/` file-based config roots (`"project"`/`"user"`/…).
|
|
364
|
-
* Projected into `Agent.create({ local: { settingSources } })` by `assembleM8CreateOptions`
|
|
365
|
-
* (merged with `cwd`, decoupled from inline skills). Absent ⇒ inline (code) config only.
|
|
366
|
-
*/
|
|
367
|
-
settingSources?: readonly SettingSource[];
|
|
368
|
-
/** Code `Plugin` objects forwarded to `Agent.create({ plugins })` (lifecycle-hook seam). */
|
|
369
|
-
plugins?: readonly unknown[];
|
|
370
|
-
tools: CompiledTool[];
|
|
371
|
-
agents: Record<string, CompiledSubAgent>;
|
|
372
|
-
memory?: MemoryOptions | MemorySettings;
|
|
373
|
-
skills?: SkillsSettings;
|
|
374
|
-
context?: ContextSettings;
|
|
375
|
-
/**
|
|
376
|
-
* M7 — run-context injected into every tool handler's `ctx.context` by the theokit adapter
|
|
377
|
-
* (`buildSdkTools` wrapper). Populated by `defineAgent({ context })` (functional surface).
|
|
378
|
-
* NAME NOTE: distinct from the context-window `context` (`ContextSettings`) above — this is
|
|
379
|
-
* per-run user data for tools, not token-budget config.
|
|
380
|
-
*/
|
|
381
|
-
runContext?: Record<string, unknown>;
|
|
382
|
-
/** Raw @ProjectContext config; the adapter builds the (async) systemPrompt resolver from it. */
|
|
383
|
-
projectContext?: ProjectContextOptions;
|
|
384
|
-
mcpServers?: McpServersMap;
|
|
385
|
-
maxIterations?: number;
|
|
386
|
-
timeoutMs?: number;
|
|
387
|
-
stream: boolean;
|
|
388
|
-
/**
|
|
389
|
-
* HITL gate map (M4): runtime tool name → `@HumanInTheLoop` config. Absent/empty ⇒ no gated
|
|
390
|
-
* tools. The harness (`mountAgent`) turns this into the `pre_tool_call` pause wiring.
|
|
391
|
-
*/
|
|
392
|
-
hitl?: Map<string, HumanInTheLoopOptions>;
|
|
393
|
-
/**
|
|
394
|
-
* `@Checkpoint` config (M4): when present the harness emits `checkpoint_saved` and selects the
|
|
395
|
-
* durable SDK conversation storage (`storage: 'filesystem'`) so a same-`sessionId` request resumes.
|
|
396
|
-
*/
|
|
397
|
-
checkpoint?: CheckpointOptions;
|
|
398
|
-
/**
|
|
399
|
-
* M9 — guardrails: input/output guards applied at the framework boundary (ADR-0040 § D2).
|
|
400
|
-
* Input guards run on the user message BEFORE the SDK runtime sees it (fail-fast on `block`).
|
|
401
|
-
* They REUSE the runtime; they never reimplement it. Absent/empty ⇒ no guards.
|
|
402
|
-
*/
|
|
403
|
-
guardrails?: readonly Guardrail[];
|
|
404
|
-
/**
|
|
405
|
-
* M13 — per-request skills resolver (from `defineAgent({ skills: (ctx) => [...] })`). The request
|
|
406
|
-
* path resolves it against the run-context (`resolveEnabledSkills`) and sets `skills.enabled`
|
|
407
|
-
* before the SDK runs. Not consumed by the SDK directly (it reads `skills`). Absent ⇒ no resolver.
|
|
408
|
-
*/
|
|
409
|
-
skillsResolver?: SkillsSelection;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
37
|
/**
|
|
413
38
|
* M8-3 — compile `@Skills` metadata into the SDK's `SkillsSettings`.
|
|
414
39
|
*
|
|
@@ -448,22 +73,12 @@ declare function compileSkills(options: SkillsOptions): SkillsSettings;
|
|
|
448
73
|
* (ADR D2) instead of silently dropping them (G10 — honest enforcement).
|
|
449
74
|
*/
|
|
450
75
|
|
|
451
|
-
/** How to compact the transcript when `maxTokens` is exceeded. */
|
|
452
|
-
type ContextCompactionStrategy = 'truncate-oldest' | 'summarize-oldest' | 'sliding-window' | 'priority-based';
|
|
453
76
|
/**
|
|
454
77
|
* M53 — declared here, with its conversion, instead of on the decorator being deleted.
|
|
455
78
|
*/
|
|
456
79
|
interface ContextWindowOptions {
|
|
457
80
|
/** Maximum tokens before compaction triggers. */
|
|
458
81
|
maxTokens?: number;
|
|
459
|
-
/** How to compact when maxTokens is exceeded. */
|
|
460
|
-
compactionStrategy?: ContextCompactionStrategy;
|
|
461
|
-
/** Always preserve the system prompt during compaction (default: true). */
|
|
462
|
-
preserveSystemPrompt?: boolean;
|
|
463
|
-
/** Number of recent messages to always keep intact (default: 10). */
|
|
464
|
-
preserveLastN?: number;
|
|
465
|
-
/** Keep all tool results even during compaction (default: true). */
|
|
466
|
-
preserveToolResults?: boolean;
|
|
467
82
|
}
|
|
468
83
|
interface CompiledContextWindow {
|
|
469
84
|
/** SDK-shaped context budget passed to `Agent.create({ context })`. */
|
|
@@ -786,6 +401,31 @@ interface HitlWiring {
|
|
|
786
401
|
awaitApproval: (approvalId: string, opts: HumanInTheLoopOptions, toolName: string) => Promise<boolean | HitlDecision>;
|
|
787
402
|
}
|
|
788
403
|
|
|
404
|
+
/**
|
|
405
|
+
* M96 U1 — the approval posture: what a surface does when a gated tool asks for approval.
|
|
406
|
+
*
|
|
407
|
+
* ## Why a closed type, and why mandatory
|
|
408
|
+
*
|
|
409
|
+
* The defect this module closes was one of TYPE, not of behaviour. The "no HITL" posture was not
|
|
410
|
+
* representable as a value, so it was expressed as ABSENCE — and an absence has no exhaustive
|
|
411
|
+
* `match`, appears in no log, and fails no test. `toAgentFactory` compiled the `compiled.hitl` map
|
|
412
|
+
* that `.approvals({…})` produces and threw it away, with the discard admitted in writing in the
|
|
413
|
+
* JSDoc, while the sibling bridge REFUSED for the same definition.
|
|
414
|
+
*
|
|
415
|
+
* The permissive posture remains entirely expressible — as a NAMED VALUE, with a written reason.
|
|
416
|
+
* What stops existing is the omission.
|
|
417
|
+
*
|
|
418
|
+
* ## Os peers
|
|
419
|
+
*
|
|
420
|
+
* `codex` models the posture as a four-variant `enum AskForApproval` in the protocol crate, and
|
|
421
|
+
* makes forgetting it a compile error through the `ToolRuntime: Approvable + Sandboxable` supertrait;
|
|
422
|
+
* a mandatory field is the closest this type system gets to that. `codex` also resolves the
|
|
423
|
+
* ambiguity of omission in the safe direction (`GranularApprovalConfig`: an absent field is
|
|
424
|
+
* auto-REJECTED, never auto-approved), and names the human's stand-in rather than inferring it from
|
|
425
|
+
* the absence of one (`ApprovalReviewer::{Guardian, User}`). `opencode` does the same inside out:
|
|
426
|
+
* an absent rule resolves to `ask`.
|
|
427
|
+
*/
|
|
428
|
+
|
|
789
429
|
/**
|
|
790
430
|
* What this surface does when a gated tool asks for approval. Four variants, none of them
|
|
791
431
|
* "omission" — each with a concrete consumer and a written reason.
|
|
@@ -803,8 +443,26 @@ type ApprovalPosture = {
|
|
|
803
443
|
/** Resolves the human decision; execution stays paused until this settles. */
|
|
804
444
|
awaitApproval: (approvalId: string, opts: HumanInTheLoopOptions, toolName: string) => Promise<boolean | HitlDecision>;
|
|
805
445
|
} | {
|
|
806
|
-
/** Nobody asks and the tool runs. Legitimate when something else confines the execution. */
|
|
446
|
+
/** Nobody asks and the tool runs. Legitimate only when something else confines the execution. */
|
|
807
447
|
kind: 'auto-approve';
|
|
448
|
+
/**
|
|
449
|
+
* M77 — the EVIDENCE that something else confines the execution. Not optional, and not a
|
|
450
|
+
* string.
|
|
451
|
+
*
|
|
452
|
+
* This is the most consequential decision a coding agent makes — "run commands without
|
|
453
|
+
* asking" — and until M77 its type asked only for a `reason: string`. A string is
|
|
454
|
+
* unverifiable at the seam: nothing could tell "confined by bwrap, kernel-enforced" from
|
|
455
|
+
* "I'm sure it's fine". So the consumer implemented the refusal itself, TWICE
|
|
456
|
+
* (`shouldAutoApprove` in the TUI, `resolveHeadlessApproval` in the headless path), with the
|
|
457
|
+
* same rule in both — an absent posture counts as unconfined. A security rule duplicated
|
|
458
|
+
* across two call sites is a rule that will eventually disagree with itself (G12).
|
|
459
|
+
*
|
|
460
|
+
* `SandboxPosture` is the SDK's own honest answer to "am I kernel-enforced right now?", and
|
|
461
|
+
* it carries `detail` so a refusal can say WHY rather than just "unconfined". Requiring it
|
|
462
|
+
* makes the unconfined case unrepresentable at the type level; {@link applyPosture} refuses
|
|
463
|
+
* it at runtime for the caller who casts past the type.
|
|
464
|
+
*/
|
|
465
|
+
confinedBy: SandboxPosture;
|
|
808
466
|
reason: string;
|
|
809
467
|
} | {
|
|
810
468
|
/** Nobody asks and the tool does NOT run — the safe reading of omission (codex `GranularApprovalConfig`). */
|
|
@@ -821,185 +479,6 @@ type ApprovalPosture = {
|
|
|
821
479
|
reason: string;
|
|
822
480
|
};
|
|
823
481
|
|
|
824
|
-
/**
|
|
825
|
-
* M82 — the typed shape of `AgentBuilder.create().hooks({...})`.
|
|
826
|
-
*
|
|
827
|
-
* ## Why this type lives here
|
|
828
|
-
*
|
|
829
|
-
* Until M82 the signature was `Readonly<Record<string, unknown>>`: any key was accepted and every
|
|
830
|
-
* handler received `ctx: unknown`. A consumer that wanted types had to declare its own — and that is
|
|
831
|
-
* exactly what agent-builder did, with a local alias of five handlers, four of them carrying
|
|
832
|
-
* `ctx: unknown` because there was nowhere to import the contexts from.
|
|
833
|
-
*
|
|
834
|
-
* It is the same class M81 closed with `discoverSubagents`: framework knowledge reimplemented in the
|
|
835
|
-
* app because the framework did not publish it. The type is born where the knowledge lives.
|
|
836
|
-
*
|
|
837
|
-
* ## About `transform_tool_result`
|
|
838
|
-
*
|
|
839
|
-
* This is the ONLY tool-stage channel whose return value the SDK applies — `#runTransform` folds the
|
|
840
|
-
* returned value in; `#runFireAndForget`, used by `post_tool_call`, discards it. Since M82 its
|
|
841
|
-
* context carries `toolCalls`, so a scoped policy (by tool name) can ACT on the result rather than
|
|
842
|
-
* merely observe it.
|
|
843
|
-
*/
|
|
844
|
-
|
|
845
|
-
/**
|
|
846
|
-
* Lifecycle handlers keyed by `HookName`.
|
|
847
|
-
*
|
|
848
|
-
* Every field is optional: an agent registers only the events it cares about. `.hooks()` accepts the
|
|
849
|
-
* UNION of this type with the earlier loose shape (M82's ADR-4), so no implicit index signature is
|
|
850
|
-
* needed for the value to pass at the call site — the narrowing is gradual, not a break.
|
|
851
|
-
*/
|
|
852
|
-
interface HookHandlers {
|
|
853
|
-
/**
|
|
854
|
-
* Runs BEFORE the tool. Returning `{ block: true, message }` VETOES the call — the only hook with
|
|
855
|
-
* veto power.
|
|
856
|
-
*/
|
|
857
|
-
pre_tool_call?: (ctx: PreToolCallContext) => Promise<PreToolCallDecision | undefined> | PreToolCallDecision | undefined;
|
|
858
|
-
/**
|
|
859
|
-
* Runs AFTER the tool, with `{name, args, result}`. Fire-and-forget: the return value is
|
|
860
|
-
* **discarded** by the SDK. To ACT on the result use {@link transform_tool_result}.
|
|
861
|
-
*/
|
|
862
|
-
post_tool_call?: (ctx: PostToolCallContext) => Promise<void> | void;
|
|
863
|
-
/**
|
|
864
|
-
* Folds the turn's tool results before they go up to the model. Since M82 the context brings
|
|
865
|
-
* `toolCalls` — plural, because the seam receives the turn's BATCH; correlate by
|
|
866
|
-
* `toolUseId === id`.
|
|
867
|
-
*/
|
|
868
|
-
transform_tool_result?: <T>(results: T, ctx: ToolResultTransformContext) => Promise<T> | T;
|
|
869
|
-
/** Folds the model's text before it is consumed. No tool call involved. */
|
|
870
|
-
transform_llm_output?: (output: string, ctx: TransformContext) => Promise<string> | string;
|
|
871
|
-
on_session_start?: (ctx: SessionLifecycleContext) => Promise<void> | void;
|
|
872
|
-
on_session_end?: (ctx: SessionLifecycleContext) => Promise<void> | void;
|
|
873
|
-
pre_user_send?: (ctx: PreUserSendContext) => Promise<PreUserSendResult | undefined> | PreUserSendResult | undefined;
|
|
874
|
-
post_assistant_reply?: (ctx: PostAssistantReplyContext) => Promise<void> | void;
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
/**
|
|
878
|
-
* M2 (theokit-ai-first) — `defineAgent`, the zero-config imperative agent surface.
|
|
879
|
-
*
|
|
880
|
-
* ADR-B1: `defineAgent({...})` (default-exported from a top-level `agents/<name>.ts`) is
|
|
881
|
-
* the canonical zero-config surface; the `@Agent` class decorator stays the advanced/DI
|
|
882
|
-
* surface. Both compile to {@link CompiledAgentOptions} and run through the same SDK
|
|
883
|
-
* runtime (`createSdkAgentStream`) — one runtime, two syntaxes.
|
|
884
|
-
*
|
|
885
|
-
* This module is PURE metadata (sdk-runtime.md / G2): `defineAgent` describes an agent, it
|
|
886
|
-
* NEVER calls an LLM. It imports only `zod` (types) + the compiler shape — no `theokit`
|
|
887
|
-
* core, preserving the agents → (nothing) dependency direction (G1).
|
|
888
|
-
*/
|
|
889
|
-
|
|
890
|
-
/**
|
|
891
|
-
* Brand tag for a `defineAgent` value. `Symbol.for` (global registry, not `Symbol()`) so
|
|
892
|
-
* the brand survives duplicate module instances (dual-package / bundling) — the scanner's
|
|
893
|
-
* brand-check then works regardless of which copy created the definition.
|
|
894
|
-
*/
|
|
895
|
-
declare const AGENT_BRAND: unique symbol;
|
|
896
|
-
/** Config accepted by {@link defineAgent}. */
|
|
897
|
-
interface DefineAgentConfig<TInput extends z.ZodType = z.ZodType> {
|
|
898
|
-
/** Zod schema for the request body — lifted into the typed client (M2, {@link InferAgentInput}). */
|
|
899
|
-
input?: TInput;
|
|
900
|
-
/** Model id (e.g. `claude-sonnet-4-6`). Falls back to the SDK default when omitted. */
|
|
901
|
-
model?: string;
|
|
902
|
-
/** Static system prompt. */
|
|
903
|
-
system?: string;
|
|
904
|
-
/** Extended-thinking effort. */
|
|
905
|
-
reasoningEffort?: ReasoningEffort;
|
|
906
|
-
/**
|
|
907
|
-
* Pre-built tools. Accepts the `@theokit/sdk` `CustomTool` that `defineAgentTool`
|
|
908
|
-
* (theokit/server) and every `@theokit/sdk-tools` factory return (issue #81) — they are
|
|
909
|
-
* normalized to the internal {@link CompiledTool} shape at compile time.
|
|
910
|
-
*/
|
|
911
|
-
tools?: readonly CustomTool[];
|
|
912
|
-
/**
|
|
913
|
-
* M7 — run-context: an opaque, per-agent object forwarded to every tool handler's
|
|
914
|
-
* `ctx.context` at run time (injected by the theokit adapter's tool wrapper). Set shared config
|
|
915
|
-
* (e.g. `{ projectRoot }`) ONCE at the agent level instead of baking it into each tool
|
|
916
|
-
* factory. Mirrors ai-sdk `experimental_context`, mastra `RuntimeContext`, and
|
|
917
|
-
* openai-agents-js `RunContext`. Distinct from `@Agent`'s context-window `context`.
|
|
918
|
-
*/
|
|
919
|
-
context?: Record<string, unknown>;
|
|
920
|
-
/**
|
|
921
|
-
* M9 — guardrails: input/output guards applied at the framework boundary (ADR-0040 § D2).
|
|
922
|
-
* Input guards run on the user message before the SDK runtime; a `block` fails the run fast.
|
|
923
|
-
* Built-ins live in `@theokit/agents` (`promptInjectionDetector`, `piiDetector`, `costGuard`,
|
|
924
|
-
* `unicodeNormalizer`, `outputModeration`).
|
|
925
|
-
*/
|
|
926
|
-
guardrails?: readonly Guardrail[];
|
|
927
|
-
/**
|
|
928
|
-
* M14 — HITL approvals keyed by tool name. Each gated tool pauses the run and emits an
|
|
929
|
-
* `approval_required` event until approved (reuses the same `compiled.hitl` wiring the `@Agent`
|
|
930
|
-
* + `@HumanInTheLoop` path produces). A key that does not match a declared tool fails fast at
|
|
931
|
-
* compile time.
|
|
932
|
-
*/
|
|
933
|
-
approvals?: Record<string, HumanInTheLoopOptions>;
|
|
934
|
-
/**
|
|
935
|
-
* M13 — skills selection: a static list (compiled straight to the SDK `skills.enabled`) OR a
|
|
936
|
-
* per-request resolver `(ctx) => string[]` (carried on `compiled.skillsResolver`, resolved by the
|
|
937
|
-
* request path against the run-context). Absent ⇒ the SDK enables every discovered skill.
|
|
938
|
-
*/
|
|
939
|
-
skills?: SkillsSelection;
|
|
940
|
-
/**
|
|
941
|
-
* theokit-file-based-config — opt into `.theokit/` file-based config (skills, subagents, hooks,
|
|
942
|
-
* MCP, context, cron). The SDK discovers config from these roots under the app's `cwd`:
|
|
943
|
-
* `"project"` = `<cwd>/.theokit/`, `"user"` = `~/.theokit/`. Absent ⇒ inline (code) config only.
|
|
944
|
-
* SECURITY: enabling `"project"` enables shell-executing hooks from `.theokit/hooks.json` — this
|
|
945
|
-
* is opt-in because `.theokit/` is the app's own repo (informed consent). The SDK owns discovery
|
|
946
|
-
* + execution (G2 / ADR-0040); theokit only wires this into `Agent.create({ local.settingSources })`.
|
|
947
|
-
*/
|
|
948
|
-
settingSources?: readonly SettingSource[];
|
|
949
|
-
/**
|
|
950
|
-
* M49 — durable memory (the SDK's `.theokit/memory/` subsystem: `Remember:` capture, MEMORY.md
|
|
951
|
-
* store, auto-injected `<memory>` block, `memory_search`/`memory_get` tools). The shape is the
|
|
952
|
-
* SDK's own `MemorySettings` — the canonical runtime contract. Projected into
|
|
953
|
-
* `Agent.create({ memory })` by `assembleM8CreateOptions`.
|
|
954
|
-
*/
|
|
955
|
-
memory?: MemorySettings;
|
|
956
|
-
/**
|
|
957
|
-
* Code `Plugin` objects forwarded to `Agent.create({ plugins })` — EXTENSION units (tools,
|
|
958
|
-
* commands, model providers, memory adapters). For lifecycle interception use {@link hooks}.
|
|
959
|
-
*/
|
|
960
|
-
plugins?: readonly unknown[];
|
|
961
|
-
/**
|
|
962
|
-
* Lifecycle hooks keyed by `HookName` (`pre_tool_call` may veto via `{ block, message }`). Set by
|
|
963
|
-
* the builder's `hooks()`; converted into a code plugin at `build()` and never reaching the SDK
|
|
964
|
-
* under this name — the plugin is the TRANSPORT, this is the contract callers write against.
|
|
965
|
-
*/
|
|
966
|
-
hooks?: HookHandlers | Readonly<Record<string, unknown>>;
|
|
967
|
-
/**
|
|
968
|
-
* MCP servers available to the agent — the builder-chain equivalent of the `@MCP` class
|
|
969
|
-
* decorator. Each key is a server name; the value is the server configuration. Forwarded
|
|
970
|
-
* unchanged to `Agent.create({ mcpServers })` (the SDK owns MCP execution). Absent ⇒ no MCP.
|
|
971
|
-
*/
|
|
972
|
-
mcpServers?: McpServersMap;
|
|
973
|
-
}
|
|
974
|
-
/**
|
|
975
|
-
* A branded agent definition — the value {@link defineAgent} returns.
|
|
976
|
-
*
|
|
977
|
-
* `TTools` (M8) is a phantom type parameter carrying the tool-name union: the `AgentBuilder.create()` builder
|
|
978
|
-
* threads its accumulated literal tool names here (`.build()` returns `AgentDefinition<TInput,
|
|
979
|
-
* 'a' | 'b'>`), so the generated client (`.theokit/agents.d.ts`) can expose them via
|
|
980
|
-
* {@link InferAgentToolNames}. `defineAgent` leaves it `string` (its tools array carries no literal
|
|
981
|
-
* names). Never present at runtime.
|
|
982
|
-
*/
|
|
983
|
-
type AgentDefinition<TInput extends z.ZodType = z.ZodType, TTools extends string = string> = DefineAgentConfig<TInput> & {
|
|
984
|
-
readonly [AGENT_BRAND]: true;
|
|
985
|
-
readonly __toolNames?: TTools;
|
|
986
|
-
};
|
|
987
|
-
/** Infer the request type of an agent definition from its `input` Zod schema. */
|
|
988
|
-
type InferAgentInput<T> = T extends AgentDefinition<infer S> ? (S extends z.ZodType ? z.infer<S> : never) : never;
|
|
989
|
-
/**
|
|
990
|
-
* Infer the tool-name union of an agent definition (M8). Yields the literal union for agents built
|
|
991
|
-
* with the `AgentBuilder.create()` builder (`'read_file' | 'count_lines'`), or `string` for `defineAgent` agents
|
|
992
|
-
* whose tools array carries no literal names.
|
|
993
|
-
*/
|
|
994
|
-
type InferAgentToolNames<T> = T extends AgentDefinition<z.ZodType, infer N> ? N : never;
|
|
995
|
-
/** Brand-check: is `value` a {@link defineAgent} result? */
|
|
996
|
-
declare function isAgentDefinition(value: unknown): value is AgentDefinition;
|
|
997
|
-
/**
|
|
998
|
-
* Lower a definition to the SDK-ready {@link CompiledAgentOptions} — the same shape
|
|
999
|
-
* `compileAgent` (decorator path) produces, so both surfaces converge on one runtime.
|
|
1000
|
-
*/
|
|
1001
|
-
declare function compileAgentDefinition(def: AgentDefinition): CompiledAgentOptions;
|
|
1002
|
-
|
|
1003
482
|
/**
|
|
1004
483
|
* A definition, or a THUNK that produces one per session.
|
|
1005
484
|
*
|
|
@@ -1324,6 +803,26 @@ interface ToolContextError<TRequired> {
|
|
|
1324
803
|
}
|
|
1325
804
|
/** The agent context before `.context()` is called — satisfies only tools with no requirement. */
|
|
1326
805
|
type EmptyContext = Record<never, never>;
|
|
806
|
+
/**
|
|
807
|
+
* The union of literal tool names in a tuple of {@link ContextualTool}s.
|
|
808
|
+
*
|
|
809
|
+
* Written as a distributed conditional rather than `TList[number]['name']` so an EMPTY list yields
|
|
810
|
+
* `never` (which unions away, leaving `TTools` untouched) instead of `string` (which would widen the
|
|
811
|
+
* accumulated union and silently destroy the type-state for the rest of the chain).
|
|
812
|
+
*/
|
|
813
|
+
type ToolNamesOf<TList> = TList extends readonly (infer TElement)[] ? TElement extends ContextualTool<infer TName> ? TName : never : never;
|
|
814
|
+
/**
|
|
815
|
+
* The combined run-context every tool in the tuple requires.
|
|
816
|
+
*
|
|
817
|
+
* The singular `.tool()` guards one `TRequired` against the agent's `TContext`; a list has to guard
|
|
818
|
+
* ALL of them, so this intersects them. Without it, `.tools([...])` would be a hole in the exact
|
|
819
|
+
* check `.tool()` performs — a batch API that quietly accepts what the single-item API rejects is
|
|
820
|
+
* worse than no batch API.
|
|
821
|
+
*
|
|
822
|
+
* Intersection, not union: satisfying every element means the agent's context must have what each
|
|
823
|
+
* one needs. `unknown` (a plain tool) intersects away, so a list of plain tools stays unconstrained.
|
|
824
|
+
*/
|
|
825
|
+
type ToolContextOf<TList> = (TList extends readonly (infer TElement)[] ? TElement extends ContextualTool<string, infer TRequired> ? (required: TRequired) => void : never : never) extends (required: infer TIntersection) => void ? TIntersection : never;
|
|
1327
826
|
/**
|
|
1328
827
|
* A tool that MAY declare, at the type level, the run-context shape it needs. A plain
|
|
1329
828
|
* {@link CustomTool} (`TRequired = unknown`) is satisfied by any agent context. Build one that
|
|
@@ -1380,6 +879,38 @@ interface AgentBuilder<TInput extends z.ZodType | UnsetMarker = UnsetMarker, TMo
|
|
|
1380
879
|
* satisfy — set it first with `.context()`.
|
|
1381
880
|
*/
|
|
1382
881
|
tool<TName extends string, TRequired>(tool: ContextualTool<TName, TRequired>, ...guard: TContext extends TRequired ? [] : [error: ToolContextError<TRequired>]): AgentBuilder<TInput, TModel, TContext, TTools | TName>;
|
|
882
|
+
/**
|
|
883
|
+
* M69 — add MANY tools at once, accumulating the union of their names.
|
|
884
|
+
*
|
|
885
|
+
* The chain only had the singular `.tool()`, so a tool set computed at runtime — the normal case,
|
|
886
|
+
* since which tools an agent gets depends on sandbox mode, surface profile and trust — could not
|
|
887
|
+
* be expressed in the chain. The measured workaround was a fold outside it:
|
|
888
|
+
*
|
|
889
|
+
* allTools.reduce((acc, tool) => acc.tool(tool), chain)
|
|
890
|
+
*
|
|
891
|
+
* That works and loses the type-state: the accumulated name union collapses, so
|
|
892
|
+
* `InferAgentToolNames` stops seeing the literal names the generated client is built from. The
|
|
893
|
+
* escape hatch cost exactly the guarantee the builder exists for.
|
|
894
|
+
*
|
|
895
|
+
* An empty list is a typed no-op — `never` unions away, so `TTools` is untouched rather than
|
|
896
|
+
* widened.
|
|
897
|
+
*/
|
|
898
|
+
tools<const TList extends readonly ContextualTool[]>(list: TList, ...guard: TContext extends ToolContextOf<TList> ? [] : [error: ToolContextError<ToolContextOf<TList>>]): AgentBuilder<TInput, TModel, TContext, TTools | ToolNamesOf<TList>>;
|
|
899
|
+
/**
|
|
900
|
+
* M69 — apply a sub-chain only when `condition` holds, preserving the type-state either way.
|
|
901
|
+
*
|
|
902
|
+
* `.use(preset)` composes a whole sub-chain but cannot skip a link in the MIDDLE of one, which is
|
|
903
|
+
* what a conditional element needs.
|
|
904
|
+
*
|
|
905
|
+
* The condition is a plain `boolean`, already computed — never a predicate with access to
|
|
906
|
+
* context. A predicate would make this a door for business logic inside the authoring chain (the
|
|
907
|
+
* milestone's named risk); a boolean keeps the decision where the caller made it.
|
|
908
|
+
*
|
|
909
|
+
* The returned type is the same on both branches, because the condition is a runtime value and a
|
|
910
|
+
* type cannot depend on it: the union is what the branch COULD add. That is what lets `.when` sit
|
|
911
|
+
* mid-chain without collapsing what came before.
|
|
912
|
+
*/
|
|
913
|
+
when<TResult extends AgentBuilder<TInput, TModel, TContext, string>>(condition: boolean, apply: (builder: AgentBuilder<TInput, TModel, TContext, TTools>) => TResult): TResult;
|
|
1383
914
|
/** M9 — add one input/output guardrail (appends). Runs at the framework boundary before the SDK. */
|
|
1384
915
|
guardrail(g: Guardrail): AgentBuilder<TInput, TModel, TContext, TTools>;
|
|
1385
916
|
/** M9 — set the full guardrail list (replaces any previously added). */
|
|
@@ -1401,11 +932,16 @@ interface AgentBuilder<TInput extends z.ZodType | UnsetMarker = UnsetMarker, TMo
|
|
|
1401
932
|
skills(selection: SkillsSelection): AgentBuilder<TInput, TModel, TContext, TTools>;
|
|
1402
933
|
/**
|
|
1403
934
|
* theokit-file-based-config — opt into `.theokit/` file-based config (skills, subagents, hooks,
|
|
1404
|
-
* MCP, context, cron), discovered by the SDK from the app root (`
|
|
1405
|
-
* `
|
|
1406
|
-
*
|
|
935
|
+
* MCP, context, cron), discovered by the SDK from the app root (`project` = `<cwd>/.theokit/`,
|
|
936
|
+
* `user` = `~/.theokit/`). Unset ⇒ inline (code) config only.
|
|
937
|
+
*
|
|
938
|
+
* SECURITY (M68): takes a {@link SettingSourcesSelection}, not a string array. `project` reads
|
|
939
|
+
* `.theokit/hooks.json`, which **executes shell**, so it requires a `TrustPosture` as evidence;
|
|
940
|
+
* `user` is a plain boolean because `~/.theokit/` is the operator's own machine. The previous
|
|
941
|
+
* signature called `project` "opt-in because `.theokit/` is your own repo" — true for a web app
|
|
942
|
+
* whose `cwd` is its own deploy, false for an agent pointed at a repository someone else wrote.
|
|
1407
943
|
*/
|
|
1408
|
-
settingSources(
|
|
944
|
+
settingSources(selection: SettingSourcesSelection): AgentBuilder<TInput, TModel, TContext, TTools>;
|
|
1409
945
|
/**
|
|
1410
946
|
* M49 — enable the SDK's durable memory for this agent (`.theokit/memory/` in the run cwd:
|
|
1411
947
|
* `Remember:` capture with secret redaction, auto-injected recall, memory tools). Takes the SDK's
|
|
@@ -1474,23 +1010,17 @@ declare const AgentBuilder: {
|
|
|
1474
1010
|
create(): AgentBuilder;
|
|
1475
1011
|
};
|
|
1476
1012
|
|
|
1013
|
+
/** Thrown when an `agents/` file default-exports neither a `defineAgent` value nor an `@Agent` class. */
|
|
1477
1014
|
/**
|
|
1478
|
-
*
|
|
1479
|
-
*
|
|
1480
|
-
* Turns a loaded `agents/<name>.ts` module into the M0/M1 canonical `UIMessageStream`:
|
|
1015
|
+
* M80 — extends {@link TheokitAgentError}, not plain `Error`.
|
|
1481
1016
|
*
|
|
1482
|
-
*
|
|
1483
|
-
*
|
|
1484
|
-
*
|
|
1485
|
-
*
|
|
1486
|
-
* `compileAgentDefinition`, an `@Agent`-decorated class lowers via `compileAgent`
|
|
1487
|
-
* (which requires the full `@MainLoop` decoration — its existing errors surface for
|
|
1488
|
-
* DI-heavy classes). Neither runs an LLM directly — `@theokit/sdk` stays the sole
|
|
1489
|
-
* runtime (G2 / sdk-runtime.md); this module only wires its output onto the wire.
|
|
1017
|
+
* `isTransientError` is defined over `TheokitAgentError`, so a class outside that hierarchy is
|
|
1018
|
+
* INVISIBLE to it and the only recourse left to a consumer is matching on message text. `code` is
|
|
1019
|
+
* stable across a rename; `isRetryable` is DECLARED, because a default would be a retry policy
|
|
1020
|
+
* nobody chose.
|
|
1490
1021
|
*/
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
declare class AgentDefinitionError extends Error {
|
|
1022
|
+
declare class AgentDefinitionError extends TheokitAgentError {
|
|
1023
|
+
readonly name = "AgentDefinitionError";
|
|
1494
1024
|
constructor(source: string);
|
|
1495
1025
|
}
|
|
1496
1026
|
declare function compileAgentModule(mod: unknown, source?: string): CompiledAgentOptions;
|
|
@@ -1623,18 +1153,6 @@ type LoopStrategyConfig = z.infer<typeof loopStrategyConfigSchema>;
|
|
|
1623
1153
|
*/
|
|
1624
1154
|
declare function resolveLoopStrategy(strategy: string, maxIterations?: number): LoopStrategy;
|
|
1625
1155
|
|
|
1626
|
-
/**
|
|
1627
|
-
* Shared delegation value types + typed errors.
|
|
1628
|
-
*
|
|
1629
|
-
* Extracted from `agent-orchestrator.ts` so BOTH the orchestrator (`delegate`)
|
|
1630
|
-
* and the loop driver (`loop/run-reflective-loop.ts`) can import them WITHOUT a
|
|
1631
|
-
* cycle (orchestrator → loop → delegation-types; orchestrator → delegation-types;
|
|
1632
|
-
* delegation-types has only a TYPE-ONLY import of `LoopFinishReason` (erased at
|
|
1633
|
-
* runtime → no runtime edge; `loop-strategy.ts` is a leaf importing only zod, so
|
|
1634
|
-
* no cycle — Acyclic Dependencies Principle, G1).
|
|
1635
|
-
* `agent-orchestrator.ts` re-exports these for backward compatibility.
|
|
1636
|
-
*/
|
|
1637
|
-
|
|
1638
1156
|
interface DelegationResult {
|
|
1639
1157
|
response: string;
|
|
1640
1158
|
toolCalls: {
|
|
@@ -1677,10 +1195,19 @@ interface DelegationResult {
|
|
|
1677
1195
|
* `subpath-coverage.test.ts` recorded the collision as a `gap` on `./errors`, with the reason written
|
|
1678
1196
|
* down and the acknowledgement that renaming was breaking and out of M78's scope. M91 paid the bill.
|
|
1679
1197
|
*/
|
|
1680
|
-
|
|
1198
|
+
/**
|
|
1199
|
+
* M80 — extends {@link TheokitAgentError}, not plain `Error`.
|
|
1200
|
+
*
|
|
1201
|
+
* `isTransientError` is defined over `TheokitAgentError`, so a class outside that hierarchy is
|
|
1202
|
+
* INVISIBLE to it and the only recourse left to a consumer is matching on message text. `code` is
|
|
1203
|
+
* stable across a rename; `isRetryable` is DECLARED, because a default would be a retry policy
|
|
1204
|
+
* nobody chose.
|
|
1205
|
+
*/
|
|
1206
|
+
declare class DelegationBudgetExceededError extends TheokitAgentError {
|
|
1681
1207
|
readonly agentName: string;
|
|
1682
1208
|
readonly actualCost: number;
|
|
1683
1209
|
readonly budgetLimit: number;
|
|
1210
|
+
readonly name = "DelegationBudgetExceededError";
|
|
1684
1211
|
constructor(agentName: string, actualCost: number, budgetLimit: number);
|
|
1685
1212
|
}
|
|
1686
1213
|
/**
|
|
@@ -1691,9 +1218,18 @@ declare class DelegationBudgetExceededError extends Error {
|
|
|
1691
1218
|
declare const BudgetExceededError: typeof DelegationBudgetExceededError;
|
|
1692
1219
|
/** @deprecated Use {@link DelegationBudgetExceededError}. */
|
|
1693
1220
|
type BudgetExceededError = DelegationBudgetExceededError;
|
|
1694
|
-
|
|
1221
|
+
/**
|
|
1222
|
+
* M80 — extends {@link TheokitAgentError}, not plain `Error`.
|
|
1223
|
+
*
|
|
1224
|
+
* `isTransientError` is defined over `TheokitAgentError`, so a class outside that hierarchy is
|
|
1225
|
+
* INVISIBLE to it and the only recourse left to a consumer is matching on message text. `code` is
|
|
1226
|
+
* stable across a rename; `isRetryable` is DECLARED, because a default would be a retry policy
|
|
1227
|
+
* nobody chose.
|
|
1228
|
+
*/
|
|
1229
|
+
declare class DelegationError extends TheokitAgentError {
|
|
1695
1230
|
readonly agentName: string;
|
|
1696
1231
|
readonly cause: unknown;
|
|
1232
|
+
readonly name = "DelegationError";
|
|
1697
1233
|
constructor(agentName: string, cause: unknown);
|
|
1698
1234
|
}
|
|
1699
1235
|
|
|
@@ -1804,6 +1340,15 @@ type RoundStreamFactory = (message: string, sessionId: string, opts?: {
|
|
|
1804
1340
|
*/
|
|
1805
1341
|
|
|
1806
1342
|
interface DelegateOptions {
|
|
1343
|
+
/**
|
|
1344
|
+
* M81 — wall-clock cap for the delegation, in milliseconds. Absent ⇒ no clock cap.
|
|
1345
|
+
*
|
|
1346
|
+
* A DIFFERENT guard from `budget`: money is spent by work that progresses, and a delegation that
|
|
1347
|
+
* HANGS burns clock without spending a cent. A consumer wrote its own timeout race with its own
|
|
1348
|
+
* typed error because this was missing. Exceeding it raises `DelegationTimeoutError`, which —
|
|
1349
|
+
* unlike the budget errors — is marked retryable, because a hang is often transient.
|
|
1350
|
+
*/
|
|
1351
|
+
readonly timeoutMs?: number;
|
|
1807
1352
|
/** Max USD for this sub-agent call. */
|
|
1808
1353
|
budget?: number;
|
|
1809
1354
|
/** Parent's remaining budget (for clamping). */
|
|
@@ -2043,6 +1588,22 @@ declare function createApiErrorHandler<R = unknown>(policy: ApiErrorPolicy<R>):
|
|
|
2043
1588
|
* SubAgent class or an LLM — and so it NEVER re-implements the delegation runtime.
|
|
2044
1589
|
*/
|
|
2045
1590
|
|
|
1591
|
+
/**
|
|
1592
|
+
* M81 — anything that can run a delegation.
|
|
1593
|
+
*
|
|
1594
|
+
* The reach gap this closes: both wrappers took a `SubAgentSpec` produced by the capability
|
|
1595
|
+
* compiler, so a consumer holding an SDK `SubAgent` or `Squad` could not feed them. That is why the
|
|
1596
|
+
* scoring loop — the layer's highest-value piece — had ZERO adoption in a product that runs an
|
|
1597
|
+
* explicit review pass: it was unreachable from the primitives that product actually holds.
|
|
1598
|
+
*
|
|
1599
|
+
* An SDK `SubAgent` or `Squad` satisfies this by having `run`. So does a test double, which is why
|
|
1600
|
+
* the loop is now testable without a compiler, a class or an LLM.
|
|
1601
|
+
*/
|
|
1602
|
+
interface DelegationPort {
|
|
1603
|
+
run(message: string): Promise<DelegationResult>;
|
|
1604
|
+
}
|
|
1605
|
+
/** What both wrappers accept: the compiled spec (unchanged) or the port (M81, additive). */
|
|
1606
|
+
type DelegationTarget = SubAgentSpec | DelegationPort;
|
|
2046
1607
|
/** The delegation primitive both wrappers drive. Defaults to the M12 {@link delegate}. */
|
|
2047
1608
|
type DelegateFn = (subAgent: SubAgentSpec, message: string, opts?: DelegateOptions) => Promise<DelegationResult>;
|
|
2048
1609
|
/** A running background delegation the supervisor can await/poll later. */
|
|
@@ -2057,7 +1618,7 @@ interface BackgroundDelegation {
|
|
|
2057
1618
|
* supervisor keeps working and calls `wait()` when it needs the result. A thin async wrapper over
|
|
2058
1619
|
* `delegate` — not a scheduler (Top-risk 1). Rejections are still observable via `wait()`.
|
|
2059
1620
|
*/
|
|
2060
|
-
declare function delegateBackground(subAgent:
|
|
1621
|
+
declare function delegateBackground(subAgent: DelegationTarget, message: string, opts?: DelegateOptions & {
|
|
2061
1622
|
delegateFn?: DelegateFn;
|
|
2062
1623
|
}): BackgroundDelegation;
|
|
2063
1624
|
/** A scorer's verdict on a sub-agent result. `feedback` is fed back into the next round on failure. */
|
|
@@ -2085,13 +1646,69 @@ interface ScoredDelegation {
|
|
|
2085
1646
|
* `maxRounds` is reached. Each round is ONE `delegate` call — no second loop, no new store. Returns
|
|
2086
1647
|
* the final result (passing, or the last attempt) with the per-round verdict trail.
|
|
2087
1648
|
*/
|
|
2088
|
-
declare function delegateWithScoring(subAgent:
|
|
1649
|
+
declare function delegateWithScoring(subAgent: DelegationTarget, message: string, opts: DelegateOptions & {
|
|
2089
1650
|
scorer: Scorer;
|
|
2090
1651
|
maxRounds?: number;
|
|
2091
1652
|
delegateFn?: DelegateFn;
|
|
2092
1653
|
feedbackTemplate?: (message: string, feedback: string) => string;
|
|
2093
1654
|
}): Promise<ScoredDelegation>;
|
|
2094
1655
|
|
|
1656
|
+
/**
|
|
1657
|
+
* M81 — the two gaps around a delegation's LIFE, as opposed to its execution.
|
|
1658
|
+
*
|
|
1659
|
+
* The execution engine was supplied and works. What was missing sits either side of it:
|
|
1660
|
+
*
|
|
1661
|
+
* - **a clock cap.** `budget` is money only, and a delegation that HANGS burns clock, not dollars.
|
|
1662
|
+
* So a consumer wrote its own timeout race with its own typed error — mechanism, re-derived.
|
|
1663
|
+
* - **disposal with an owner.** `delegate()` never creates disposable agents, so every site that
|
|
1664
|
+
* does — a squad, an ephemeral reviewer — hand-wrote acquire/dispose. Both of those files carried
|
|
1665
|
+
* a bug-fix comment about `finally` semantics, which is what "we got this wrong once" looks like
|
|
1666
|
+
* when the correct version lives nowhere in particular.
|
|
1667
|
+
*/
|
|
1668
|
+
/**
|
|
1669
|
+
* Raised when a delegation exceeds its wall-clock cap.
|
|
1670
|
+
*
|
|
1671
|
+
* A distinct class from the budget error on purpose: "you spent your dollars" and "you ran out of
|
|
1672
|
+
* time" call for different responses, and a caller that cannot tell them apart retries the one that
|
|
1673
|
+
* will hang again.
|
|
1674
|
+
*/
|
|
1675
|
+
declare class DelegationTimeoutError extends TheokitAgentError {
|
|
1676
|
+
readonly name = "DelegationTimeoutError";
|
|
1677
|
+
constructor(subAgent: string, timeoutMs: number);
|
|
1678
|
+
}
|
|
1679
|
+
/**
|
|
1680
|
+
* Race a delegation against a wall clock.
|
|
1681
|
+
*
|
|
1682
|
+
* The timer is cleared on both paths: a pending `setTimeout` keeps the event loop alive, and a CLI
|
|
1683
|
+
* that finishes its work and then sits for thirty seconds looks broken in a way nobody connects back
|
|
1684
|
+
* to a delegation cap.
|
|
1685
|
+
*/
|
|
1686
|
+
declare function withClockCap<T>(promise: Promise<T>, timeoutMs: number, subAgent: string): Promise<T>;
|
|
1687
|
+
/** An agent that must be released, and the release. */
|
|
1688
|
+
interface EphemeralAgent<TAgent> {
|
|
1689
|
+
readonly agent: TAgent;
|
|
1690
|
+
readonly dispose: () => void | Promise<void>;
|
|
1691
|
+
}
|
|
1692
|
+
/**
|
|
1693
|
+
* Run `body` against a freshly created agent and dispose it afterwards, whatever happens.
|
|
1694
|
+
*
|
|
1695
|
+
* ## Why the disposal cannot mask the result
|
|
1696
|
+
*
|
|
1697
|
+
* `Promise.allSettled` semantics, named by the milestone: the body's outcome — value OR error — is
|
|
1698
|
+
* what the caller receives, and a failing `dispose` never replaces it.
|
|
1699
|
+
*
|
|
1700
|
+
* A cleanup that threw over a successful run would report a teardown error for work that actually
|
|
1701
|
+
* succeeded. Worse, a cleanup that threw over a FAILED run would replace the real failure with the
|
|
1702
|
+
* teardown one, and the diagnosis the caller needed is gone. That asymmetry is precisely what the
|
|
1703
|
+
* two hand-written call sites got wrong, each with its own bug-fix comment about `finally`.
|
|
1704
|
+
*
|
|
1705
|
+
* The disposal error is not silently swallowed either — it is reported through `onDisposeError`, so
|
|
1706
|
+
* a leak is observable without competing with the result.
|
|
1707
|
+
*/
|
|
1708
|
+
declare function withEphemeralAgent<TAgent, TResult>(create: () => EphemeralAgent<TAgent> | Promise<EphemeralAgent<TAgent>>, body: (agent: TAgent) => Promise<TResult>, options?: {
|
|
1709
|
+
readonly onDisposeError?: (error: unknown) => void;
|
|
1710
|
+
}): Promise<TResult>;
|
|
1711
|
+
|
|
2095
1712
|
/**
|
|
2096
1713
|
* M24 (ADR-0041) — MCP follow-ups, framework-side layer over the `@MCP` config (ADR-0040 § D2).
|
|
2097
1714
|
*
|
|
@@ -2182,100 +1799,6 @@ declare class McpFileError extends TheokitAgentError {
|
|
|
2182
1799
|
*/
|
|
2183
1800
|
declare function loadMcpJson(cwd: string, opts?: LoadMcpJsonOptions): McpServersMap;
|
|
2184
1801
|
|
|
2185
|
-
/**
|
|
2186
|
-
* M68 — the trust gate for `settingSources`.
|
|
2187
|
-
*
|
|
2188
|
-
* ## The defect this module closes
|
|
2189
|
-
*
|
|
2190
|
-
* `settingSources` enables on-disk config discovery. `'user'` reads `~/.theokit/` — the operator's
|
|
2191
|
-
* own machine, which no third party controls. `'project'` reads `<cwd>/.theokit/`, **including
|
|
2192
|
-
* `hooks.json`, which executes shell**.
|
|
2193
|
-
*
|
|
2194
|
-
* The previous API took `readonly SettingSource[]`, and its JSDoc justified the risk this way:
|
|
2195
|
-
* *"it is opt-in because `.theokit/` is the app's own repo (informed consent)"*. That premise holds
|
|
2196
|
-
* for a web app whose `cwd` is its own deploy. It does **not** hold for the class of product this
|
|
2197
|
-
* framework addresses — an agent whose `cwd` is a repository the user just cloned. There `.theokit/`
|
|
2198
|
-
* is attacker-controlled content, and enabling `'project'` is remote code execution on the first
|
|
2199
|
-
* `build()`.
|
|
2200
|
-
*
|
|
2201
|
-
* Documenting it did not prevent it. The measured consumer (TheoCode) did not trust the API: it
|
|
2202
|
-
* gated from the outside, with a `posture.allows` of its own (`chat.ts:386`, comment B-008). It
|
|
2203
|
-
* already **had** the right decision and could not pass it through, because the API only accepted
|
|
2204
|
-
* strings. The gate existed on its side and evaporated at the boundary.
|
|
2205
|
-
*
|
|
2206
|
-
* ## The evidence is the SDK's, not one invented here
|
|
2207
|
-
*
|
|
2208
|
-
* `TrustPosture` is `@theokit/sdk`'s own trust primitive, and `recordWiring`'s doc says *"a posture
|
|
2209
|
-
* is the only thing in this package that retains a capability"*. A bespoke type would make two trust
|
|
2210
|
-
* grammars coexist and drift apart (ADR 0063).
|
|
2211
|
-
*/
|
|
2212
|
-
/**
|
|
2213
|
-
* The framework's capability vocabulary — deliberately a single name (ADR 0065).
|
|
2214
|
-
*
|
|
2215
|
-
* `allows` is all-or-nothing in the SDK: every declared `K` gets the same boolean. A finer
|
|
2216
|
-
* vocabulary (`hooks`, `skills`, `subagents`, `mcp`) would promise the consumer it can gate one
|
|
2217
|
-
* without gating the other, and the primitive does not deliver that. An API that suggests a
|
|
2218
|
-
* distinction the runtime does not make teaches the wrong thing, and the error only surfaces when
|
|
2219
|
-
* somebody depends on the distinction.
|
|
2220
|
-
*/
|
|
2221
|
-
type SettingSourceCapability = 'projectSettings';
|
|
2222
|
-
/** Authorization to read config from the working directory. Requires the posture, never a claim. */
|
|
2223
|
-
interface ProjectSettingsGrant {
|
|
2224
|
-
/**
|
|
2225
|
-
* Typically the output of `resolveTrustPosture` — which is what gives it `source` (`'env' |
|
|
2226
|
-
* 'store' | 'default'`) and therefore a refusal that says WHERE the decision came from instead of
|
|
2227
|
-
* merely denying.
|
|
2228
|
-
*/
|
|
2229
|
-
readonly trustedBy: TrustPosture<SettingSourceCapability>;
|
|
2230
|
-
}
|
|
2231
|
-
/**
|
|
2232
|
-
* Which on-disk config roots the agent may read.
|
|
2233
|
-
*
|
|
2234
|
-
* The asymmetry is the design: `user` is a boolean because `~/.theokit/` belongs to the operator;
|
|
2235
|
-
* `project` requires evidence because `<cwd>/.theokit/` may not. Omitting a root is not enabling it
|
|
2236
|
-
* — never "enabling without a gate". The asymmetry is inherited from the SDK itself, whose
|
|
2237
|
-
* `TrustPostureInput.envOverride` documents that `false` and `undefined` both mean "the operator did
|
|
2238
|
-
* not turn it on", not "turned it off".
|
|
2239
|
-
*/
|
|
2240
|
-
interface SettingSourcesSelection {
|
|
2241
|
-
/** `~/.theokit/` — the operator's machine. No gate: no third party controls it. */
|
|
2242
|
-
readonly user?: boolean;
|
|
2243
|
-
/** `<cwd>/.theokit/` — controlled by whoever wrote the open repository. Requires evidence. */
|
|
2244
|
-
readonly project?: ProjectSettingsGrant;
|
|
2245
|
-
}
|
|
2246
|
-
/**
|
|
2247
|
-
* Refusal to read the working directory for lack of trust.
|
|
2248
|
-
*
|
|
2249
|
-
* Descends from `TheokitAgentError` because typed errors are an unbreakable rule here — and because
|
|
2250
|
-
* `isTransientError` only sees this hierarchy. A class extending plain `Error` would be invisible to
|
|
2251
|
-
* the predicate that separates recoverable from unrecoverable (the defect M67 fixed in five
|
|
2252
|
-
* classes).
|
|
2253
|
-
*/
|
|
2254
|
-
declare class UntrustedSettingSourceError extends TheokitAgentError {
|
|
2255
|
-
/** Where the trust decision came from: `'env' | 'store' | 'default'`. */
|
|
2256
|
-
readonly trustSource: string;
|
|
2257
|
-
/** The refused capability. */
|
|
2258
|
-
readonly capability: SettingSourceCapability;
|
|
2259
|
-
readonly name = "UntrustedSettingSourceError";
|
|
2260
|
-
constructor(message: string,
|
|
2261
|
-
/** Where the trust decision came from: `'env' | 'store' | 'default'`. */
|
|
2262
|
-
trustSource: string,
|
|
2263
|
-
/** The refused capability. */
|
|
2264
|
-
capability: SettingSourceCapability);
|
|
2265
|
-
}
|
|
2266
|
-
/**
|
|
2267
|
-
* Translate the declared selection into the `SettingSource`s the SDK accepts, refusing what the
|
|
2268
|
-
* posture does not authorize.
|
|
2269
|
-
*
|
|
2270
|
-
* Refuses rather than ignores (ADR 0064). Ignoring would leave the product running in the belief
|
|
2271
|
-
* that the repository's hooks are active — a silent failure mode, on the wrong side. The SDK already
|
|
2272
|
-
* picked that side for the same problem: `recordWiring` throws `UngatedCapabilityError` when
|
|
2273
|
-
* somebody registers a capability the posture does not gate.
|
|
2274
|
-
*
|
|
2275
|
-
* @throws {UntrustedSettingSourceError} when `project` is requested and the posture does not grant it.
|
|
2276
|
-
*/
|
|
2277
|
-
declare function resolveSettingSources(selection: SettingSourcesSelection | undefined): readonly SettingSource[];
|
|
2278
|
-
|
|
2279
1802
|
/**
|
|
2280
1803
|
* Agent manifest generator — build-time JSON describing all agents, tools, guards, policies.
|
|
2281
1804
|
*
|
|
@@ -2421,4 +1944,4 @@ declare function agentsPlugin(opts: AgentsPluginOptions): {
|
|
|
2421
1944
|
register(app: PluginApp): void;
|
|
2422
1945
|
};
|
|
2423
1946
|
|
|
2424
|
-
export { type
|
|
1947
|
+
export { type LoopStrategyConfig as $, type AgentManifestEntry as A, type BackgroundDelegation as B, type ContextWindowOptions as C, type DelegationResult as D, type CompiledContextWindow as E, ContextualTool as F, DEFAULT_MAX_ITERATIONS as G, type HitlDecision as H, type DefinitionOrThunk as I, type DelegateFn as J, type DelegateOptions as K, type LoopStrategy as L, DelegationBudgetExceededError as M, DelegationError as N, type DelegationPort as O, type DelegationTarget as P, DelegationTimeoutError as Q, type ReflectionStrategy as R, type StreamEvent as S, type DoneEvent as T, type EphemeralAgent as U, type ErrorEvent as V, type FileEditEvent as W, type IterationEvent as X, type LLMCallContext as Y, type LoopFinishReason as Z, type LoopOutcome as _, type RoundStreamFactory as a, resolveMcpServers as a$, type McpApprovalSpec as a0, McpFileError as a1, type McpRegistryConfig as a2, type McpRequestContext as a3, type McpSelection as a4, type PartialToolCallEvent as a5, type ProcessInputContext as a6, type ReflectionContext as a7, type ReflectionResult as a8, type ReflectionStrategyConfig as a9, createThinkTagExtractor as aA, createToolHooksPlugin as aB, delegate as aC, delegateBackground as aD, delegateWithScoring as aE, extractThinkTagStream as aF, generateAgentManifest as aG, generateAgentRoutes as aH, isAgentContext as aI, isApprovalRequired as aJ, isDone as aK, isError as aL, isPartialToolCall as aM, isTextDelta as aN, isToolCall as aO, isToolResult as aP, ladderReflectionStrategy as aQ, loadMcpJson as aR, loopStrategyConfigSchema as aS, mcpRegistry as aT, mcpToolApprovals as aU, noopReflectionStrategy as aV, presentUIMessageStream as aW, projectContextMetadataOnlyKnobs as aX, reasoningEffortOf as aY, reflectionStrategyConfigSchema as aZ, resolveLoopStrategy as a_, type RunStartedEvent as aa, type ScoreVerdict as ab, type ScoredDelegation as ac, type Scorer as ad, type SdkAgentHandle as ae, type SdkMessage as af, type SdkSendOptions as ag, type SdkTurnHandle as ah, type Segment as ai, type StateUpdateEvent as aj, type TextDeltaEvent as ak, type ThinkingEvent as al, type ToolCallEvent as am, type ToolCallVeto as an, type ToolHooks as ao, type ToolHooksPlugin as ap, type ToolResultEvent as aq, agentsPlugin as ar, buildModelSelection as as, compileAgentModule as at, compileContextWindow as au, compileProjectContext as av, compileSkills as aw, createAgentExecutionContext as ax, createApiErrorHandler as ay, createSdkAgentStream as az, type SkillsOptions as b, runWithApiErrorHandling as b0, streamAgentResponse as b1, toAgentFactory as b2, translateSdkEvent as b3, withClockCap as b4, withEphemeralAgent as b5, type ApprovalPosture as c, type AfterToolCallContext as d, AgentBuilder as e, AgentDefinitionError as f, type AgentExecutionContext as g, type AgentManifest as h, type AgentManifestSource as i, type AgentManifestTool as j, type AgentRoute as k, type AgentRouteContext as l, type AgentRunInfo as m, type AgentStreamEvent as n, type AgentTurnMetadata as o, type AgentsPluginOptions as p, type ApiErrorContext as q, type ApiErrorDecision as r, streamAgentUIMessages as s, type ApiErrorPolicy as t, type ApprovalRequiredEvent as u, type ArtifactChunkEvent as v, type ArtifactStartEvent as w, type BeforeToolCallContext as x, BudgetExceededError as y, type CheckpointSavedEvent as z };
|