@theokit/agents 7.3.1 → 7.4.1
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-tgyu8J7q.d.ts → agent-handle-BX4oFqfb.d.ts} +10 -10
- package/dist/auth.d.ts +68 -66
- package/dist/auth.js +106 -98
- package/dist/auth.js.map +1 -1
- package/dist/{bridge-entry-ofFpOe-j.d.ts → bridge-entry-Z8GjrwH4.d.ts} +85 -84
- package/dist/bridge.d.ts +1 -1
- package/dist/bridge.js +1 -2
- package/dist/{chunk-CVDPGEJF.js → chunk-FJA4QQLZ.js} +191 -246
- package/dist/chunk-FJA4QQLZ.js.map +1 -0
- package/dist/{chunk-7ECCHM4N.js → chunk-PHUNONZT.js} +523 -1053
- package/dist/chunk-PHUNONZT.js.map +1 -0
- package/dist/client-react.d.ts +1 -1
- package/dist/client-react.js +3 -9
- package/dist/client-react.js.map +1 -1
- package/dist/client.d.ts +3 -3
- package/dist/client.js +1 -2
- package/dist/index.d.ts +82 -50
- package/dist/index.js +161 -394
- package/dist/index.js.map +1 -1
- package/dist/interactive.js +6 -3
- package/dist/interactive.js.map +1 -1
- package/dist/persistence.js +0 -2
- package/dist/persistence.js.map +1 -1
- package/dist/pty.js +7 -3
- package/dist/pty.js.map +1 -1
- package/dist/sandbox.js +26 -3
- package/dist/sandbox.js.map +1 -1
- package/dist/testing.js +3 -21
- package/dist/testing.js.map +1 -1
- package/dist/tools.js +55 -3
- package/dist/tools.js.map +1 -1
- package/package.json +12 -12
- package/LICENSE +0 -201
- package/dist/chunk-7ECCHM4N.js.map +0 -1
- package/dist/chunk-CVDPGEJF.js.map +0 -1
- package/dist/chunk-Z4QWC7IK.js +0 -7
- package/dist/chunk-Z4QWC7IK.js.map +0 -1
|
@@ -1,30 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
__name
|
|
3
|
-
} from "./chunk-Z4QWC7IK.js";
|
|
4
|
-
|
|
5
1
|
// src/errors.ts
|
|
6
2
|
import { ConfigurationError } from "@theokit/sdk/errors";
|
|
7
3
|
|
|
8
4
|
// src/bridge/define-agent.ts
|
|
9
5
|
var AGENT_BRAND = /* @__PURE__ */ Symbol.for("theokit.agent.definition");
|
|
10
6
|
function defineAgent(config) {
|
|
11
|
-
return {
|
|
12
|
-
...config,
|
|
13
|
-
[AGENT_BRAND]: true
|
|
14
|
-
};
|
|
7
|
+
return { ...config, [AGENT_BRAND]: true };
|
|
15
8
|
}
|
|
16
|
-
__name(defineAgent, "defineAgent");
|
|
17
9
|
function isAgentDefinition(value) {
|
|
18
10
|
return typeof value === "object" && value !== null && value[AGENT_BRAND] === true;
|
|
19
11
|
}
|
|
20
|
-
__name(isAgentDefinition, "isAgentDefinition");
|
|
21
12
|
function toCompiledTool(tool) {
|
|
22
13
|
const handler = tool.handler;
|
|
23
14
|
const compiled = {
|
|
24
15
|
name: tool.name,
|
|
25
16
|
description: tool.description,
|
|
26
17
|
inputSchema: tool.inputSchema,
|
|
27
|
-
handler:
|
|
18
|
+
handler: (input, ctx) => handler(input, ctx)
|
|
28
19
|
};
|
|
29
20
|
for (const sym of Object.getOwnPropertySymbols(tool)) {
|
|
30
21
|
;
|
|
@@ -32,7 +23,6 @@ function toCompiledTool(tool) {
|
|
|
32
23
|
}
|
|
33
24
|
return compiled;
|
|
34
25
|
}
|
|
35
|
-
__name(toCompiledTool, "toCompiledTool");
|
|
36
26
|
function compileAgentDefinition(def) {
|
|
37
27
|
return {
|
|
38
28
|
model: def.model,
|
|
@@ -43,48 +33,33 @@ function compileAgentDefinition(def) {
|
|
|
43
33
|
stream: true,
|
|
44
34
|
// M7 — run-context flows to CompiledAgentOptions.runContext (distinct from the
|
|
45
35
|
// context-window `context` field the decorator path uses); absent ⇒ no key.
|
|
46
|
-
...def.context !== void 0 ? {
|
|
47
|
-
runContext: def.context
|
|
48
|
-
} : {},
|
|
36
|
+
...def.context !== void 0 ? { runContext: def.context } : {},
|
|
49
37
|
// M9 — guardrails flow through unchanged; the runner applies them at the input boundary.
|
|
50
|
-
...def.guardrails !== void 0 ? {
|
|
51
|
-
guardrails: def.guardrails
|
|
52
|
-
} : {},
|
|
38
|
+
...def.guardrails !== void 0 ? { guardrails: def.guardrails } : {},
|
|
53
39
|
// M14 — HITL approvals compile into the same `hitl` map the decorator path produces.
|
|
54
|
-
...def.approvals !== void 0 ? {
|
|
55
|
-
hitl: compileApprovals(def)
|
|
56
|
-
} : {},
|
|
40
|
+
...def.approvals !== void 0 ? { hitl: compileApprovals(def) } : {},
|
|
57
41
|
// M13 — skills: a static list → SDK skills.enabled; a resolver → carried for the request path.
|
|
58
42
|
...compileSkillsSelection(def.skills),
|
|
59
43
|
// theokit-file-based-config — the declared `.theokit/` sources flow to the run path, which
|
|
60
44
|
// projects them into `Agent.create({ local.settingSources })`; absent ⇒ inline config only.
|
|
61
|
-
...def.settingSources !== void 0 ? {
|
|
62
|
-
settingSources: def.settingSources
|
|
63
|
-
} : {},
|
|
45
|
+
...def.settingSources !== void 0 ? { settingSources: def.settingSources } : {},
|
|
64
46
|
// M49 — memory flows to the projection layer; `assembleM8CreateOptions` forwards it to Agent.create.
|
|
65
|
-
...def.memory !== void 0 ? {
|
|
66
|
-
memory: def.memory
|
|
67
|
-
} : {},
|
|
47
|
+
...def.memory !== void 0 ? { memory: def.memory } : {},
|
|
68
48
|
// Hooks are converted here — the layer EVERY path converges on — rather than on the builder, so
|
|
69
49
|
// `defineAgent({ hooks })` cannot type-check and silently no-op. A lifecycle hook that is
|
|
70
50
|
// declared but never registered is a security gate that does not gate.
|
|
71
51
|
...compileHooksAndPlugins(def),
|
|
72
52
|
// MCP — builder/`defineAgent` servers converge on the same `mcpServers` field the `@MCP`
|
|
73
53
|
// decorator path populates; the SDK adapter forwards it to `Agent.create({ mcpServers })`.
|
|
74
|
-
...def.mcpServers !== void 0 ? {
|
|
75
|
-
mcpServers: def.mcpServers
|
|
76
|
-
} : {}
|
|
54
|
+
...def.mcpServers !== void 0 ? { mcpServers: def.mcpServers } : {}
|
|
77
55
|
};
|
|
78
56
|
}
|
|
79
|
-
__name(compileAgentDefinition, "compileAgentDefinition");
|
|
80
57
|
function compileHooksAndPlugins(def) {
|
|
81
58
|
const map = def.hooks;
|
|
82
59
|
const entries = Object.entries(map ?? {}).filter(([, h]) => typeof h === "function");
|
|
83
60
|
const explicit = def.plugins ?? [];
|
|
84
61
|
if (entries.length === 0) {
|
|
85
|
-
return def.plugins !== void 0 ? {
|
|
86
|
-
plugins: def.plugins
|
|
87
|
-
} : {};
|
|
62
|
+
return def.plugins !== void 0 ? { plugins: def.plugins } : {};
|
|
88
63
|
}
|
|
89
64
|
const plugin = {
|
|
90
65
|
name: "theokit-builder-hooks",
|
|
@@ -96,19 +71,11 @@ function compileHooksAndPlugins(def) {
|
|
|
96
71
|
}
|
|
97
72
|
}
|
|
98
73
|
};
|
|
99
|
-
return {
|
|
100
|
-
plugins: [
|
|
101
|
-
...explicit,
|
|
102
|
-
plugin
|
|
103
|
-
]
|
|
104
|
-
};
|
|
74
|
+
return { plugins: [...explicit, plugin] };
|
|
105
75
|
}
|
|
106
|
-
__name(compileHooksAndPlugins, "compileHooksAndPlugins");
|
|
107
76
|
function compileSkillsSelection(skills) {
|
|
108
77
|
if (skills === void 0) return {};
|
|
109
|
-
if (typeof skills === "function") return {
|
|
110
|
-
skillsResolver: skills
|
|
111
|
-
};
|
|
78
|
+
if (typeof skills === "function") return { skillsResolver: skills };
|
|
112
79
|
const enabled = [];
|
|
113
80
|
const inline = [];
|
|
114
81
|
for (const entry of skills) {
|
|
@@ -116,30 +83,22 @@ function compileSkillsSelection(skills) {
|
|
|
116
83
|
else inline.push(entry);
|
|
117
84
|
}
|
|
118
85
|
return {
|
|
119
|
-
skills: {
|
|
120
|
-
enabled,
|
|
121
|
-
autoInject: true,
|
|
122
|
-
...inline.length > 0 ? {
|
|
123
|
-
inline
|
|
124
|
-
} : {}
|
|
125
|
-
}
|
|
86
|
+
skills: { enabled, autoInject: true, ...inline.length > 0 ? { inline } : {} }
|
|
126
87
|
};
|
|
127
88
|
}
|
|
128
|
-
__name(compileSkillsSelection, "compileSkillsSelection");
|
|
129
89
|
function compileApprovals(def) {
|
|
130
90
|
const toolNames = new Set((def.tools ?? []).map((t) => t.name));
|
|
131
91
|
const gates = /* @__PURE__ */ new Map();
|
|
132
92
|
for (const [toolName, options] of Object.entries(def.approvals ?? {})) {
|
|
133
93
|
if (!toolNames.has(toolName)) {
|
|
134
|
-
throw new Error(
|
|
135
|
-
...toolNames
|
|
136
|
-
|
|
94
|
+
throw new Error(
|
|
95
|
+
`[@theokit/agents] defineAgent approval references unknown tool "${toolName}". Declared tools: ${[...toolNames].join(", ") || "(none)"}.`
|
|
96
|
+
);
|
|
137
97
|
}
|
|
138
98
|
gates.set(toolName, options);
|
|
139
99
|
}
|
|
140
100
|
return gates;
|
|
141
101
|
}
|
|
142
|
-
__name(compileApprovals, "compileApprovals");
|
|
143
102
|
|
|
144
103
|
// src/bridge/compile-context-window.ts
|
|
145
104
|
var STRATEGY_KNOBS = [
|
|
@@ -155,26 +114,16 @@ function compileContextWindow(options) {
|
|
|
155
114
|
}
|
|
156
115
|
const opts = options;
|
|
157
116
|
const metadataOnlyKnobs = STRATEGY_KNOBS.filter((knob) => opts[knob] !== void 0);
|
|
158
|
-
return {
|
|
159
|
-
context,
|
|
160
|
-
metadataOnlyKnobs
|
|
161
|
-
};
|
|
117
|
+
return { context, metadataOnlyKnobs };
|
|
162
118
|
}
|
|
163
|
-
__name(compileContextWindow, "compileContextWindow");
|
|
164
119
|
|
|
165
120
|
// src/bridge/compile-skills.ts
|
|
166
121
|
function compileSkills(options) {
|
|
167
122
|
if (options.autoDiscover) {
|
|
168
|
-
return {
|
|
169
|
-
autoInject: true
|
|
170
|
-
};
|
|
123
|
+
return { autoInject: true };
|
|
171
124
|
}
|
|
172
|
-
return {
|
|
173
|
-
enabled: options.include,
|
|
174
|
-
autoInject: true
|
|
175
|
-
};
|
|
125
|
+
return { enabled: options.include, autoInject: true };
|
|
176
126
|
}
|
|
177
|
-
__name(compileSkills, "compileSkills");
|
|
178
127
|
|
|
179
128
|
// src/bridge/agent-compiler.ts
|
|
180
129
|
var SDK_TOOL_NAME = /^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/;
|
|
@@ -188,24 +137,27 @@ var SDK_RESERVED_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
188
137
|
var SDK_RESERVED_TOOL_PREFIX = "mcp_";
|
|
189
138
|
function toolRuntimeName(namespace, toolName) {
|
|
190
139
|
if (toolName.trim().length === 0) {
|
|
191
|
-
const where = namespace ? `
|
|
192
|
-
throw new ConfigurationError(`tool:
|
|
140
|
+
const where = namespace ? ` in namespace "${namespace}"` : "";
|
|
141
|
+
throw new ConfigurationError(`tool: empty name${where} \u2014 declare a non-empty name for the tool`);
|
|
193
142
|
}
|
|
194
143
|
const name = namespace ? `${namespace}_${toolName}` : toolName;
|
|
195
144
|
if (!SDK_TOOL_NAME.test(name)) {
|
|
196
145
|
if (SDK_TOOL_NAME_CHARSET.test(name)) {
|
|
197
|
-
throw new ConfigurationError(
|
|
146
|
+
throw new ConfigurationError(
|
|
147
|
+
`tool: name "${name}" has length ${name.length} \u2014 the composition namespace + "_" + tool exceeds the maximum of ${SDK_TOOL_NAME_MAX_LENGTH} the SDK accepts`
|
|
148
|
+
);
|
|
198
149
|
}
|
|
199
|
-
throw new ConfigurationError(
|
|
150
|
+
throw new ConfigurationError(
|
|
151
|
+
`tool: invalid name "${name}" \u2014 it must match ${String(SDK_TOOL_NAME)} (the SDK rejects the rest; check the namespace and the tool name)`
|
|
152
|
+
);
|
|
200
153
|
}
|
|
201
154
|
if (SDK_RESERVED_TOOL_NAMES.has(name) || name.startsWith(SDK_RESERVED_TOOL_PREFIX)) {
|
|
202
|
-
throw new ConfigurationError(
|
|
203
|
-
...SDK_RESERVED_TOOL_NAMES
|
|
204
|
-
|
|
155
|
+
throw new ConfigurationError(
|
|
156
|
+
`tool: reserved name "${name}" \u2014 the SDK reserves ${[...SDK_RESERVED_TOOL_NAMES].join(", ")} and the prefix "${SDK_RESERVED_TOOL_PREFIX}"`
|
|
157
|
+
);
|
|
205
158
|
}
|
|
206
159
|
return name;
|
|
207
160
|
}
|
|
208
|
-
__name(toolRuntimeName, "toolRuntimeName");
|
|
209
161
|
function compileHitlGates(toolboxes) {
|
|
210
162
|
const gates = /* @__PURE__ */ new Map();
|
|
211
163
|
for (const tb of toolboxes) {
|
|
@@ -217,50 +169,50 @@ function compileHitlGates(toolboxes) {
|
|
|
217
169
|
}
|
|
218
170
|
return gates;
|
|
219
171
|
}
|
|
220
|
-
__name(compileHitlGates, "compileHitlGates");
|
|
221
172
|
function compileTools(toolboxes, toolboxInstances) {
|
|
222
173
|
const tools = [];
|
|
223
174
|
for (const tb of toolboxes) {
|
|
224
175
|
const instance = toolboxInstances.get(tb.class);
|
|
225
176
|
if (!instance) {
|
|
226
|
-
throw new ConfigurationError(
|
|
177
|
+
throw new ConfigurationError(
|
|
178
|
+
`toolbox: ${tb.class.name} was not instantiated \u2014 pass the instance in \`toolboxInstances\``
|
|
179
|
+
);
|
|
227
180
|
}
|
|
228
181
|
for (const tool of tb.tools) {
|
|
229
182
|
const handler = instance[tool.propertyKey];
|
|
230
183
|
if (typeof handler !== "function") {
|
|
231
|
-
throw new ConfigurationError(
|
|
184
|
+
throw new ConfigurationError(
|
|
185
|
+
`toolbox: ${tb.class.name}.${String(tool.propertyKey)} is not a method (tool "${tool.config.name}")`
|
|
186
|
+
);
|
|
232
187
|
}
|
|
233
188
|
const name = toolRuntimeName(tb.namespace, tool.config.name);
|
|
234
189
|
tools.push({
|
|
235
190
|
name,
|
|
236
191
|
description: tool.config.description,
|
|
237
192
|
inputSchema: tool.config.input,
|
|
238
|
-
handler:
|
|
193
|
+
handler: (input) => handler.call(instance, input)
|
|
239
194
|
});
|
|
240
195
|
}
|
|
241
196
|
}
|
|
242
197
|
return tools;
|
|
243
198
|
}
|
|
244
|
-
__name(compileTools, "compileTools");
|
|
245
199
|
|
|
246
200
|
// src/bridge/agent-execution-context.ts
|
|
247
201
|
function createAgentExecutionContext(base, agent, run, toolCall) {
|
|
248
202
|
return {
|
|
249
|
-
getRequest:
|
|
250
|
-
getUrl:
|
|
251
|
-
getClass:
|
|
252
|
-
getMethodName:
|
|
253
|
-
getAgent:
|
|
254
|
-
getRun:
|
|
255
|
-
getToolCall:
|
|
256
|
-
isAgentContext:
|
|
203
|
+
getRequest: () => base.getRequest(),
|
|
204
|
+
getUrl: () => base.getUrl(),
|
|
205
|
+
getClass: () => base.getClass(),
|
|
206
|
+
getMethodName: () => base.getMethodName(),
|
|
207
|
+
getAgent: () => agent,
|
|
208
|
+
getRun: () => run,
|
|
209
|
+
getToolCall: () => toolCall ?? null,
|
|
210
|
+
isAgentContext: () => true
|
|
257
211
|
};
|
|
258
212
|
}
|
|
259
|
-
__name(createAgentExecutionContext, "createAgentExecutionContext");
|
|
260
213
|
function isAgentContext(ctx) {
|
|
261
214
|
return "isAgentContext" in ctx && ctx.isAgentContext();
|
|
262
215
|
}
|
|
263
|
-
__name(isAgentContext, "isAgentContext");
|
|
264
216
|
|
|
265
217
|
// src/bridge/compile-project-context.ts
|
|
266
218
|
var UNMAPPED_KNOBS = [
|
|
@@ -274,7 +226,6 @@ function projectContextMetadataOnlyKnobs(options) {
|
|
|
274
226
|
const opts = options;
|
|
275
227
|
return UNMAPPED_KNOBS.filter((knob) => opts[knob] !== void 0);
|
|
276
228
|
}
|
|
277
|
-
__name(projectContextMetadataOnlyKnobs, "projectContextMetadataOnlyKnobs");
|
|
278
229
|
function compileProjectContext(options, base) {
|
|
279
230
|
return async (promptCtx) => {
|
|
280
231
|
const resolvedBase = typeof base === "function" ? await base(promptCtx) : base;
|
|
@@ -285,24 +236,16 @@ function compileProjectContext(options, base) {
|
|
|
285
236
|
const { buildEnvContext, buildRepoMap } = await import("@theokit/sdk-tools");
|
|
286
237
|
const { readProjectInstructions } = await import("@theokit/sdk/project");
|
|
287
238
|
const env = buildEnvContext(cwd);
|
|
288
|
-
const repoMap = buildRepoMap(cwd, {
|
|
289
|
-
ignore: options.ignorePatterns
|
|
290
|
-
});
|
|
239
|
+
const repoMap = buildRepoMap(cwd, { ignore: options.ignorePatterns });
|
|
291
240
|
let instructions = "";
|
|
292
241
|
try {
|
|
293
242
|
instructions = (await readProjectInstructions(cwd)).content ?? "";
|
|
294
243
|
} catch {
|
|
295
244
|
instructions = "";
|
|
296
245
|
}
|
|
297
|
-
return [
|
|
298
|
-
env,
|
|
299
|
-
repoMap,
|
|
300
|
-
instructions,
|
|
301
|
-
resolvedBase
|
|
302
|
-
].filter(Boolean).join("\n\n");
|
|
246
|
+
return [env, repoMap, instructions, resolvedBase].filter(Boolean).join("\n\n");
|
|
303
247
|
};
|
|
304
248
|
}
|
|
305
|
-
__name(compileProjectContext, "compileProjectContext");
|
|
306
249
|
|
|
307
250
|
// src/bridge/agent-sse-handler.ts
|
|
308
251
|
var encoder = new TextEncoder();
|
|
@@ -310,14 +253,14 @@ function streamAgentResponse(eventStream) {
|
|
|
310
253
|
const stream = new ReadableStream({
|
|
311
254
|
async start(controller) {
|
|
312
255
|
let closed = false;
|
|
313
|
-
const safeEnqueue =
|
|
256
|
+
const safeEnqueue = (chunk) => {
|
|
314
257
|
if (closed) return;
|
|
315
258
|
try {
|
|
316
259
|
controller.enqueue(chunk);
|
|
317
260
|
} catch {
|
|
318
261
|
closed = true;
|
|
319
262
|
}
|
|
320
|
-
}
|
|
263
|
+
};
|
|
321
264
|
try {
|
|
322
265
|
for await (const event of eventStream) {
|
|
323
266
|
if (closed) break;
|
|
@@ -332,9 +275,7 @@ data: ${data}
|
|
|
332
275
|
if (!closed) {
|
|
333
276
|
const errorEvent = {
|
|
334
277
|
type: "error",
|
|
335
|
-
error: {
|
|
336
|
-
message: err instanceof Error ? err.message : "Internal agent error"
|
|
337
|
-
}
|
|
278
|
+
error: { message: err instanceof Error ? err.message : "Internal agent error" }
|
|
338
279
|
};
|
|
339
280
|
const frame = `event: error
|
|
340
281
|
data: ${JSON.stringify(errorEvent)}
|
|
@@ -356,37 +297,29 @@ data: ${JSON.stringify(errorEvent)}
|
|
|
356
297
|
}
|
|
357
298
|
});
|
|
358
299
|
}
|
|
359
|
-
__name(streamAgentResponse, "streamAgentResponse");
|
|
360
300
|
|
|
361
301
|
// src/bridge/agent-stream-events.ts
|
|
362
302
|
function isTextDelta(e) {
|
|
363
303
|
return e.type === "text_delta";
|
|
364
304
|
}
|
|
365
|
-
__name(isTextDelta, "isTextDelta");
|
|
366
305
|
function isToolCall(e) {
|
|
367
306
|
return e.type === "tool_call";
|
|
368
307
|
}
|
|
369
|
-
__name(isToolCall, "isToolCall");
|
|
370
308
|
function isPartialToolCall(e) {
|
|
371
309
|
return e.type === "partial_tool_call";
|
|
372
310
|
}
|
|
373
|
-
__name(isPartialToolCall, "isPartialToolCall");
|
|
374
311
|
function isToolResult(e) {
|
|
375
312
|
return e.type === "tool_result";
|
|
376
313
|
}
|
|
377
|
-
__name(isToolResult, "isToolResult");
|
|
378
314
|
function isDone(e) {
|
|
379
315
|
return e.type === "done";
|
|
380
316
|
}
|
|
381
|
-
__name(isDone, "isDone");
|
|
382
317
|
function isError(e) {
|
|
383
318
|
return e.type === "error";
|
|
384
319
|
}
|
|
385
|
-
__name(isError, "isError");
|
|
386
320
|
function isApprovalRequired(e) {
|
|
387
321
|
return e.type === "approval_required";
|
|
388
322
|
}
|
|
389
|
-
__name(isApprovalRequired, "isApprovalRequired");
|
|
390
323
|
|
|
391
324
|
// src/bridge/agent-route-generator.ts
|
|
392
325
|
function generateAgentRoutes(ctx) {
|
|
@@ -396,7 +329,7 @@ function generateAgentRoutes(ctx) {
|
|
|
396
329
|
routes.push({
|
|
397
330
|
method: "POST",
|
|
398
331
|
path: `${basePath}/chat`,
|
|
399
|
-
handler:
|
|
332
|
+
handler: async (request) => {
|
|
400
333
|
let body = null;
|
|
401
334
|
try {
|
|
402
335
|
body = await request.json();
|
|
@@ -404,92 +337,75 @@ function generateAgentRoutes(ctx) {
|
|
|
404
337
|
}
|
|
405
338
|
const message = body?.message;
|
|
406
339
|
if (typeof message !== "string" || message.length === 0) {
|
|
407
|
-
return new Response(
|
|
408
|
-
error: {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
}
|
|
412
|
-
}), {
|
|
413
|
-
status: 400,
|
|
414
|
-
headers: {
|
|
415
|
-
"content-type": "application/json"
|
|
416
|
-
}
|
|
417
|
-
});
|
|
340
|
+
return new Response(
|
|
341
|
+
JSON.stringify({ error: { code: "BAD_REQUEST", message: "message field required" } }),
|
|
342
|
+
{ status: 400, headers: { "content-type": "application/json" } }
|
|
343
|
+
);
|
|
418
344
|
}
|
|
419
345
|
const rawSessionId = body?.sessionId;
|
|
420
346
|
const sessionId = typeof rawSessionId === "string" ? rawSessionId : `session-${Date.now()}`;
|
|
421
347
|
return streamAgentResponse(createRun(message, sessionId));
|
|
422
|
-
}
|
|
348
|
+
}
|
|
423
349
|
});
|
|
424
350
|
if (getRun) {
|
|
425
351
|
routes.push({
|
|
426
352
|
method: "GET",
|
|
427
353
|
path: `${basePath}/runs/:runId`,
|
|
428
|
-
handler:
|
|
354
|
+
handler: async (request) => {
|
|
429
355
|
const url = new URL(request.url);
|
|
430
356
|
const runId = url.pathname.split("/").pop() ?? "";
|
|
431
357
|
const run = await getRun(runId);
|
|
432
358
|
if (!run) {
|
|
433
|
-
return new Response(
|
|
434
|
-
error: {
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
}
|
|
438
|
-
}), {
|
|
439
|
-
status: 404,
|
|
440
|
-
headers: {
|
|
441
|
-
"content-type": "application/json"
|
|
442
|
-
}
|
|
443
|
-
});
|
|
359
|
+
return new Response(
|
|
360
|
+
JSON.stringify({ error: { code: "NOT_FOUND", message: `Run ${runId} not found` } }),
|
|
361
|
+
{ status: 404, headers: { "content-type": "application/json" } }
|
|
362
|
+
);
|
|
444
363
|
}
|
|
445
364
|
return new Response(JSON.stringify(run), {
|
|
446
365
|
status: 200,
|
|
447
|
-
headers: {
|
|
448
|
-
"content-type": "application/json"
|
|
449
|
-
}
|
|
366
|
+
headers: { "content-type": "application/json" }
|
|
450
367
|
});
|
|
451
|
-
}
|
|
368
|
+
}
|
|
452
369
|
});
|
|
453
370
|
}
|
|
454
371
|
return routes;
|
|
455
372
|
}
|
|
456
|
-
__name(generateAgentRoutes, "generateAgentRoutes");
|
|
457
373
|
|
|
458
374
|
// src/guardrails/types.ts
|
|
459
375
|
var GuardrailViolationError = class extends Error {
|
|
460
|
-
|
|
461
|
-
|
|
376
|
+
constructor(guardName, phase, reason) {
|
|
377
|
+
super(`Guardrail "${guardName}" blocked ${phase}: ${reason}`);
|
|
378
|
+
this.guardName = guardName;
|
|
379
|
+
this.phase = phase;
|
|
380
|
+
this.reason = reason;
|
|
381
|
+
this.name = "GuardrailViolationError";
|
|
462
382
|
}
|
|
463
383
|
guardName;
|
|
464
384
|
phase;
|
|
465
385
|
reason;
|
|
466
|
-
constructor(guardName, phase, reason) {
|
|
467
|
-
super(`Guardrail "${guardName}" blocked ${phase}: ${reason}`), this.guardName = guardName, this.phase = phase, this.reason = reason;
|
|
468
|
-
this.name = "GuardrailViolationError";
|
|
469
|
-
}
|
|
470
386
|
};
|
|
471
387
|
var CostBudgetExceededError = class extends Error {
|
|
472
|
-
static {
|
|
473
|
-
__name(this, "CostBudgetExceededError");
|
|
474
|
-
}
|
|
475
|
-
usedTokens;
|
|
476
|
-
maxTokens;
|
|
477
388
|
constructor(usedTokens, maxTokens) {
|
|
478
|
-
super(`Cost budget exceeded: ${usedTokens} > ${maxTokens} tokens`)
|
|
389
|
+
super(`Cost budget exceeded: ${usedTokens} > ${maxTokens} tokens`);
|
|
390
|
+
this.usedTokens = usedTokens;
|
|
391
|
+
this.maxTokens = maxTokens;
|
|
479
392
|
this.name = "CostBudgetExceededError";
|
|
480
393
|
}
|
|
394
|
+
usedTokens;
|
|
395
|
+
maxTokens;
|
|
481
396
|
};
|
|
482
397
|
|
|
483
398
|
// src/guardrails/detectors.ts
|
|
484
399
|
function estimateTokens(text) {
|
|
485
400
|
return Math.ceil(text.length / 4);
|
|
486
401
|
}
|
|
487
|
-
__name(estimateTokens, "estimateTokens");
|
|
488
402
|
var INJECTION_PHRASES = [
|
|
489
403
|
"previous instructions",
|
|
404
|
+
// "ignore/disregard [all|the] previous instructions"
|
|
490
405
|
"disregard the above",
|
|
491
406
|
"you are now dan",
|
|
492
407
|
"system prompt",
|
|
408
|
+
// "reveal your/the system prompt"
|
|
493
409
|
"no restrictions",
|
|
494
410
|
"without restrictions",
|
|
495
411
|
"no rules",
|
|
@@ -498,31 +414,21 @@ var INJECTION_PHRASES = [
|
|
|
498
414
|
function normalizeForMatch(text) {
|
|
499
415
|
return text.toLowerCase().replace(/\s+/g, " ");
|
|
500
416
|
}
|
|
501
|
-
__name(normalizeForMatch, "normalizeForMatch");
|
|
502
417
|
function promptInjectionDetector(options = {}) {
|
|
503
|
-
const phrases = [
|
|
504
|
-
...INJECTION_PHRASES,
|
|
505
|
-
...(options.extra ?? []).map((p) => p.toLowerCase())
|
|
506
|
-
];
|
|
418
|
+
const phrases = [...INJECTION_PHRASES, ...(options.extra ?? []).map((p) => p.toLowerCase())];
|
|
507
419
|
return {
|
|
508
420
|
name: "prompt-injection",
|
|
509
421
|
checkInput(text) {
|
|
510
422
|
const normalized = normalizeForMatch(text);
|
|
511
423
|
for (const phrase of phrases) {
|
|
512
424
|
if (normalized.includes(phrase)) {
|
|
513
|
-
return {
|
|
514
|
-
action: "block",
|
|
515
|
-
reason: `prompt injection phrase matched: "${phrase}"`
|
|
516
|
-
};
|
|
425
|
+
return { action: "block", reason: `prompt injection phrase matched: "${phrase}"` };
|
|
517
426
|
}
|
|
518
427
|
}
|
|
519
|
-
return {
|
|
520
|
-
action: "allow"
|
|
521
|
-
};
|
|
428
|
+
return { action: "allow" };
|
|
522
429
|
}
|
|
523
430
|
};
|
|
524
431
|
}
|
|
525
|
-
__name(promptInjectionDetector, "promptInjectionDetector");
|
|
526
432
|
var CPF = /\b\d{3}\.?\d{3}\.?\d{3}-?\d{2}\b/g;
|
|
527
433
|
var EMAIL = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g;
|
|
528
434
|
var PHONE = /\+?\d[\d\s()-]{7,13}\d/g;
|
|
@@ -535,36 +441,22 @@ function piiDetector(options = {}) {
|
|
|
535
441
|
redacted = redacted.replace(EMAIL, placeholder);
|
|
536
442
|
redacted = redacted.replace(CPF, placeholder);
|
|
537
443
|
redacted = redacted.replace(PHONE, placeholder);
|
|
538
|
-
if (redacted === text) return {
|
|
539
|
-
|
|
540
|
-
};
|
|
541
|
-
return {
|
|
542
|
-
action: "redact",
|
|
543
|
-
text: redacted,
|
|
544
|
-
reason: "PII detected and redacted"
|
|
545
|
-
};
|
|
444
|
+
if (redacted === text) return { action: "allow" };
|
|
445
|
+
return { action: "redact", text: redacted, reason: "PII detected and redacted" };
|
|
546
446
|
}
|
|
547
447
|
};
|
|
548
448
|
}
|
|
549
|
-
__name(piiDetector, "piiDetector");
|
|
550
449
|
var OBFUSCATION_CHARS = /[\u200B-\u200D\uFEFF\u202A-\u202E\u2066-\u2069]/g;
|
|
551
450
|
function unicodeNormalizer() {
|
|
552
451
|
return {
|
|
553
452
|
name: "unicode-normalizer",
|
|
554
453
|
checkInput(text) {
|
|
555
454
|
const cleaned = text.normalize("NFKC").replace(OBFUSCATION_CHARS, "");
|
|
556
|
-
if (cleaned === text) return {
|
|
557
|
-
|
|
558
|
-
};
|
|
559
|
-
return {
|
|
560
|
-
action: "redact",
|
|
561
|
-
text: cleaned,
|
|
562
|
-
reason: "obfuscation characters normalized"
|
|
563
|
-
};
|
|
455
|
+
if (cleaned === text) return { action: "allow" };
|
|
456
|
+
return { action: "redact", text: cleaned, reason: "obfuscation characters normalized" };
|
|
564
457
|
}
|
|
565
458
|
};
|
|
566
459
|
}
|
|
567
|
-
__name(unicodeNormalizer, "unicodeNormalizer");
|
|
568
460
|
function costGuard(options) {
|
|
569
461
|
let used = 0;
|
|
570
462
|
return {
|
|
@@ -576,28 +468,19 @@ function costGuard(options) {
|
|
|
576
468
|
if (used > options.maxTokens) {
|
|
577
469
|
return Promise.reject(new CostBudgetExceededError(used, options.maxTokens));
|
|
578
470
|
}
|
|
579
|
-
return Promise.resolve({
|
|
580
|
-
action: "allow"
|
|
581
|
-
});
|
|
471
|
+
return Promise.resolve({ action: "allow" });
|
|
582
472
|
}
|
|
583
473
|
};
|
|
584
474
|
}
|
|
585
|
-
__name(costGuard, "costGuard");
|
|
586
475
|
function outputModeration(options) {
|
|
587
476
|
return {
|
|
588
477
|
name: "output-moderation",
|
|
589
478
|
async checkOutput(text) {
|
|
590
479
|
const flagged = await options.moderate(text);
|
|
591
|
-
return flagged ? {
|
|
592
|
-
action: "block",
|
|
593
|
-
reason: "output flagged by moderation predicate"
|
|
594
|
-
} : {
|
|
595
|
-
action: "allow"
|
|
596
|
-
};
|
|
480
|
+
return flagged ? { action: "block", reason: "output flagged by moderation predicate" } : { action: "allow" };
|
|
597
481
|
}
|
|
598
482
|
};
|
|
599
483
|
}
|
|
600
|
-
__name(outputModeration, "outputModeration");
|
|
601
484
|
|
|
602
485
|
// src/guardrails/pipeline.ts
|
|
603
486
|
async function runInputGuards(text, guards) {
|
|
@@ -612,7 +495,6 @@ async function runInputGuards(text, guards) {
|
|
|
612
495
|
}
|
|
613
496
|
return current;
|
|
614
497
|
}
|
|
615
|
-
__name(runInputGuards, "runInputGuards");
|
|
616
498
|
async function runOutputGuards(text, guards) {
|
|
617
499
|
let current = text;
|
|
618
500
|
for (const g of guards) {
|
|
@@ -625,7 +507,6 @@ async function runOutputGuards(text, guards) {
|
|
|
625
507
|
}
|
|
626
508
|
return current;
|
|
627
509
|
}
|
|
628
|
-
__name(runOutputGuards, "runOutputGuards");
|
|
629
510
|
|
|
630
511
|
// src/guardrails/stream.ts
|
|
631
512
|
async function* moderateOutputStream(inner, guards, extractText) {
|
|
@@ -645,7 +526,6 @@ async function* moderateOutputStream(inner, guards, extractText) {
|
|
|
645
526
|
for (const event of buffered) yield event;
|
|
646
527
|
return step.value;
|
|
647
528
|
}
|
|
648
|
-
__name(moderateOutputStream, "moderateOutputStream");
|
|
649
529
|
|
|
650
530
|
// src/bridge/tool-hooks-plugin.ts
|
|
651
531
|
function createToolHooksPlugin(hooks) {
|
|
@@ -658,30 +538,22 @@ function createToolHooksPlugin(hooks) {
|
|
|
658
538
|
register(ctx) {
|
|
659
539
|
const { beforeToolCall, afterToolCall, beforeLLMCall, afterLLMCall, processInput } = hooks;
|
|
660
540
|
if (beforeToolCall) {
|
|
661
|
-
ctx.on("pre_tool_call", (c) => beforeToolCall({
|
|
662
|
-
name: c.name ?? "",
|
|
663
|
-
args: c.args ?? {}
|
|
664
|
-
}));
|
|
541
|
+
ctx.on("pre_tool_call", (c) => beforeToolCall({ name: c.name ?? "", args: c.args ?? {} }));
|
|
665
542
|
}
|
|
666
543
|
if (afterToolCall) {
|
|
667
|
-
ctx.on("post_tool_call", (c) => afterToolCall({
|
|
668
|
-
name: c.name ?? "",
|
|
669
|
-
result: c.result
|
|
670
|
-
}));
|
|
544
|
+
ctx.on("post_tool_call", (c) => afterToolCall({ name: c.name ?? "", result: c.result }));
|
|
671
545
|
}
|
|
672
546
|
if (beforeLLMCall) {
|
|
673
|
-
ctx.on(
|
|
674
|
-
|
|
675
|
-
runId: c.runId,
|
|
676
|
-
|
|
677
|
-
}));
|
|
547
|
+
ctx.on(
|
|
548
|
+
"pre_llm_call",
|
|
549
|
+
(c) => beforeLLMCall({ agentId: c.agentId, runId: c.runId, iteration: c.iteration })
|
|
550
|
+
);
|
|
678
551
|
}
|
|
679
552
|
if (afterLLMCall) {
|
|
680
|
-
ctx.on(
|
|
681
|
-
|
|
682
|
-
runId: c.runId,
|
|
683
|
-
|
|
684
|
-
}));
|
|
553
|
+
ctx.on(
|
|
554
|
+
"post_llm_call",
|
|
555
|
+
(c) => afterLLMCall({ agentId: c.agentId, runId: c.runId, iteration: c.iteration })
|
|
556
|
+
);
|
|
685
557
|
}
|
|
686
558
|
if (processInput) {
|
|
687
559
|
ctx.on("pre_user_send", async (c) => {
|
|
@@ -690,49 +562,30 @@ function createToolHooksPlugin(hooks) {
|
|
|
690
562
|
agentId: c.agentId,
|
|
691
563
|
runId: c.runId
|
|
692
564
|
});
|
|
693
|
-
return injected !== void 0 && injected.length > 0 ? {
|
|
694
|
-
recalledContext: injected
|
|
695
|
-
} : void 0;
|
|
565
|
+
return injected !== void 0 && injected.length > 0 ? { recalledContext: injected } : void 0;
|
|
696
566
|
});
|
|
697
567
|
}
|
|
698
568
|
}
|
|
699
569
|
};
|
|
700
570
|
}
|
|
701
|
-
__name(createToolHooksPlugin, "createToolHooksPlugin");
|
|
702
571
|
|
|
703
572
|
// src/bridge/model-selection.ts
|
|
704
573
|
var PARAM_THINKING = "thinking";
|
|
705
574
|
function buildModelSelection(model, effort) {
|
|
706
|
-
const base = typeof model === "string" ? {
|
|
707
|
-
id: model
|
|
708
|
-
} : {
|
|
709
|
-
...model
|
|
710
|
-
};
|
|
575
|
+
const base = typeof model === "string" ? { id: model } : { ...model };
|
|
711
576
|
if (!effort) return base;
|
|
712
|
-
return {
|
|
713
|
-
...base,
|
|
714
|
-
params: [
|
|
715
|
-
...base.params ?? [],
|
|
716
|
-
{
|
|
717
|
-
id: PARAM_THINKING,
|
|
718
|
-
value: effort
|
|
719
|
-
}
|
|
720
|
-
]
|
|
721
|
-
};
|
|
577
|
+
return { ...base, params: [...base.params ?? [], { id: PARAM_THINKING, value: effort }] };
|
|
722
578
|
}
|
|
723
|
-
__name(buildModelSelection, "buildModelSelection");
|
|
724
579
|
function reasoningEffortOf(model) {
|
|
725
580
|
const params = typeof model === "string" ? void 0 : model.params;
|
|
726
581
|
return params?.find((p) => p.id === PARAM_THINKING)?.value;
|
|
727
582
|
}
|
|
728
|
-
__name(reasoningEffortOf, "reasoningEffortOf");
|
|
729
583
|
|
|
730
584
|
// src/bridge/event-translator.ts
|
|
731
585
|
function asString(value, fallback) {
|
|
732
586
|
if (typeof value === "string") return value;
|
|
733
587
|
return fallback;
|
|
734
588
|
}
|
|
735
|
-
__name(asString, "asString");
|
|
736
589
|
function serializeToolOutput(value, fallback) {
|
|
737
590
|
if (typeof value === "string") return value;
|
|
738
591
|
if (value === void 0 || value === null) return fallback;
|
|
@@ -742,7 +595,6 @@ function serializeToolOutput(value, fallback) {
|
|
|
742
595
|
return typeof value === "bigint" ? value.toString() : fallback;
|
|
743
596
|
}
|
|
744
597
|
}
|
|
745
|
-
__name(serializeToolOutput, "serializeToolOutput");
|
|
746
598
|
function translateSystemEvent(msg, runId) {
|
|
747
599
|
return [
|
|
748
600
|
{
|
|
@@ -753,7 +605,6 @@ function translateSystemEvent(msg, runId) {
|
|
|
753
605
|
}
|
|
754
606
|
];
|
|
755
607
|
}
|
|
756
|
-
__name(translateSystemEvent, "translateSystemEvent");
|
|
757
608
|
function translateAssistantEvent(msg) {
|
|
758
609
|
const events = [];
|
|
759
610
|
const message = msg.message;
|
|
@@ -762,18 +613,15 @@ function translateAssistantEvent(msg) {
|
|
|
762
613
|
for (const block of content) {
|
|
763
614
|
const b = block;
|
|
764
615
|
if (b.type === "text" && b.text) {
|
|
765
|
-
events.push({
|
|
766
|
-
type: "text_delta",
|
|
767
|
-
content: b.text
|
|
768
|
-
});
|
|
616
|
+
events.push({ type: "text_delta", content: b.text });
|
|
769
617
|
}
|
|
770
618
|
if (b.type === "tool_use") {
|
|
771
619
|
events.push({
|
|
772
620
|
type: "tool_call",
|
|
773
|
-
// #138 —
|
|
774
|
-
//
|
|
775
|
-
//
|
|
776
|
-
//
|
|
621
|
+
// #138 — this was `tc-${Date.now()}`. A fresh id on every call is NEVER in the dedup set, so
|
|
622
|
+
// the fallback defeated dedup by construction — and still looked like a real id to a reader.
|
|
623
|
+
// An empty string is honest: `isDuplicatedByDelta` treats it as "I cannot identify this" and
|
|
624
|
+
// prefers a visible double render to a silent suppression.
|
|
777
625
|
callId: b.id ?? "",
|
|
778
626
|
toolName: b.name ?? "unknown",
|
|
779
627
|
input: b.input ?? {}
|
|
@@ -782,7 +630,6 @@ function translateAssistantEvent(msg) {
|
|
|
782
630
|
}
|
|
783
631
|
return events;
|
|
784
632
|
}
|
|
785
|
-
__name(translateAssistantEvent, "translateAssistantEvent");
|
|
786
633
|
function translateToolCallEvent(msg) {
|
|
787
634
|
const status = msg.status;
|
|
788
635
|
const callId = asString(msg.call_id, "");
|
|
@@ -813,17 +660,11 @@ function translateToolCallEvent(msg) {
|
|
|
813
660
|
}
|
|
814
661
|
if (status === "running") {
|
|
815
662
|
return [
|
|
816
|
-
{
|
|
817
|
-
type: "tool_call",
|
|
818
|
-
callId,
|
|
819
|
-
toolName,
|
|
820
|
-
input: msg.args ?? msg.input ?? msg.arguments ?? {}
|
|
821
|
-
}
|
|
663
|
+
{ type: "tool_call", callId, toolName, input: msg.args ?? msg.input ?? msg.arguments ?? {} }
|
|
822
664
|
];
|
|
823
665
|
}
|
|
824
666
|
return [];
|
|
825
667
|
}
|
|
826
|
-
__name(translateToolCallEvent, "translateToolCallEvent");
|
|
827
668
|
function translateStatusEvent(msg) {
|
|
828
669
|
const s = msg.status;
|
|
829
670
|
if (s === "FINISHED" || s === "CANCELLED") {
|
|
@@ -831,11 +672,7 @@ function translateStatusEvent(msg) {
|
|
|
831
672
|
{
|
|
832
673
|
type: "done",
|
|
833
674
|
result: "",
|
|
834
|
-
usage: {
|
|
835
|
-
inputTokens: 0,
|
|
836
|
-
outputTokens: 0,
|
|
837
|
-
totalTokens: 0
|
|
838
|
-
},
|
|
675
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
839
676
|
durationMs: 0,
|
|
840
677
|
cost: 0
|
|
841
678
|
}
|
|
@@ -853,18 +690,16 @@ function translateStatusEvent(msg) {
|
|
|
853
690
|
}
|
|
854
691
|
return [];
|
|
855
692
|
}
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
693
|
+
var alreadyWarned = /* @__PURE__ */ new Set();
|
|
694
|
+
function warnIfUnknown(type, deliberatelyIgnored) {
|
|
695
|
+
if (deliberatelyIgnored.has(type) || alreadyWarned.has(type)) return;
|
|
696
|
+
alreadyWarned.add(type);
|
|
697
|
+
console.warn(
|
|
698
|
+
`[theokit] agents.bridge: SDK event "${type}" is not translated and was discarded. If it carries information the UI needs, the translator needs a case for it (#141).`
|
|
699
|
+
);
|
|
862
700
|
}
|
|
863
|
-
|
|
864
|
-
var
|
|
865
|
-
"user"
|
|
866
|
-
]);
|
|
867
|
-
var INTERACTION_UPDATE_IGNORADOS = /* @__PURE__ */ new Set([
|
|
701
|
+
var SDK_MESSAGE_IGNORED = /* @__PURE__ */ new Set(["user"]);
|
|
702
|
+
var INTERACTION_UPDATE_IGNORED = /* @__PURE__ */ new Set([
|
|
868
703
|
"thinking-completed",
|
|
869
704
|
"token-delta",
|
|
870
705
|
"step-started",
|
|
@@ -879,21 +714,11 @@ function translateSdkEvent(msg, runId) {
|
|
|
879
714
|
case "tool_call":
|
|
880
715
|
return translateToolCallEvent(msg);
|
|
881
716
|
case "thinking":
|
|
882
|
-
return [
|
|
883
|
-
{
|
|
884
|
-
type: "thinking",
|
|
885
|
-
content: asString(msg.text, "")
|
|
886
|
-
}
|
|
887
|
-
];
|
|
717
|
+
return [{ type: "thinking", content: asString(msg.text, "") }];
|
|
888
718
|
case "status":
|
|
889
719
|
return translateStatusEvent(msg);
|
|
890
720
|
case "request":
|
|
891
|
-
return [
|
|
892
|
-
{
|
|
893
|
-
type: "input_requested",
|
|
894
|
-
requestId: asString(msg.request_id, "")
|
|
895
|
-
}
|
|
896
|
-
];
|
|
721
|
+
return [{ type: "input_requested", requestId: asString(msg.request_id, "") }];
|
|
897
722
|
case "task": {
|
|
898
723
|
const status = typeof msg.status === "string" ? msg.status : void 0;
|
|
899
724
|
const text = typeof msg.text === "string" ? msg.text : void 0;
|
|
@@ -901,37 +726,22 @@ function translateSdkEvent(msg, runId) {
|
|
|
901
726
|
return [
|
|
902
727
|
{
|
|
903
728
|
type: "task_progress",
|
|
904
|
-
...status !== void 0 ? {
|
|
905
|
-
|
|
906
|
-
} : {},
|
|
907
|
-
...text !== void 0 ? {
|
|
908
|
-
text
|
|
909
|
-
} : {}
|
|
729
|
+
...status !== void 0 ? { status } : {},
|
|
730
|
+
...text !== void 0 ? { text } : {}
|
|
910
731
|
}
|
|
911
732
|
];
|
|
912
733
|
}
|
|
913
734
|
default:
|
|
914
|
-
|
|
735
|
+
warnIfUnknown(msg.type, SDK_MESSAGE_IGNORED);
|
|
915
736
|
return [];
|
|
916
737
|
}
|
|
917
738
|
}
|
|
918
|
-
__name(translateSdkEvent, "translateSdkEvent");
|
|
919
739
|
function translateInteractionUpdate(update) {
|
|
920
740
|
switch (update.type) {
|
|
921
741
|
case "text-delta":
|
|
922
|
-
return update.text ? [
|
|
923
|
-
{
|
|
924
|
-
type: "text_delta",
|
|
925
|
-
content: update.text
|
|
926
|
-
}
|
|
927
|
-
] : [];
|
|
742
|
+
return update.text ? [{ type: "text_delta", content: update.text }] : [];
|
|
928
743
|
case "thinking-delta":
|
|
929
|
-
return update.text ? [
|
|
930
|
-
{
|
|
931
|
-
type: "thinking",
|
|
932
|
-
content: update.text
|
|
933
|
-
}
|
|
934
|
-
] : [];
|
|
744
|
+
return update.text ? [{ type: "thinking", content: update.text }] : [];
|
|
935
745
|
case "tool-call-started":
|
|
936
746
|
return [
|
|
937
747
|
{
|
|
@@ -962,18 +772,12 @@ function translateInteractionUpdate(update) {
|
|
|
962
772
|
}
|
|
963
773
|
];
|
|
964
774
|
case "shell-output-delta":
|
|
965
|
-
return [
|
|
966
|
-
{
|
|
967
|
-
type: "shell_output",
|
|
968
|
-
event: update.event
|
|
969
|
-
}
|
|
970
|
-
];
|
|
775
|
+
return [{ type: "shell_output", event: update.event }];
|
|
971
776
|
default:
|
|
972
|
-
|
|
777
|
+
warnIfUnknown(update.type, INTERACTION_UPDATE_IGNORED);
|
|
973
778
|
return [];
|
|
974
779
|
}
|
|
975
780
|
}
|
|
976
|
-
__name(translateInteractionUpdate, "translateInteractionUpdate");
|
|
977
781
|
|
|
978
782
|
// src/bridge/think-tag-extractor.ts
|
|
979
783
|
var TAG = "think";
|
|
@@ -986,11 +790,10 @@ function heldPrefixLength(s, delim) {
|
|
|
986
790
|
}
|
|
987
791
|
return 0;
|
|
988
792
|
}
|
|
989
|
-
__name(heldPrefixLength, "heldPrefixLength");
|
|
990
793
|
function createThinkTagExtractor() {
|
|
991
794
|
let mode = "text";
|
|
992
795
|
let buffer = "";
|
|
993
|
-
const write =
|
|
796
|
+
const write = (chunk) => {
|
|
994
797
|
buffer += chunk;
|
|
995
798
|
const out = [];
|
|
996
799
|
for (; ; ) {
|
|
@@ -998,52 +801,30 @@ function createThinkTagExtractor() {
|
|
|
998
801
|
const idx = buffer.indexOf(delim);
|
|
999
802
|
if (idx !== -1) {
|
|
1000
803
|
const content = buffer.slice(0, idx);
|
|
1001
|
-
if (content) out.push({
|
|
1002
|
-
kind: mode,
|
|
1003
|
-
content
|
|
1004
|
-
});
|
|
804
|
+
if (content) out.push({ kind: mode, content });
|
|
1005
805
|
buffer = buffer.slice(idx + delim.length);
|
|
1006
806
|
mode = mode === "text" ? "thinking" : "text";
|
|
1007
807
|
continue;
|
|
1008
808
|
}
|
|
1009
809
|
const keep = heldPrefixLength(buffer, delim);
|
|
1010
810
|
const emit = buffer.slice(0, buffer.length - keep);
|
|
1011
|
-
if (emit) out.push({
|
|
1012
|
-
kind: mode,
|
|
1013
|
-
content: emit
|
|
1014
|
-
});
|
|
811
|
+
if (emit) out.push({ kind: mode, content: emit });
|
|
1015
812
|
buffer = buffer.slice(buffer.length - keep);
|
|
1016
813
|
break;
|
|
1017
814
|
}
|
|
1018
815
|
return out;
|
|
1019
|
-
}
|
|
1020
|
-
const end =
|
|
816
|
+
};
|
|
817
|
+
const end = () => {
|
|
1021
818
|
if (!buffer) return [];
|
|
1022
|
-
const seg = {
|
|
1023
|
-
kind: mode,
|
|
1024
|
-
content: buffer
|
|
1025
|
-
};
|
|
819
|
+
const seg = { kind: mode, content: buffer };
|
|
1026
820
|
buffer = "";
|
|
1027
|
-
return [
|
|
1028
|
-
seg
|
|
1029
|
-
];
|
|
1030
|
-
}, "end");
|
|
1031
|
-
return {
|
|
1032
|
-
write,
|
|
1033
|
-
end
|
|
821
|
+
return [seg];
|
|
1034
822
|
};
|
|
823
|
+
return { write, end };
|
|
1035
824
|
}
|
|
1036
|
-
__name(createThinkTagExtractor, "createThinkTagExtractor");
|
|
1037
825
|
function segmentToEvent(seg) {
|
|
1038
|
-
return seg.kind === "thinking" ? {
|
|
1039
|
-
type: "thinking",
|
|
1040
|
-
content: seg.content
|
|
1041
|
-
} : {
|
|
1042
|
-
type: "text_delta",
|
|
1043
|
-
content: seg.content
|
|
1044
|
-
};
|
|
826
|
+
return seg.kind === "thinking" ? { type: "thinking", content: seg.content } : { type: "text_delta", content: seg.content };
|
|
1045
827
|
}
|
|
1046
|
-
__name(segmentToEvent, "segmentToEvent");
|
|
1047
828
|
async function* extractThinkTagStream(source) {
|
|
1048
829
|
const extractor = createThinkTagExtractor();
|
|
1049
830
|
try {
|
|
@@ -1058,7 +839,6 @@ async function* extractThinkTagStream(source) {
|
|
|
1058
839
|
for (const seg of extractor.end()) yield segmentToEvent(seg);
|
|
1059
840
|
}
|
|
1060
841
|
}
|
|
1061
|
-
__name(extractThinkTagStream, "extractThinkTagStream");
|
|
1062
842
|
|
|
1063
843
|
// src/debug-log.ts
|
|
1064
844
|
function debugLog(marker, data) {
|
|
@@ -1067,7 +847,6 @@ function debugLog(marker, data) {
|
|
|
1067
847
|
console.debug(marker, data);
|
|
1068
848
|
}
|
|
1069
849
|
}
|
|
1070
|
-
__name(debugLog, "debugLog");
|
|
1071
850
|
|
|
1072
851
|
// src/bridge/hitl-plugin.ts
|
|
1073
852
|
function createHitlPlugin(wiring) {
|
|
@@ -1091,96 +870,84 @@ function createHitlPlugin(wiring) {
|
|
|
1091
870
|
callbackUrl: `approve/${approvalId}`,
|
|
1092
871
|
timeoutMs: opts.timeout ?? 3e5,
|
|
1093
872
|
// M20 — carry the declared custom-payload schema so the UI knows what to collect.
|
|
1094
|
-
...opts.payloadSchema !== void 0 ? {
|
|
1095
|
-
payloadSchema: opts.payloadSchema
|
|
1096
|
-
} : {}
|
|
873
|
+
...opts.payloadSchema !== void 0 ? { payloadSchema: opts.payloadSchema } : {}
|
|
1097
874
|
});
|
|
1098
875
|
const raw = await wiring.awaitApproval(approvalId, opts, c.name);
|
|
1099
|
-
const decision = typeof raw === "boolean" ? {
|
|
1100
|
-
approved: raw
|
|
1101
|
-
} : raw;
|
|
876
|
+
const decision = typeof raw === "boolean" ? { approved: raw } : raw;
|
|
1102
877
|
if (decision.approved) return void 0;
|
|
1103
878
|
let message = `Tool '${c.name}' denied by human approver`;
|
|
1104
879
|
if (decision.reason) message += `: ${decision.reason}`;
|
|
1105
880
|
if (decision.payload !== void 0) {
|
|
1106
881
|
message += ` (payload: ${JSON.stringify(decision.payload)})`;
|
|
1107
882
|
}
|
|
1108
|
-
return {
|
|
1109
|
-
block: true,
|
|
1110
|
-
message
|
|
1111
|
-
};
|
|
883
|
+
return { block: true, message };
|
|
1112
884
|
});
|
|
1113
885
|
}
|
|
1114
886
|
};
|
|
1115
887
|
}
|
|
1116
|
-
__name(createHitlPlugin, "createHitlPlugin");
|
|
1117
888
|
|
|
1118
889
|
// src/bridge/approval-posture.ts
|
|
1119
|
-
function
|
|
1120
|
-
return
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
...daPostura
|
|
1133
|
-
];
|
|
890
|
+
function reasonOf(posturePolicy) {
|
|
891
|
+
return posturePolicy.kind === "interactive" ? "human approver on this surface" : posturePolicy.reason;
|
|
892
|
+
}
|
|
893
|
+
function applyPosture(extra, m8, posturePolicy, gated) {
|
|
894
|
+
const ofThePosture = posturePlugins(posturePolicy, gated);
|
|
895
|
+
if (ofThePosture.length === 0) return;
|
|
896
|
+
const currentOnes = extra.plugins ?? m8.plugins;
|
|
897
|
+
if (currentOnes !== void 0 && !Array.isArray(currentOnes)) {
|
|
898
|
+
throw new Error(
|
|
899
|
+
`[@theokit/agents] approval posture "${posturePolicy.kind}" needs to install a plugin, but \`plugins\` was supplied in the legacy object form, which cannot carry both. Pass \`plugins\` as an array so the approval gate is not dropped.`
|
|
900
|
+
);
|
|
901
|
+
}
|
|
902
|
+
extra.plugins = [...currentOnes ?? [], ...ofThePosture];
|
|
1134
903
|
}
|
|
1135
|
-
|
|
1136
|
-
function pluginsDaPostura(postura, gated) {
|
|
904
|
+
function posturePlugins(posturePolicy, gated) {
|
|
1137
905
|
debugLog("[theokit] approval posture", {
|
|
1138
|
-
kind:
|
|
1139
|
-
reason:
|
|
906
|
+
kind: posturePolicy.kind,
|
|
907
|
+
reason: reasonOf(posturePolicy)
|
|
1140
908
|
});
|
|
1141
909
|
if (gated === void 0 || gated.size === 0) return [];
|
|
1142
|
-
switch (
|
|
910
|
+
switch (posturePolicy.kind) {
|
|
1143
911
|
case "interactive":
|
|
1144
912
|
return [
|
|
1145
913
|
createHitlPlugin({
|
|
1146
914
|
gated,
|
|
1147
|
-
emit:
|
|
1148
|
-
awaitApproval:
|
|
915
|
+
emit: posturePolicy.emit,
|
|
916
|
+
awaitApproval: posturePolicy.awaitApproval
|
|
1149
917
|
})
|
|
1150
918
|
];
|
|
1151
919
|
case "auto-approve":
|
|
1152
920
|
return [
|
|
1153
921
|
createToolHooksPlugin({
|
|
1154
|
-
beforeToolCall:
|
|
922
|
+
beforeToolCall: (ctx) => {
|
|
1155
923
|
if (gated.has(ctx.name)) {
|
|
1156
924
|
debugLog("[theokit] gated tool auto-approved", {
|
|
1157
925
|
tool: ctx.name,
|
|
1158
|
-
reason:
|
|
926
|
+
reason: posturePolicy.reason
|
|
1159
927
|
});
|
|
1160
928
|
}
|
|
1161
929
|
return void 0;
|
|
1162
|
-
}
|
|
930
|
+
}
|
|
1163
931
|
})
|
|
1164
932
|
];
|
|
1165
933
|
case "auto-reject":
|
|
1166
934
|
return [
|
|
1167
935
|
createToolHooksPlugin({
|
|
1168
|
-
//
|
|
1169
|
-
//
|
|
1170
|
-
beforeToolCall:
|
|
936
|
+
// Only GATED tools are refused: the posture describes the gate, not a universal block.
|
|
937
|
+
// Refusing everything would break every agent with a free tool next to a gated one.
|
|
938
|
+
beforeToolCall: (ctx) => gated.has(ctx.name) ? {
|
|
1171
939
|
block: true,
|
|
1172
|
-
message: `Tool '${ctx.name}' requires human approval, and this surface has no approver (approval posture: auto-reject \u2014 ${
|
|
1173
|
-
} : void 0
|
|
940
|
+
message: `Tool '${ctx.name}' requires human approval, and this surface has no approver (approval posture: auto-reject \u2014 ${posturePolicy.reason}). Refused (fail-closed).`
|
|
941
|
+
} : void 0
|
|
1174
942
|
})
|
|
1175
943
|
];
|
|
1176
944
|
case "owned-by-surface":
|
|
1177
945
|
return [];
|
|
1178
946
|
}
|
|
1179
947
|
}
|
|
1180
|
-
__name(pluginsDaPostura, "pluginsDaPostura");
|
|
1181
948
|
|
|
1182
|
-
// src/bridge/
|
|
1183
|
-
function
|
|
949
|
+
// src/bridge/definition-or-thunk.ts
|
|
950
|
+
function project(def, overrides) {
|
|
1184
951
|
const compiled = compileAgentDefinition(def);
|
|
1185
952
|
return {
|
|
1186
953
|
compiled,
|
|
@@ -1189,29 +956,13 @@ function projetar(def, overrides) {
|
|
|
1189
956
|
runContext: overrides.runContext ?? compiled.runContext
|
|
1190
957
|
};
|
|
1191
958
|
}
|
|
1192
|
-
|
|
1193
|
-
function resolverProjecao(def, overrides) {
|
|
959
|
+
function resolveProjection(def, overrides) {
|
|
1194
960
|
if (typeof def === "function") {
|
|
1195
|
-
return async (sessionId) =>
|
|
961
|
+
return async (sessionId) => project(await def(sessionId), overrides);
|
|
1196
962
|
}
|
|
1197
|
-
const eager =
|
|
963
|
+
const eager = project(def, overrides);
|
|
1198
964
|
return () => Promise.resolve(eager);
|
|
1199
965
|
}
|
|
1200
|
-
__name(resolverProjecao, "resolverProjecao");
|
|
1201
|
-
|
|
1202
|
-
// src/bridge/erro-do-sdk.ts
|
|
1203
|
-
function eventoDeErroDoSdk(err) {
|
|
1204
|
-
const sdkErr = err;
|
|
1205
|
-
return {
|
|
1206
|
-
type: "error",
|
|
1207
|
-
code: sdkErr.code ?? "SDK_ERROR",
|
|
1208
|
-
message: err instanceof Error ? err.message : "SDK agent error",
|
|
1209
|
-
// O SDK computa `isRetryable` por classe de erro na construção; fixá-lo em `false` aqui
|
|
1210
|
-
// contradizia o próprio erro.
|
|
1211
|
-
retryable: sdkErr.isRetryable === true
|
|
1212
|
-
};
|
|
1213
|
-
}
|
|
1214
|
-
__name(eventoDeErroDoSdk, "eventoDeErroDoSdk");
|
|
1215
966
|
|
|
1216
967
|
// src/bridge/sdk-adapter-create-options.ts
|
|
1217
968
|
function assembleM8CreateOptions(compiled) {
|
|
@@ -1228,10 +979,7 @@ function assembleM8CreateOptions(compiled) {
|
|
|
1228
979
|
}
|
|
1229
980
|
const settingSources = resolveSettingSources(compiled);
|
|
1230
981
|
if (settingSources) {
|
|
1231
|
-
options.local = {
|
|
1232
|
-
...options.local,
|
|
1233
|
-
settingSources
|
|
1234
|
-
};
|
|
982
|
+
options.local = { ...options.local, settingSources };
|
|
1235
983
|
applied.push("settingSources");
|
|
1236
984
|
}
|
|
1237
985
|
if (compiled.context) {
|
|
@@ -1254,32 +1002,23 @@ function assembleM8CreateOptions(compiled) {
|
|
|
1254
1002
|
} else {
|
|
1255
1003
|
const dropped = Object.keys(compiled.memory);
|
|
1256
1004
|
if (dropped.length > 0) {
|
|
1257
|
-
process.stderr.write(
|
|
1258
|
-
`)
|
|
1005
|
+
process.stderr.write(
|
|
1006
|
+
`[theokit-agents] @Memory decorator options not yet mapped to the SDK (${dropped.join(", ")}) \u2014 memory enabled with defaults
|
|
1007
|
+
`
|
|
1008
|
+
);
|
|
1259
1009
|
}
|
|
1260
|
-
options.memory = {
|
|
1261
|
-
enabled: true
|
|
1262
|
-
};
|
|
1010
|
+
options.memory = { enabled: true };
|
|
1263
1011
|
}
|
|
1264
1012
|
applied.push("memory");
|
|
1265
1013
|
}
|
|
1266
|
-
return {
|
|
1267
|
-
options,
|
|
1268
|
-
applied
|
|
1269
|
-
};
|
|
1014
|
+
return { options, applied };
|
|
1270
1015
|
}
|
|
1271
|
-
__name(assembleM8CreateOptions, "assembleM8CreateOptions");
|
|
1272
1016
|
function resolveSettingSources(compiled) {
|
|
1273
1017
|
const explicit = compiled.settingSources;
|
|
1274
|
-
if (explicit && explicit.length > 0) return [
|
|
1275
|
-
|
|
1276
|
-
];
|
|
1277
|
-
if (compiled.skills) return [
|
|
1278
|
-
"project"
|
|
1279
|
-
];
|
|
1018
|
+
if (explicit && explicit.length > 0) return [...explicit];
|
|
1019
|
+
if (compiled.skills) return ["project"];
|
|
1280
1020
|
return void 0;
|
|
1281
1021
|
}
|
|
1282
|
-
__name(resolveSettingSources, "resolveSettingSources");
|
|
1283
1022
|
function realUsageDone(result, t0) {
|
|
1284
1023
|
const u = result.usage;
|
|
1285
1024
|
const inputTokens = u?.inputTokens ?? 0;
|
|
@@ -1301,7 +1040,19 @@ function realUsageDone(result, t0) {
|
|
|
1301
1040
|
cost: result.cost?.amount ?? 0
|
|
1302
1041
|
};
|
|
1303
1042
|
}
|
|
1304
|
-
|
|
1043
|
+
|
|
1044
|
+
// src/bridge/sdk-error.ts
|
|
1045
|
+
function sdkErrorEvent(err) {
|
|
1046
|
+
const sdkErr = err;
|
|
1047
|
+
return {
|
|
1048
|
+
type: "error",
|
|
1049
|
+
code: sdkErr.code ?? "SDK_ERROR",
|
|
1050
|
+
message: err instanceof Error ? err.message : "SDK agent error",
|
|
1051
|
+
// The SDK computes `isRetryable` per error class at construction; pinning it to `false` here
|
|
1052
|
+
// contradicted the error itself.
|
|
1053
|
+
retryable: sdkErr.isRetryable === true
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1305
1056
|
|
|
1306
1057
|
// src/bridge/sdk-timeline.ts
|
|
1307
1058
|
function idsOf(e, raw) {
|
|
@@ -1312,13 +1063,11 @@ function idsOf(e, raw) {
|
|
|
1312
1063
|
if (typeof model === "string" && model !== "" && model !== callId) ids.push(model);
|
|
1313
1064
|
return ids;
|
|
1314
1065
|
}
|
|
1315
|
-
__name(idsOf, "idsOf");
|
|
1316
1066
|
function bucketFor(e, seen) {
|
|
1317
1067
|
if (e.type === "tool_call") return seen.started;
|
|
1318
1068
|
if (e.type === "tool_result") return seen.completed;
|
|
1319
1069
|
return void 0;
|
|
1320
1070
|
}
|
|
1321
|
-
__name(bucketFor, "bucketFor");
|
|
1322
1071
|
function dedupeTools(events, raw, seen) {
|
|
1323
1072
|
return events.filter((e) => {
|
|
1324
1073
|
if (e.type === "thinking") {
|
|
@@ -1335,19 +1084,15 @@ function dedupeTools(events, raw, seen) {
|
|
|
1335
1084
|
return true;
|
|
1336
1085
|
});
|
|
1337
1086
|
}
|
|
1338
|
-
__name(dedupeTools, "dedupeTools");
|
|
1339
1087
|
function createToolSeen() {
|
|
1340
|
-
return {
|
|
1341
|
-
started: /* @__PURE__ */ new Set(),
|
|
1342
|
-
completed: /* @__PURE__ */ new Set(),
|
|
1343
|
-
sawThinkingDelta: false
|
|
1344
|
-
};
|
|
1088
|
+
return { started: /* @__PURE__ */ new Set(), completed: /* @__PURE__ */ new Set(), sawThinkingDelta: false };
|
|
1345
1089
|
}
|
|
1346
|
-
__name(createToolSeen, "createToolSeen");
|
|
1347
1090
|
function translateTimelineEvent(ev, runId, seen) {
|
|
1348
1091
|
if (ev.kind === "delta") {
|
|
1349
1092
|
if (ev.update === void 0) return [];
|
|
1350
|
-
const events2 = translateInteractionUpdate(
|
|
1093
|
+
const events2 = translateInteractionUpdate(
|
|
1094
|
+
ev.update
|
|
1095
|
+
);
|
|
1351
1096
|
return dedupeTools(events2, ev.update, seen);
|
|
1352
1097
|
}
|
|
1353
1098
|
if (ev.message === void 0) return [];
|
|
@@ -1355,7 +1100,6 @@ function translateTimelineEvent(ev, runId, seen) {
|
|
|
1355
1100
|
const kept = ev.textAlreadyStreamed === true ? events.filter((e) => e.type !== "text_delta") : events;
|
|
1356
1101
|
return dedupeTools(kept, ev.message, seen);
|
|
1357
1102
|
}
|
|
1358
|
-
__name(translateTimelineEvent, "translateTimelineEvent");
|
|
1359
1103
|
|
|
1360
1104
|
// src/bridge/tool-dialect-stripper.ts
|
|
1361
1105
|
var OPEN2 = "<function=";
|
|
@@ -1367,12 +1111,11 @@ function heldPrefixLength2(s, delim) {
|
|
|
1367
1111
|
}
|
|
1368
1112
|
return 0;
|
|
1369
1113
|
}
|
|
1370
|
-
__name(heldPrefixLength2, "heldPrefixLength");
|
|
1371
1114
|
function createToolDialectStripper() {
|
|
1372
1115
|
let mode = "text";
|
|
1373
1116
|
let buffer = "";
|
|
1374
1117
|
let pendingLeak = "";
|
|
1375
|
-
const write =
|
|
1118
|
+
const write = (chunk) => {
|
|
1376
1119
|
buffer += chunk;
|
|
1377
1120
|
const out = [];
|
|
1378
1121
|
for (; ; ) {
|
|
@@ -1380,10 +1123,7 @@ function createToolDialectStripper() {
|
|
|
1380
1123
|
const idx2 = buffer.indexOf(OPEN2);
|
|
1381
1124
|
if (idx2 !== -1) {
|
|
1382
1125
|
const content = buffer.slice(0, idx2);
|
|
1383
|
-
if (content) out.push({
|
|
1384
|
-
kind: "text",
|
|
1385
|
-
content
|
|
1386
|
-
});
|
|
1126
|
+
if (content) out.push({ kind: "text", content });
|
|
1387
1127
|
pendingLeak = OPEN2;
|
|
1388
1128
|
buffer = buffer.slice(idx2 + OPEN2.length);
|
|
1389
1129
|
mode = "stripping";
|
|
@@ -1391,10 +1131,7 @@ function createToolDialectStripper() {
|
|
|
1391
1131
|
}
|
|
1392
1132
|
const keep2 = heldPrefixLength2(buffer, OPEN2);
|
|
1393
1133
|
const emit = buffer.slice(0, buffer.length - keep2);
|
|
1394
|
-
if (emit) out.push({
|
|
1395
|
-
kind: "text",
|
|
1396
|
-
content: emit
|
|
1397
|
-
});
|
|
1134
|
+
if (emit) out.push({ kind: "text", content: emit });
|
|
1398
1135
|
buffer = buffer.slice(buffer.length - keep2);
|
|
1399
1136
|
break;
|
|
1400
1137
|
}
|
|
@@ -1411,34 +1148,22 @@ function createToolDialectStripper() {
|
|
|
1411
1148
|
break;
|
|
1412
1149
|
}
|
|
1413
1150
|
return out;
|
|
1414
|
-
}
|
|
1415
|
-
const end =
|
|
1151
|
+
};
|
|
1152
|
+
const end = () => {
|
|
1416
1153
|
const leftover = mode === "stripping" ? pendingLeak + buffer : buffer;
|
|
1417
1154
|
buffer = "";
|
|
1418
1155
|
pendingLeak = "";
|
|
1419
|
-
return leftover ? [
|
|
1420
|
-
{
|
|
1421
|
-
kind: "text",
|
|
1422
|
-
content: leftover
|
|
1423
|
-
}
|
|
1424
|
-
] : [];
|
|
1425
|
-
}, "end");
|
|
1426
|
-
return {
|
|
1427
|
-
write,
|
|
1428
|
-
end
|
|
1156
|
+
return leftover ? [{ kind: "text", content: leftover }] : [];
|
|
1429
1157
|
};
|
|
1158
|
+
return { write, end };
|
|
1430
1159
|
}
|
|
1431
|
-
__name(createToolDialectStripper, "createToolDialectStripper");
|
|
1432
1160
|
async function* stripToolDialectStream(source) {
|
|
1433
1161
|
const stripper = createToolDialectStripper();
|
|
1434
1162
|
try {
|
|
1435
1163
|
for await (const event of source) {
|
|
1436
1164
|
if (event.type === "text_delta" && typeof event.content === "string") {
|
|
1437
1165
|
for (const seg of stripper.write(event.content)) {
|
|
1438
|
-
yield {
|
|
1439
|
-
type: "text_delta",
|
|
1440
|
-
content: seg.content
|
|
1441
|
-
};
|
|
1166
|
+
yield { type: "text_delta", content: seg.content };
|
|
1442
1167
|
}
|
|
1443
1168
|
} else {
|
|
1444
1169
|
yield event;
|
|
@@ -1446,37 +1171,26 @@ async function* stripToolDialectStream(source) {
|
|
|
1446
1171
|
}
|
|
1447
1172
|
} finally {
|
|
1448
1173
|
for (const seg of stripper.end()) {
|
|
1449
|
-
yield {
|
|
1450
|
-
type: "text_delta",
|
|
1451
|
-
content: seg.content
|
|
1452
|
-
};
|
|
1174
|
+
yield { type: "text_delta", content: seg.content };
|
|
1453
1175
|
}
|
|
1454
1176
|
}
|
|
1455
1177
|
}
|
|
1456
|
-
__name(stripToolDialectStream, "stripToolDialectStream");
|
|
1457
1178
|
|
|
1458
1179
|
// src/bridge/sdk-adapter.ts
|
|
1459
1180
|
function withLeakedDialectRecovery(providers) {
|
|
1460
1181
|
return {
|
|
1461
1182
|
...providers,
|
|
1462
|
-
routes: providers.routes.map((route) => ({
|
|
1463
|
-
...route,
|
|
1464
|
-
extractToolCallsFromContent: true
|
|
1465
|
-
}))
|
|
1183
|
+
routes: providers.routes.map((route) => ({ ...route, extractToolCallsFromContent: true }))
|
|
1466
1184
|
};
|
|
1467
1185
|
}
|
|
1468
|
-
__name(withLeakedDialectRecovery, "withLeakedDialectRecovery");
|
|
1469
1186
|
function buildExtraCreateOptions(overrides, compiled) {
|
|
1470
1187
|
const recoverLeakedToolCalls = overrides.recoverLeakedToolCalls ?? compiled.recoverLeakedToolCalls ?? false;
|
|
1471
1188
|
const extra = {};
|
|
1472
1189
|
if (overrides.plugins !== void 0) {
|
|
1473
|
-
const asArray =
|
|
1190
|
+
const asArray = (v) => Array.isArray(v) ? v : void 0;
|
|
1474
1191
|
const overrideList = asArray(overrides.plugins);
|
|
1475
1192
|
const compiledList = asArray(compiled.plugins);
|
|
1476
|
-
extra.plugins = overrideList !== void 0 && compiledList !== void 0 ? [
|
|
1477
|
-
...compiledList,
|
|
1478
|
-
...overrideList
|
|
1479
|
-
] : overrides.plugins;
|
|
1193
|
+
extra.plugins = overrideList !== void 0 && compiledList !== void 0 ? [...compiledList, ...overrideList] : overrides.plugins;
|
|
1480
1194
|
}
|
|
1481
1195
|
if (overrides.providers !== void 0) {
|
|
1482
1196
|
extra.providers = recoverLeakedToolCalls ? withLeakedDialectRecovery(overrides.providers) : overrides.providers;
|
|
@@ -1485,7 +1199,6 @@ function buildExtraCreateOptions(overrides, compiled) {
|
|
|
1485
1199
|
if (overrides.budgetTracker !== void 0) extra.budgetTracker = overrides.budgetTracker;
|
|
1486
1200
|
return extra;
|
|
1487
1201
|
}
|
|
1488
|
-
__name(buildExtraCreateOptions, "buildExtraCreateOptions");
|
|
1489
1202
|
async function loadSdkRuntime() {
|
|
1490
1203
|
try {
|
|
1491
1204
|
const sdk = await import("@theokit/sdk");
|
|
@@ -1495,40 +1208,30 @@ async function loadSdkRuntime() {
|
|
|
1495
1208
|
// `.bind` keeps the static factory callable when detached from `sdk.Tool` (it takes no `this`,
|
|
1496
1209
|
// but binding is explicit + satisfies unbound-method rather than relying on that).
|
|
1497
1210
|
defineTool: sdk.Tool.create.bind(sdk.Tool),
|
|
1498
|
-
...skillReadTool ? {
|
|
1499
|
-
defineSkillReadTool: /* @__PURE__ */ __name((skills) => skillReadTool.create(skills), "defineSkillReadTool")
|
|
1500
|
-
} : {}
|
|
1211
|
+
...skillReadTool ? { defineSkillReadTool: (skills) => skillReadTool.create(skills) } : {}
|
|
1501
1212
|
};
|
|
1502
1213
|
} catch (err) {
|
|
1503
1214
|
console.warn("[theokit] @theokit/sdk import failed:", err);
|
|
1504
1215
|
return null;
|
|
1505
1216
|
}
|
|
1506
1217
|
}
|
|
1507
|
-
__name(loadSdkRuntime, "loadSdkRuntime");
|
|
1508
1218
|
function resolveTextTransformFlags(compiled, overrides) {
|
|
1509
1219
|
return {
|
|
1510
1220
|
parseThinkTags: overrides.parseThinkTags ?? compiled.parseThinkTags ?? false,
|
|
1511
1221
|
stripToolDialect: overrides.stripToolDialect ?? compiled.stripToolDialect ?? false
|
|
1512
1222
|
};
|
|
1513
1223
|
}
|
|
1514
|
-
__name(resolveTextTransformFlags, "resolveTextTransformFlags");
|
|
1515
1224
|
function applyTextTransforms(events, opts) {
|
|
1516
1225
|
let out = opts.parseThinkTags ? extractThinkTagStream(events) : events;
|
|
1517
1226
|
if (opts.stripToolDialect) out = stripToolDialectStream(out);
|
|
1518
1227
|
return out;
|
|
1519
1228
|
}
|
|
1520
|
-
__name(applyTextTransforms, "applyTextTransforms");
|
|
1521
1229
|
function hasZodInputSchema(schema) {
|
|
1522
1230
|
return typeof schema?.parse === "function";
|
|
1523
1231
|
}
|
|
1524
|
-
__name(hasZodInputSchema, "hasZodInputSchema");
|
|
1525
1232
|
function withRunContext(handler, runContext) {
|
|
1526
|
-
return (input, ctx) => handler(input, {
|
|
1527
|
-
...ctx,
|
|
1528
|
-
context: runContext
|
|
1529
|
-
});
|
|
1233
|
+
return (input, ctx) => handler(input, { ...ctx, context: runContext });
|
|
1530
1234
|
}
|
|
1531
|
-
__name(withRunContext, "withRunContext");
|
|
1532
1235
|
function buildSdkTools(compiledTools, defineTool, extraSdkTools = [], runContext) {
|
|
1533
1236
|
const has = runContext !== void 0;
|
|
1534
1237
|
return [
|
|
@@ -1541,25 +1244,20 @@ function buildSdkTools(compiledTools, defineTool, extraSdkTools = [], runContext
|
|
|
1541
1244
|
handler: has ? withRunContext(t.handler, runContext) : t.handler
|
|
1542
1245
|
});
|
|
1543
1246
|
}
|
|
1544
|
-
return has ? {
|
|
1545
|
-
...t,
|
|
1546
|
-
handler: withRunContext(t.handler, runContext)
|
|
1547
|
-
} : t;
|
|
1247
|
+
return has ? { ...t, handler: withRunContext(t.handler, runContext) } : t;
|
|
1548
1248
|
}),
|
|
1549
|
-
...extraSdkTools.map(
|
|
1550
|
-
...t,
|
|
1551
|
-
|
|
1552
|
-
} : t)
|
|
1249
|
+
...extraSdkTools.map(
|
|
1250
|
+
(t) => has ? { ...t, handler: withRunContext(t.handler, runContext) } : t
|
|
1251
|
+
)
|
|
1553
1252
|
];
|
|
1554
1253
|
}
|
|
1555
|
-
|
|
1556
|
-
var resolverApiKey = /* @__PURE__ */ __name(async (k) => typeof k === "function" ? await k() : k, "resolverApiKey");
|
|
1254
|
+
var resolverApiKey = async (k) => typeof k === "function" ? await k() : k;
|
|
1557
1255
|
function createSdkAgentStream(compiled, compiledTools, apiKey, overrides = {}) {
|
|
1558
1256
|
const model = overrides.model ?? compiled.model ?? "openai/gpt-4o-mini";
|
|
1559
1257
|
const reasoningEffort = overrides.reasoningEffort ?? compiled.reasoningEffort;
|
|
1560
1258
|
const { parseThinkTags, stripToolDialect } = resolveTextTransformFlags(compiled, overrides);
|
|
1561
1259
|
const runContext = overrides.runContext ?? compiled.runContext;
|
|
1562
|
-
const factory =
|
|
1260
|
+
const factory = (message, sessionId, factoryOpts) => ({
|
|
1563
1261
|
async *[Symbol.asyncIterator]() {
|
|
1564
1262
|
const runId = `run-${Date.now()}`;
|
|
1565
1263
|
const t0 = Date.now();
|
|
@@ -1605,27 +1303,30 @@ function createSdkAgentStream(compiled, compiledTools, apiKey, overrides = {}) {
|
|
|
1605
1303
|
t0
|
|
1606
1304
|
});
|
|
1607
1305
|
} catch (err) {
|
|
1608
|
-
yield
|
|
1306
|
+
yield sdkErrorEvent(err);
|
|
1609
1307
|
}
|
|
1610
1308
|
}
|
|
1611
|
-
}), "factory");
|
|
1612
|
-
return Object.assign(factory, {
|
|
1613
|
-
resolvedModel: model
|
|
1614
1309
|
});
|
|
1310
|
+
return Object.assign(factory, { resolvedModel: model });
|
|
1615
1311
|
}
|
|
1616
|
-
__name(createSdkAgentStream, "createSdkAgentStream");
|
|
1617
1312
|
async function* streamSdkAgent(rt, compiled, sdkTools, opts) {
|
|
1618
1313
|
const { Agent } = rt;
|
|
1619
|
-
const {
|
|
1314
|
+
const {
|
|
1315
|
+
apiKey,
|
|
1316
|
+
model,
|
|
1317
|
+
reasoningEffort,
|
|
1318
|
+
overrides,
|
|
1319
|
+
parseThinkTags,
|
|
1320
|
+
stripToolDialect,
|
|
1321
|
+
sessionId,
|
|
1322
|
+
message,
|
|
1323
|
+
factoryOpts,
|
|
1324
|
+
runId,
|
|
1325
|
+
t0
|
|
1326
|
+
} = opts;
|
|
1620
1327
|
const { options: m8, applied } = assembleM8CreateOptions(compiled);
|
|
1621
|
-
if (overrides.cwd !== void 0) m8.local = {
|
|
1622
|
-
|
|
1623
|
-
cwd: overrides.cwd
|
|
1624
|
-
};
|
|
1625
|
-
if (overrides.baseDir !== void 0) m8.local = {
|
|
1626
|
-
...m8.local,
|
|
1627
|
-
baseDir: overrides.baseDir
|
|
1628
|
-
};
|
|
1328
|
+
if (overrides.cwd !== void 0) m8.local = { ...m8.local, cwd: overrides.cwd };
|
|
1329
|
+
if (overrides.baseDir !== void 0) m8.local = { ...m8.local, baseDir: overrides.baseDir };
|
|
1629
1330
|
const extra = buildExtraCreateOptions(overrides, compiled);
|
|
1630
1331
|
if (applied.length > 0) {
|
|
1631
1332
|
debugLog("[THEO_AGENT_M8_RUNTIME_APPLIED]", {
|
|
@@ -1642,19 +1343,13 @@ async function* streamSdkAgent(rt, compiled, sdkTools, opts) {
|
|
|
1642
1343
|
...extra
|
|
1643
1344
|
});
|
|
1644
1345
|
try {
|
|
1645
|
-
const state = {
|
|
1646
|
-
sawError: false,
|
|
1647
|
-
lastEventType: ""
|
|
1648
|
-
};
|
|
1346
|
+
const state = { sawError: false, lastEventType: "" };
|
|
1649
1347
|
const sendOptions = {};
|
|
1650
1348
|
if (factoryOpts?.disableTools === true) sendOptions.toolChoice = "none";
|
|
1651
1349
|
if (overrides.onRunEvent !== void 0) sendOptions.onRunEvent = overrides.onRunEvent;
|
|
1652
|
-
const sendInput = overrides.images && overrides.images.length > 0 ? {
|
|
1653
|
-
text: message,
|
|
1654
|
-
images: overrides.images
|
|
1655
|
-
} : message;
|
|
1350
|
+
const sendInput = overrides.images && overrides.images.length > 0 ? { text: message, images: overrides.images } : message;
|
|
1656
1351
|
const sendPromise = agent.send(sendInput, sendOptions);
|
|
1657
|
-
const timeline =
|
|
1352
|
+
const timeline = async function* () {
|
|
1658
1353
|
const run = await sendPromise;
|
|
1659
1354
|
const seen = createToolSeen();
|
|
1660
1355
|
for await (const ev of run.events()) {
|
|
@@ -1665,7 +1360,7 @@ async function* streamSdkAgent(rt, compiled, sdkTools, opts) {
|
|
|
1665
1360
|
yield event;
|
|
1666
1361
|
}
|
|
1667
1362
|
}
|
|
1668
|
-
}
|
|
1363
|
+
};
|
|
1669
1364
|
for await (const event of applyTextTransforms(timeline(), {
|
|
1670
1365
|
parseThinkTags,
|
|
1671
1366
|
stripToolDialect
|
|
@@ -1677,7 +1372,7 @@ async function* streamSdkAgent(rt, compiled, sdkTools, opts) {
|
|
|
1677
1372
|
yield {
|
|
1678
1373
|
type: "error",
|
|
1679
1374
|
code: "RUN_FAILED",
|
|
1680
|
-
message: "
|
|
1375
|
+
message: "The turn ended with an error; see the earlier `error` event.",
|
|
1681
1376
|
retryable: false
|
|
1682
1377
|
};
|
|
1683
1378
|
}
|
|
@@ -1688,15 +1383,16 @@ async function* streamSdkAgent(rt, compiled, sdkTools, opts) {
|
|
|
1688
1383
|
await agent.dispose();
|
|
1689
1384
|
}
|
|
1690
1385
|
}
|
|
1691
|
-
__name(streamSdkAgent, "streamSdkAgent");
|
|
1692
1386
|
function toAgentFactory(def, opts) {
|
|
1693
1387
|
const overrides = opts.overrides ?? {};
|
|
1694
|
-
const
|
|
1388
|
+
const projectPerSession = resolveProjection(def, overrides);
|
|
1695
1389
|
return async (sessionId) => {
|
|
1696
|
-
const { compiled, model, reasoningEffort, runContext } = await
|
|
1390
|
+
const { compiled, model, reasoningEffort, runContext } = await projectPerSession(sessionId);
|
|
1697
1391
|
const rt = await loadSdkRuntime();
|
|
1698
1392
|
if (!rt) {
|
|
1699
|
-
throw new Error(
|
|
1393
|
+
throw new Error(
|
|
1394
|
+
"[@theokit/agents] @theokit/sdk is not installed \u2014 run: pnpm add @theokit/sdk"
|
|
1395
|
+
);
|
|
1700
1396
|
}
|
|
1701
1397
|
const sdkTools = buildSdkTools(compiled.tools, rt.defineTool, overrides.sdkTools, runContext);
|
|
1702
1398
|
const inlineSkills = compiled.skills?.inline;
|
|
@@ -1704,16 +1400,10 @@ function toAgentFactory(def, opts) {
|
|
|
1704
1400
|
sdkTools.push(rt.defineSkillReadTool(inlineSkills));
|
|
1705
1401
|
}
|
|
1706
1402
|
const { options: m8 } = assembleM8CreateOptions(compiled);
|
|
1707
|
-
if (overrides.cwd !== void 0) m8.local = {
|
|
1708
|
-
|
|
1709
|
-
cwd: overrides.cwd
|
|
1710
|
-
};
|
|
1711
|
-
if (overrides.baseDir !== void 0) m8.local = {
|
|
1712
|
-
...m8.local,
|
|
1713
|
-
baseDir: overrides.baseDir
|
|
1714
|
-
};
|
|
1403
|
+
if (overrides.cwd !== void 0) m8.local = { ...m8.local, cwd: overrides.cwd };
|
|
1404
|
+
if (overrides.baseDir !== void 0) m8.local = { ...m8.local, baseDir: overrides.baseDir };
|
|
1715
1405
|
const extra = buildExtraCreateOptions(overrides, compiled);
|
|
1716
|
-
|
|
1406
|
+
applyPosture(extra, m8, opts.approvals, compiled.hitl);
|
|
1717
1407
|
const agent = await rt.Agent.getOrCreate(sessionId, {
|
|
1718
1408
|
apiKey: await resolverApiKey(opts.apiKey),
|
|
1719
1409
|
model: buildModelSelection(model, reasoningEffort),
|
|
@@ -1724,53 +1414,37 @@ function toAgentFactory(def, opts) {
|
|
|
1724
1414
|
return withGuardrails(agent, compiled.guardrails);
|
|
1725
1415
|
};
|
|
1726
1416
|
}
|
|
1727
|
-
__name(toAgentFactory, "toAgentFactory");
|
|
1728
1417
|
function withGuardrails(handle, guardrails) {
|
|
1729
1418
|
if (guardrails === void 0 || guardrails.length === 0) return handle;
|
|
1730
1419
|
return {
|
|
1731
1420
|
get agentId() {
|
|
1732
1421
|
return handle.agentId;
|
|
1733
1422
|
},
|
|
1734
|
-
dispose:
|
|
1735
|
-
send:
|
|
1423
|
+
dispose: () => handle.dispose(),
|
|
1424
|
+
send: async (msg, sendOpts) => {
|
|
1736
1425
|
const guarded = await runInputGuards(msg, guardrails);
|
|
1737
1426
|
const turn = await handle.send(guarded, sendOpts);
|
|
1738
1427
|
return {
|
|
1739
|
-
wait:
|
|
1428
|
+
wait: async () => {
|
|
1740
1429
|
const out = await turn.wait();
|
|
1741
1430
|
if (out.result === void 0) return out;
|
|
1742
|
-
return {
|
|
1743
|
-
|
|
1744
|
-
result: await runOutputGuards(out.result, guardrails)
|
|
1745
|
-
};
|
|
1746
|
-
}, "wait")
|
|
1431
|
+
return { ...out, result: await runOutputGuards(out.result, guardrails) };
|
|
1432
|
+
}
|
|
1747
1433
|
};
|
|
1748
|
-
}
|
|
1434
|
+
}
|
|
1749
1435
|
};
|
|
1750
1436
|
}
|
|
1751
|
-
__name(withGuardrails, "withGuardrails");
|
|
1752
1437
|
|
|
1753
1438
|
// src/bridge/present-ui-message-stream.ts
|
|
1754
1439
|
import { UIMessageStreamPresenter } from "@theokit/presenter";
|
|
1755
1440
|
function toAgentOutputEvent(e) {
|
|
1756
1441
|
switch (e.type) {
|
|
1757
1442
|
case "text_delta":
|
|
1758
|
-
return {
|
|
1759
|
-
type: "text",
|
|
1760
|
-
text: e.content
|
|
1761
|
-
};
|
|
1443
|
+
return { type: "text", text: e.content };
|
|
1762
1444
|
case "thinking":
|
|
1763
|
-
return {
|
|
1764
|
-
type: "reasoning",
|
|
1765
|
-
text: e.content
|
|
1766
|
-
};
|
|
1445
|
+
return { type: "reasoning", text: e.content };
|
|
1767
1446
|
case "tool_call":
|
|
1768
|
-
return {
|
|
1769
|
-
type: "tool-call",
|
|
1770
|
-
callId: e.callId,
|
|
1771
|
-
name: e.toolName,
|
|
1772
|
-
input: e.input
|
|
1773
|
-
};
|
|
1447
|
+
return { type: "tool-call", callId: e.callId, name: e.toolName, input: e.input };
|
|
1774
1448
|
case "tool_result":
|
|
1775
1449
|
return {
|
|
1776
1450
|
type: "tool-result",
|
|
@@ -1783,40 +1457,20 @@ function toAgentOutputEvent(e) {
|
|
|
1783
1457
|
return null;
|
|
1784
1458
|
}
|
|
1785
1459
|
}
|
|
1786
|
-
__name(toAgentOutputEvent, "toAgentOutputEvent");
|
|
1787
1460
|
function doneToMetadata(event) {
|
|
1788
|
-
return event.cost === void 0 ? {
|
|
1789
|
-
usage: event.usage,
|
|
1790
|
-
durationMs: event.durationMs
|
|
1791
|
-
} : {
|
|
1792
|
-
usage: event.usage,
|
|
1793
|
-
durationMs: event.durationMs,
|
|
1794
|
-
cost: event.cost
|
|
1795
|
-
};
|
|
1461
|
+
return event.cost === void 0 ? { usage: event.usage, durationMs: event.durationMs } : { usage: event.usage, durationMs: event.durationMs, cost: event.cost };
|
|
1796
1462
|
}
|
|
1797
|
-
__name(doneToMetadata, "doneToMetadata");
|
|
1798
1463
|
var ERROR_CODE_DATA_PART = "data-error-code";
|
|
1799
1464
|
var INPUT_REQUESTED_DATA_PART = "data-input-requested";
|
|
1800
1465
|
var TASK_PROGRESS_DATA_PART = "data-task-progress";
|
|
1801
1466
|
var SHELL_OUTPUT_DATA_PART = "data-shell-output";
|
|
1802
1467
|
function dataPart(type, data) {
|
|
1803
|
-
return {
|
|
1804
|
-
type,
|
|
1805
|
-
data,
|
|
1806
|
-
transient: true
|
|
1807
|
-
};
|
|
1468
|
+
return { type, data, transient: true };
|
|
1808
1469
|
}
|
|
1809
|
-
__name(dataPart, "dataPart");
|
|
1810
1470
|
function* errorChunks(errorText, code) {
|
|
1811
|
-
if (code !== void 0) yield dataPart(ERROR_CODE_DATA_PART, {
|
|
1812
|
-
|
|
1813
|
-
});
|
|
1814
|
-
yield {
|
|
1815
|
-
type: "error",
|
|
1816
|
-
errorText
|
|
1817
|
-
};
|
|
1471
|
+
if (code !== void 0) yield dataPart(ERROR_CODE_DATA_PART, { code });
|
|
1472
|
+
yield { type: "error", errorText };
|
|
1818
1473
|
}
|
|
1819
|
-
__name(errorChunks, "errorChunks");
|
|
1820
1474
|
function diagnosticDataPart(event) {
|
|
1821
1475
|
switch (event.type) {
|
|
1822
1476
|
case "checkpoint_saved":
|
|
@@ -1829,34 +1483,21 @@ function diagnosticDataPart(event) {
|
|
|
1829
1483
|
// catch-all, which is the reported defect one layer down: translating an event and never
|
|
1830
1484
|
// presenting it leaves the consumer just as blind, minus even the warning.
|
|
1831
1485
|
case "input_requested":
|
|
1832
|
-
return dataPart(INPUT_REQUESTED_DATA_PART, {
|
|
1833
|
-
requestId: event.requestId
|
|
1834
|
-
});
|
|
1486
|
+
return dataPart(INPUT_REQUESTED_DATA_PART, { requestId: event.requestId });
|
|
1835
1487
|
case "task_progress":
|
|
1836
1488
|
return dataPart(TASK_PROGRESS_DATA_PART, {
|
|
1837
|
-
...event.status !== void 0 ? {
|
|
1838
|
-
|
|
1839
|
-
} : {},
|
|
1840
|
-
...event.text !== void 0 ? {
|
|
1841
|
-
text: event.text
|
|
1842
|
-
} : {}
|
|
1489
|
+
...event.status !== void 0 ? { status: event.status } : {},
|
|
1490
|
+
...event.text !== void 0 ? { text: event.text } : {}
|
|
1843
1491
|
});
|
|
1844
1492
|
case "shell_output":
|
|
1845
|
-
return dataPart(SHELL_OUTPUT_DATA_PART, {
|
|
1846
|
-
event: event.event
|
|
1847
|
-
});
|
|
1493
|
+
return dataPart(SHELL_OUTPUT_DATA_PART, { event: event.event });
|
|
1848
1494
|
default:
|
|
1849
1495
|
return null;
|
|
1850
1496
|
}
|
|
1851
1497
|
}
|
|
1852
|
-
__name(diagnosticDataPart, "diagnosticDataPart");
|
|
1853
1498
|
async function* presentUIMessageStream(events, opts) {
|
|
1854
|
-
const presenter = new UIMessageStreamPresenter({
|
|
1855
|
-
|
|
1856
|
-
});
|
|
1857
|
-
yield {
|
|
1858
|
-
type: "start"
|
|
1859
|
-
};
|
|
1499
|
+
const presenter = new UIMessageStreamPresenter({ textId: opts.textId });
|
|
1500
|
+
yield { type: "start" };
|
|
1860
1501
|
let turnMetadata;
|
|
1861
1502
|
try {
|
|
1862
1503
|
for await (const event of events) {
|
|
@@ -1877,11 +1518,7 @@ async function* presentUIMessageStream(events, opts) {
|
|
|
1877
1518
|
dynamic: true
|
|
1878
1519
|
};
|
|
1879
1520
|
}
|
|
1880
|
-
yield {
|
|
1881
|
-
type: "tool-approval-request",
|
|
1882
|
-
approvalId: event.callId,
|
|
1883
|
-
toolCallId: event.callId
|
|
1884
|
-
};
|
|
1521
|
+
yield { type: "tool-approval-request", approvalId: event.callId, toolCallId: event.callId };
|
|
1885
1522
|
continue;
|
|
1886
1523
|
}
|
|
1887
1524
|
const diagnostic = diagnosticDataPart(event);
|
|
@@ -1905,105 +1542,46 @@ async function* presentUIMessageStream(events, opts) {
|
|
|
1905
1542
|
}
|
|
1906
1543
|
yield* presenter.finish(turnMetadata);
|
|
1907
1544
|
}
|
|
1908
|
-
__name(presentUIMessageStream, "presentUIMessageStream");
|
|
1909
1545
|
|
|
1910
1546
|
// src/bridge/agent-builder.ts
|
|
1911
1547
|
var ContextualTool = {
|
|
1912
1548
|
/**
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1549
|
+
* Tag a {@link CustomTool} with a literal name (so `.tool()` can accumulate the tool-name union)
|
|
1550
|
+
* and, optionally, a required run-context type. The `requiredContext` argument is a type-only
|
|
1551
|
+
* witness — pass `undefined as C` or a sample value; it is never read at runtime.
|
|
1552
|
+
*/
|
|
1917
1553
|
of(tool, _requiredContext) {
|
|
1918
1554
|
return tool;
|
|
1919
1555
|
}
|
|
1920
1556
|
};
|
|
1921
1557
|
function makeBuilder(config) {
|
|
1922
1558
|
const runtime = {
|
|
1923
|
-
input:
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
context: value
|
|
1942
|
-
}), "context"),
|
|
1943
|
-
tool: /* @__PURE__ */ __name((tool) => makeBuilder({
|
|
1944
|
-
...config,
|
|
1945
|
-
tools: [
|
|
1946
|
-
...config.tools ?? [],
|
|
1947
|
-
tool
|
|
1948
|
-
]
|
|
1949
|
-
}), "tool"),
|
|
1950
|
-
guardrail: /* @__PURE__ */ __name((g) => makeBuilder({
|
|
1951
|
-
...config,
|
|
1952
|
-
guardrails: [
|
|
1953
|
-
...config.guardrails ?? [],
|
|
1954
|
-
g
|
|
1955
|
-
]
|
|
1956
|
-
}), "guardrail"),
|
|
1957
|
-
guardrails: /* @__PURE__ */ __name((gs) => makeBuilder({
|
|
1958
|
-
...config,
|
|
1959
|
-
guardrails: gs
|
|
1960
|
-
}), "guardrails"),
|
|
1961
|
-
approval: /* @__PURE__ */ __name((toolName, options) => makeBuilder({
|
|
1962
|
-
...config,
|
|
1963
|
-
approvals: {
|
|
1964
|
-
...config.approvals ?? {},
|
|
1965
|
-
[toolName]: options
|
|
1966
|
-
}
|
|
1967
|
-
}), "approval"),
|
|
1968
|
-
approvals: /* @__PURE__ */ __name((map) => makeBuilder({
|
|
1969
|
-
...config,
|
|
1970
|
-
approvals: map
|
|
1971
|
-
}), "approvals"),
|
|
1972
|
-
skills: /* @__PURE__ */ __name((selection) => makeBuilder({
|
|
1973
|
-
...config,
|
|
1974
|
-
skills: selection
|
|
1975
|
-
}), "skills"),
|
|
1976
|
-
settingSources: /* @__PURE__ */ __name((sources) => makeBuilder({
|
|
1977
|
-
...config,
|
|
1978
|
-
settingSources: sources
|
|
1979
|
-
}), "settingSources"),
|
|
1980
|
-
memory: /* @__PURE__ */ __name((settings) => makeBuilder({
|
|
1981
|
-
...config,
|
|
1982
|
-
memory: settings
|
|
1983
|
-
}), "memory"),
|
|
1984
|
-
hooks: /* @__PURE__ */ __name((map) => makeBuilder({
|
|
1985
|
-
...config,
|
|
1986
|
-
hooks: map
|
|
1987
|
-
}), "hooks"),
|
|
1988
|
-
plugins: /* @__PURE__ */ __name((list) => makeBuilder({
|
|
1989
|
-
...config,
|
|
1990
|
-
plugins: list
|
|
1991
|
-
}), "plugins"),
|
|
1992
|
-
mcp: /* @__PURE__ */ __name((servers) => makeBuilder({
|
|
1993
|
-
...config,
|
|
1994
|
-
mcpServers: servers
|
|
1995
|
-
}), "mcp"),
|
|
1996
|
-
use: /* @__PURE__ */ __name((preset) => preset(runtime), "use"),
|
|
1997
|
-
build: /* @__PURE__ */ __name(() => defineAgent(config), "build")
|
|
1559
|
+
input: (schema) => makeBuilder({ ...config, input: schema }),
|
|
1560
|
+
model: (id) => makeBuilder({ ...config, model: id }),
|
|
1561
|
+
system: (prompt) => makeBuilder({ ...config, system: prompt }),
|
|
1562
|
+
reasoningEffort: (effort) => makeBuilder({ ...config, reasoningEffort: effort }),
|
|
1563
|
+
context: (value) => makeBuilder({ ...config, context: value }),
|
|
1564
|
+
tool: (tool) => makeBuilder({ ...config, tools: [...config.tools ?? [], tool] }),
|
|
1565
|
+
guardrail: (g) => makeBuilder({ ...config, guardrails: [...config.guardrails ?? [], g] }),
|
|
1566
|
+
guardrails: (gs) => makeBuilder({ ...config, guardrails: gs }),
|
|
1567
|
+
approval: (toolName, options) => makeBuilder({ ...config, approvals: { ...config.approvals ?? {}, [toolName]: options } }),
|
|
1568
|
+
approvals: (map) => makeBuilder({ ...config, approvals: map }),
|
|
1569
|
+
skills: (selection) => makeBuilder({ ...config, skills: selection }),
|
|
1570
|
+
settingSources: (sources) => makeBuilder({ ...config, settingSources: sources }),
|
|
1571
|
+
memory: (settings) => makeBuilder({ ...config, memory: settings }),
|
|
1572
|
+
hooks: (map) => makeBuilder({ ...config, hooks: map }),
|
|
1573
|
+
plugins: (list) => makeBuilder({ ...config, plugins: list }),
|
|
1574
|
+
mcp: (servers) => makeBuilder({ ...config, mcpServers: servers }),
|
|
1575
|
+
use: (preset) => preset(runtime),
|
|
1576
|
+
build: () => defineAgent(config)
|
|
1998
1577
|
};
|
|
1999
1578
|
return runtime;
|
|
2000
1579
|
}
|
|
2001
|
-
__name(makeBuilder, "makeBuilder");
|
|
2002
1580
|
var AgentBuilder = {
|
|
2003
1581
|
/**
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
1582
|
+
* Start a fluent agent definition. Chain `.model()` (required) + `.context()` / `.system()` /
|
|
1583
|
+
* `.input()` / `.tool()` / `.use()`, then `.build()` to get the branded {@link AgentDefinition}.
|
|
1584
|
+
*/
|
|
2007
1585
|
create() {
|
|
2008
1586
|
return makeBuilder({});
|
|
2009
1587
|
}
|
|
@@ -2011,11 +1589,10 @@ var AgentBuilder = {
|
|
|
2011
1589
|
|
|
2012
1590
|
// src/bridge/agent-endpoint.ts
|
|
2013
1591
|
var AgentDefinitionError = class extends Error {
|
|
2014
|
-
static {
|
|
2015
|
-
__name(this, "AgentDefinitionError");
|
|
2016
|
-
}
|
|
2017
1592
|
constructor(source) {
|
|
2018
|
-
super(
|
|
1593
|
+
super(
|
|
1594
|
+
`[@theokit/agents] ${source}: an agents/ file must default-export a defineAgent(...) value or an @Agent-decorated class.`
|
|
1595
|
+
);
|
|
2019
1596
|
this.name = "AgentDefinitionError";
|
|
2020
1597
|
}
|
|
2021
1598
|
};
|
|
@@ -2025,13 +1602,11 @@ function extractDefaultExport(mod) {
|
|
|
2025
1602
|
}
|
|
2026
1603
|
return mod;
|
|
2027
1604
|
}
|
|
2028
|
-
__name(extractDefaultExport, "extractDefaultExport");
|
|
2029
1605
|
function isCompiledAgentOptions(value) {
|
|
2030
1606
|
if (typeof value !== "object" || value === null) return false;
|
|
2031
1607
|
const v = value;
|
|
2032
1608
|
return Array.isArray(v.tools) && typeof v.agents === "object" && v.agents !== null;
|
|
2033
1609
|
}
|
|
2034
|
-
__name(isCompiledAgentOptions, "isCompiledAgentOptions");
|
|
2035
1610
|
function compileAgentModule(mod, source = "agent module") {
|
|
2036
1611
|
const def = extractDefaultExport(mod);
|
|
2037
1612
|
if (isAgentDefinition(def)) {
|
|
@@ -2040,33 +1615,22 @@ function compileAgentModule(mod, source = "agent module") {
|
|
|
2040
1615
|
if (isCompiledAgentOptions(def)) return def;
|
|
2041
1616
|
throw new AgentDefinitionError(source);
|
|
2042
1617
|
}
|
|
2043
|
-
__name(compileAgentModule, "compileAgentModule");
|
|
2044
1618
|
async function* asAgentStream(events) {
|
|
2045
1619
|
for await (const e of events) yield e;
|
|
2046
1620
|
}
|
|
2047
|
-
|
|
2048
|
-
var EventQueue = class EventQueue2 {
|
|
2049
|
-
static {
|
|
2050
|
-
__name(this, "EventQueue");
|
|
2051
|
-
}
|
|
1621
|
+
var EventQueue = class {
|
|
2052
1622
|
#items = [];
|
|
2053
1623
|
#resolvers = [];
|
|
2054
1624
|
#closed = false;
|
|
2055
1625
|
push(item) {
|
|
2056
1626
|
if (this.#closed) return;
|
|
2057
1627
|
const r = this.#resolvers.shift();
|
|
2058
|
-
if (r) r({
|
|
2059
|
-
value: item,
|
|
2060
|
-
done: false
|
|
2061
|
-
});
|
|
1628
|
+
if (r) r({ value: item, done: false });
|
|
2062
1629
|
else this.#items.push(item);
|
|
2063
1630
|
}
|
|
2064
1631
|
close() {
|
|
2065
1632
|
this.#closed = true;
|
|
2066
|
-
for (const r of this.#resolvers.splice(0)) r({
|
|
2067
|
-
value: void 0,
|
|
2068
|
-
done: true
|
|
2069
|
-
});
|
|
1633
|
+
for (const r of this.#resolvers.splice(0)) r({ value: void 0, done: true });
|
|
2070
1634
|
}
|
|
2071
1635
|
async *drain() {
|
|
2072
1636
|
for (; ; ) {
|
|
@@ -2083,12 +1647,12 @@ var EventQueue = class EventQueue2 {
|
|
|
2083
1647
|
};
|
|
2084
1648
|
async function* appendCheckpointSaved(source, sessionId) {
|
|
2085
1649
|
let emitted = false;
|
|
2086
|
-
const checkpoint =
|
|
1650
|
+
const checkpoint = () => ({
|
|
2087
1651
|
type: "checkpoint_saved",
|
|
2088
1652
|
checkpointId: crypto.randomUUID(),
|
|
2089
1653
|
step: 0,
|
|
2090
1654
|
resumeToken: sessionId
|
|
2091
|
-
})
|
|
1655
|
+
});
|
|
2092
1656
|
for await (const ev of source) {
|
|
2093
1657
|
if (ev.type === "done" && !emitted) {
|
|
2094
1658
|
emitted = true;
|
|
@@ -2098,7 +1662,6 @@ async function* appendCheckpointSaved(source, sessionId) {
|
|
|
2098
1662
|
}
|
|
2099
1663
|
if (!emitted) yield checkpoint();
|
|
2100
1664
|
}
|
|
2101
|
-
__name(appendCheckpointSaved, "appendCheckpointSaved");
|
|
2102
1665
|
function streamAgentUIMessages(compiled, apiKey, input) {
|
|
2103
1666
|
const textId = crypto.randomUUID();
|
|
2104
1667
|
const overrides = {};
|
|
@@ -2108,29 +1671,34 @@ function streamAgentUIMessages(compiled, apiKey, input) {
|
|
|
2108
1671
|
if (input.onRunEvent !== void 0) overrides.onRunEvent = input.onRunEvent;
|
|
2109
1672
|
let source;
|
|
2110
1673
|
if (!input.hitl || input.hitl.gated.size === 0) {
|
|
2111
|
-
const events2 = createSdkAgentStream(
|
|
1674
|
+
const events2 = createSdkAgentStream(
|
|
1675
|
+
compiled,
|
|
1676
|
+
compiled.tools,
|
|
1677
|
+
apiKey,
|
|
1678
|
+
overrides
|
|
1679
|
+
)(input.message, input.sessionId);
|
|
2112
1680
|
source = asAgentStream(events2);
|
|
2113
1681
|
} else {
|
|
2114
1682
|
const queue = new EventQueue();
|
|
2115
|
-
input.signal?.addEventListener(
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
1683
|
+
input.signal?.addEventListener(
|
|
1684
|
+
"abort",
|
|
1685
|
+
() => {
|
|
1686
|
+
queue.close();
|
|
1687
|
+
},
|
|
1688
|
+
{ once: true }
|
|
1689
|
+
);
|
|
2120
1690
|
const plugin = createHitlPlugin({
|
|
2121
1691
|
gated: input.hitl.gated,
|
|
2122
|
-
emit:
|
|
1692
|
+
emit: (e) => {
|
|
2123
1693
|
queue.push(e);
|
|
2124
|
-
},
|
|
1694
|
+
},
|
|
2125
1695
|
awaitApproval: input.hitl.awaitApproval
|
|
2126
1696
|
});
|
|
2127
1697
|
const sdkStream = createSdkAgentStream(compiled, compiled.tools, apiKey, {
|
|
2128
1698
|
...overrides,
|
|
2129
1699
|
// The HITL plugin is a structural @theokit/sdk Plugin (createHitlPlugin returns the
|
|
2130
1700
|
// { name, register } shape); the RuntimeOverrides.plugins union is widened at the SDK edge.
|
|
2131
|
-
plugins: [
|
|
2132
|
-
plugin
|
|
2133
|
-
]
|
|
1701
|
+
plugins: [plugin]
|
|
2134
1702
|
})(input.message, input.sessionId);
|
|
2135
1703
|
void (async () => {
|
|
2136
1704
|
try {
|
|
@@ -2150,11 +1718,8 @@ function streamAgentUIMessages(compiled, apiKey, input) {
|
|
|
2150
1718
|
}
|
|
2151
1719
|
const durableCheckpoint = compiled.checkpoint?.storage === "filesystem";
|
|
2152
1720
|
const events = durableCheckpoint ? appendCheckpointSaved(source, input.sessionId) : source;
|
|
2153
|
-
return presentUIMessageStream(events, {
|
|
2154
|
-
textId
|
|
2155
|
-
});
|
|
1721
|
+
return presentUIMessageStream(events, { textId });
|
|
2156
1722
|
}
|
|
2157
|
-
__name(streamAgentUIMessages, "streamAgentUIMessages");
|
|
2158
1723
|
|
|
2159
1724
|
// src/loop/compaction-strategy.ts
|
|
2160
1725
|
import { compactTranscript } from "@theokit/sdk/compaction";
|
|
@@ -2165,73 +1730,56 @@ var compactionStrategyConfigSchema = z.object({
|
|
|
2165
1730
|
keepTokens: z.number().int().positive()
|
|
2166
1731
|
});
|
|
2167
1732
|
function resolveCompactionStrategy(name, config) {
|
|
2168
|
-
const cfg = compactionStrategyConfigSchema.parse({
|
|
2169
|
-
name,
|
|
2170
|
-
keepTokens: config.keepTokens
|
|
2171
|
-
});
|
|
1733
|
+
const cfg = compactionStrategyConfigSchema.parse({ name, keepTokens: config.keepTokens });
|
|
2172
1734
|
return {
|
|
2173
1735
|
name: cfg.name,
|
|
2174
1736
|
keepTokens: cfg.keepTokens,
|
|
2175
|
-
compact:
|
|
1737
|
+
compact: (messages, options) => compactTranscript(messages, {
|
|
2176
1738
|
keepTokens: options?.keepTokens ?? cfg.keepTokens,
|
|
2177
1739
|
summarize: options?.summarize,
|
|
2178
1740
|
marker: options?.marker,
|
|
2179
1741
|
summaryTemplate: options?.summaryTemplate,
|
|
2180
1742
|
// Default-safe: a thrown summarize keeps the transcript (app opts out via failSafe:false).
|
|
2181
1743
|
failSafe: options?.failSafe ?? true
|
|
2182
|
-
})
|
|
1744
|
+
})
|
|
2183
1745
|
};
|
|
2184
1746
|
}
|
|
2185
|
-
|
|
2186
|
-
var tokenBudgetCompactionStrategy = resolveCompactionStrategy("token-budget", {
|
|
2187
|
-
keepTokens: DEFAULT_KEEP_TOKENS
|
|
2188
|
-
});
|
|
1747
|
+
var tokenBudgetCompactionStrategy = resolveCompactionStrategy("token-budget", { keepTokens: DEFAULT_KEEP_TOKENS });
|
|
2189
1748
|
|
|
2190
1749
|
// src/loop/loop-strategy.ts
|
|
2191
1750
|
import { z as z2 } from "zod";
|
|
2192
1751
|
var DEFAULT_MAX_ITERATIONS = 8;
|
|
2193
1752
|
var maxIterationsSchema = z2.number().int().min(1);
|
|
2194
1753
|
var loopStrategyConfigSchema = z2.object({
|
|
2195
|
-
name: z2.enum([
|
|
2196
|
-
"simple-chat",
|
|
2197
|
-
"plan-act-reflect",
|
|
2198
|
-
"react"
|
|
2199
|
-
]),
|
|
1754
|
+
name: z2.enum(["simple-chat", "plan-act-reflect", "react"]),
|
|
2200
1755
|
maxIterations: maxIterationsSchema
|
|
2201
1756
|
});
|
|
2202
1757
|
function assertValidCustomLoopStrategy(strategy) {
|
|
2203
1758
|
const result = maxIterationsSchema.safeParse(strategy.maxIterations);
|
|
2204
1759
|
if (!result.success) {
|
|
2205
|
-
throw new Error(
|
|
1760
|
+
throw new Error(
|
|
1761
|
+
`loopStrategy: invalid maxIterations (${String(strategy.maxIterations)}) \u2014 must be a finite integer \u2265 1 (otherwise the round < maxIterations ceiling never terminates)`
|
|
1762
|
+
);
|
|
2206
1763
|
}
|
|
2207
1764
|
}
|
|
2208
|
-
__name(assertValidCustomLoopStrategy, "assertValidCustomLoopStrategy");
|
|
2209
1765
|
function resolveLoopStrategy(strategy, maxIterations = DEFAULT_MAX_ITERATIONS) {
|
|
2210
|
-
const cfg = loopStrategyConfigSchema.parse({
|
|
2211
|
-
name: strategy,
|
|
2212
|
-
maxIterations
|
|
2213
|
-
});
|
|
1766
|
+
const cfg = loopStrategyConfigSchema.parse({ name: strategy, maxIterations });
|
|
2214
1767
|
if (cfg.name === "simple-chat") {
|
|
2215
|
-
return {
|
|
2216
|
-
name: cfg.name,
|
|
2217
|
-
maxIterations: cfg.maxIterations,
|
|
2218
|
-
shouldContinue: /* @__PURE__ */ __name(() => false, "shouldContinue")
|
|
2219
|
-
};
|
|
1768
|
+
return { name: cfg.name, maxIterations: cfg.maxIterations, shouldContinue: () => false };
|
|
2220
1769
|
}
|
|
2221
1770
|
if (cfg.name === "plan-act-reflect") {
|
|
2222
1771
|
return {
|
|
2223
1772
|
name: cfg.name,
|
|
2224
1773
|
maxIterations: cfg.maxIterations,
|
|
2225
|
-
shouldContinue:
|
|
1774
|
+
shouldContinue: (outcome) => outcome.round < cfg.maxIterations
|
|
2226
1775
|
};
|
|
2227
1776
|
}
|
|
2228
1777
|
return {
|
|
2229
1778
|
name: cfg.name,
|
|
2230
1779
|
maxIterations: cfg.maxIterations,
|
|
2231
|
-
shouldContinue:
|
|
1780
|
+
shouldContinue: (outcome) => outcome.finishReason === "tool-calls" && outcome.round < cfg.maxIterations
|
|
2232
1781
|
};
|
|
2233
1782
|
}
|
|
2234
|
-
__name(resolveLoopStrategy, "resolveLoopStrategy");
|
|
2235
1783
|
|
|
2236
1784
|
// src/loop/reflection-strategy.ts
|
|
2237
1785
|
import { z as z3 } from "zod";
|
|
@@ -2247,55 +1795,52 @@ var ladderReflectionStrategy = {
|
|
|
2247
1795
|
continue: true
|
|
2248
1796
|
};
|
|
2249
1797
|
}
|
|
2250
|
-
return {
|
|
2251
|
-
continue: false
|
|
2252
|
-
};
|
|
1798
|
+
return { continue: false };
|
|
2253
1799
|
}
|
|
2254
1800
|
};
|
|
2255
1801
|
var noopReflectionStrategy = {
|
|
2256
1802
|
name: "noop",
|
|
2257
1803
|
reflect() {
|
|
2258
|
-
return {
|
|
2259
|
-
continue: true
|
|
2260
|
-
};
|
|
1804
|
+
return { continue: true };
|
|
2261
1805
|
}
|
|
2262
1806
|
};
|
|
2263
1807
|
|
|
2264
1808
|
// src/bridge/delegation-types.ts
|
|
2265
1809
|
var DelegationBudgetExceededError = class extends Error {
|
|
2266
|
-
|
|
2267
|
-
|
|
1810
|
+
constructor(agentName, actualCost, budgetLimit) {
|
|
1811
|
+
super(
|
|
1812
|
+
`Agent "${agentName}" exceeded budget: $${actualCost.toFixed(4)} > $${budgetLimit.toFixed(4)}`
|
|
1813
|
+
);
|
|
1814
|
+
this.agentName = agentName;
|
|
1815
|
+
this.actualCost = actualCost;
|
|
1816
|
+
this.budgetLimit = budgetLimit;
|
|
1817
|
+
this.name = "DelegationBudgetExceededError";
|
|
2268
1818
|
}
|
|
2269
1819
|
agentName;
|
|
2270
1820
|
actualCost;
|
|
2271
1821
|
budgetLimit;
|
|
2272
|
-
constructor(agentName, actualCost, budgetLimit) {
|
|
2273
|
-
super(`Agent "${agentName}" exceeded budget: $${actualCost.toFixed(4)} > $${budgetLimit.toFixed(4)}`), this.agentName = agentName, this.actualCost = actualCost, this.budgetLimit = budgetLimit;
|
|
2274
|
-
this.name = "DelegationBudgetExceededError";
|
|
2275
|
-
}
|
|
2276
1822
|
};
|
|
2277
1823
|
var BudgetExceededError = DelegationBudgetExceededError;
|
|
2278
1824
|
var DelegationError = class extends Error {
|
|
2279
|
-
static {
|
|
2280
|
-
__name(this, "DelegationError");
|
|
2281
|
-
}
|
|
2282
|
-
agentName;
|
|
2283
|
-
cause;
|
|
2284
1825
|
constructor(agentName, cause) {
|
|
2285
|
-
super(
|
|
1826
|
+
super(
|
|
1827
|
+
`Delegation to agent "${agentName}" failed: ${cause instanceof Error ? cause.message : String(cause)}`
|
|
1828
|
+
);
|
|
1829
|
+
this.agentName = agentName;
|
|
1830
|
+
this.cause = cause;
|
|
2286
1831
|
this.name = "DelegationError";
|
|
2287
1832
|
}
|
|
1833
|
+
agentName;
|
|
1834
|
+
cause;
|
|
2288
1835
|
};
|
|
2289
1836
|
|
|
2290
1837
|
// src/loop/run-reflective-loop.ts
|
|
2291
1838
|
function asString2(value, fallback) {
|
|
2292
1839
|
return typeof value === "string" ? value : fallback;
|
|
2293
1840
|
}
|
|
2294
|
-
__name(asString2, "asString");
|
|
2295
1841
|
function asNumber(value, fallback) {
|
|
2296
1842
|
return typeof value === "number" ? value : fallback;
|
|
2297
1843
|
}
|
|
2298
|
-
__name(asNumber, "asNumber");
|
|
2299
1844
|
var NO_PROGRESS_THRESHOLD = 2;
|
|
2300
1845
|
var MAINLOOP_METRIC = "[THEO_AGENT_MAINLOOP_RUNTIME_APPLIED]";
|
|
2301
1846
|
var TOOL_CALLS = "tool-calls";
|
|
@@ -2308,17 +1853,15 @@ function stableStringify(value) {
|
|
|
2308
1853
|
const entries = Object.keys(obj).sort((a, b) => a.localeCompare(b)).map((k) => `${JSON.stringify(k)}:${stableStringify(obj[k])}`);
|
|
2309
1854
|
return `{${entries.join(",")}}`;
|
|
2310
1855
|
}
|
|
2311
|
-
__name(stableStringify, "stableStringify");
|
|
2312
1856
|
function roundSignature(toolCalls) {
|
|
2313
1857
|
return toolCalls.map((tc) => `${tc.name}:${stableStringify(tc.input)}`).sort((a, b) => a.localeCompare(b)).join(",");
|
|
2314
1858
|
}
|
|
2315
|
-
__name(roundSignature, "roundSignature");
|
|
2316
1859
|
function terminalReason(reflectionContinue, roundReason, round, maxIterations) {
|
|
2317
|
-
if (reflectionContinue && roundReason === TOOL_CALLS && round >= maxIterations)
|
|
1860
|
+
if (reflectionContinue && roundReason === TOOL_CALLS && round >= maxIterations)
|
|
1861
|
+
return "step_limit";
|
|
2318
1862
|
if (roundReason === TOOL_CALLS) return "stop";
|
|
2319
1863
|
return roundReason;
|
|
2320
1864
|
}
|
|
2321
|
-
__name(terminalReason, "terminalReason");
|
|
2322
1865
|
var CONTINUE_PROMPT = "Continue from the prior turns above; finish the task and give a final answer.";
|
|
2323
1866
|
function buildPrompt(round, maxIterations, message, feedback) {
|
|
2324
1867
|
const hint = round === maxIterations ? `${STEP_LIMIT_HINT}
|
|
@@ -2328,16 +1871,20 @@ function buildPrompt(round, maxIterations, message, feedback) {
|
|
|
2328
1871
|
const body = round === 1 ? message : continuation;
|
|
2329
1872
|
return hint + body;
|
|
2330
1873
|
}
|
|
2331
|
-
__name(buildPrompt, "buildPrompt");
|
|
2332
1874
|
async function* consumeRoundOrThrow(inputs, agentName) {
|
|
2333
1875
|
try {
|
|
2334
|
-
return yield* consumeOneRound(
|
|
1876
|
+
return yield* consumeOneRound(
|
|
1877
|
+
inputs.factory,
|
|
1878
|
+
inputs.prompt,
|
|
1879
|
+
inputs.sessionId,
|
|
1880
|
+
inputs.signal,
|
|
1881
|
+
inputs.retry
|
|
1882
|
+
);
|
|
2335
1883
|
} catch (err) {
|
|
2336
1884
|
if (err instanceof DelegationBudgetExceededError || err instanceof DelegationError) throw err;
|
|
2337
1885
|
throw new DelegationError(agentName, err);
|
|
2338
1886
|
}
|
|
2339
1887
|
}
|
|
2340
|
-
__name(consumeRoundOrThrow, "consumeRoundOrThrow");
|
|
2341
1888
|
function accumulateUsage(acc, r) {
|
|
2342
1889
|
acc.cost += r.cost;
|
|
2343
1890
|
acc.tokens += r.tokens;
|
|
@@ -2347,25 +1894,18 @@ function accumulateUsage(acc, r) {
|
|
|
2347
1894
|
acc.cacheReadTokens = (acc.cacheReadTokens ?? 0) + r.cacheReadTokens;
|
|
2348
1895
|
acc.cacheWriteTokens = (acc.cacheWriteTokens ?? 0) + r.cacheWriteTokens;
|
|
2349
1896
|
}
|
|
2350
|
-
__name(accumulateUsage, "accumulateUsage");
|
|
2351
1897
|
function finalize(acc, round, reason, strategyName) {
|
|
2352
1898
|
acc.rounds = round;
|
|
2353
1899
|
acc.finishReason = reason;
|
|
2354
|
-
debugLog(MAINLOOP_METRIC, {
|
|
2355
|
-
strategy: strategyName,
|
|
2356
|
-
rounds: round,
|
|
2357
|
-
terminal: reason
|
|
2358
|
-
});
|
|
1900
|
+
debugLog(MAINLOOP_METRIC, { strategy: strategyName, rounds: round, terminal: reason });
|
|
2359
1901
|
return acc;
|
|
2360
1902
|
}
|
|
2361
|
-
__name(finalize, "finalize");
|
|
2362
1903
|
function deriveFinishReason(signals) {
|
|
2363
1904
|
if (signals.sawError) return "error";
|
|
2364
1905
|
if (signals.sawDone && signals.doneFinishReason === TOOL_CALLS) return TOOL_CALLS;
|
|
2365
1906
|
if (signals.sawToolResult) return TOOL_CALLS;
|
|
2366
1907
|
return "stop";
|
|
2367
1908
|
}
|
|
2368
|
-
__name(deriveFinishReason, "deriveFinishReason");
|
|
2369
1909
|
function pushToolResult(event, r, callInputs) {
|
|
2370
1910
|
const id = asString2(event.callId, "");
|
|
2371
1911
|
const call = callInputs.get(id);
|
|
@@ -2378,7 +1918,6 @@ function pushToolResult(event, r, callInputs) {
|
|
|
2378
1918
|
output: asString2(event.output, "")
|
|
2379
1919
|
});
|
|
2380
1920
|
}
|
|
2381
|
-
__name(pushToolResult, "pushToolResult");
|
|
2382
1921
|
function applyDone(event, r) {
|
|
2383
1922
|
r.cost = asNumber(event.cost, 0);
|
|
2384
1923
|
const usage = event.usage;
|
|
@@ -2389,7 +1928,6 @@ function applyDone(event, r) {
|
|
|
2389
1928
|
r.cacheReadTokens = usage?.cacheReadTokens ?? 0;
|
|
2390
1929
|
r.cacheWriteTokens = usage?.cacheWriteTokens ?? 0;
|
|
2391
1930
|
}
|
|
2392
|
-
__name(applyDone, "applyDone");
|
|
2393
1931
|
function accumulateEvent(event, r, signals, callInputs) {
|
|
2394
1932
|
if (event.type === "text_delta" && typeof event.content === "string") {
|
|
2395
1933
|
r.responseText += event.content;
|
|
@@ -2410,28 +1948,20 @@ function accumulateEvent(event, r, signals, callInputs) {
|
|
|
2410
1948
|
r.errorMessage = asString2(event.message, "Unknown agent error");
|
|
2411
1949
|
}
|
|
2412
1950
|
}
|
|
2413
|
-
__name(accumulateEvent, "accumulateEvent");
|
|
2414
1951
|
async function startRound(factory, prompt, sessionId, signal, retry) {
|
|
2415
|
-
const open =
|
|
1952
|
+
const open = async () => {
|
|
2416
1953
|
const it = factory(prompt, sessionId)[Symbol.asyncIterator]();
|
|
2417
1954
|
try {
|
|
2418
|
-
return {
|
|
2419
|
-
it,
|
|
2420
|
-
first: await it.next()
|
|
2421
|
-
};
|
|
1955
|
+
return { it, first: await it.next() };
|
|
2422
1956
|
} catch (err) {
|
|
2423
1957
|
await it.return?.(void 0);
|
|
2424
1958
|
throw err;
|
|
2425
1959
|
}
|
|
2426
|
-
}
|
|
1960
|
+
};
|
|
2427
1961
|
if (!retry) return open();
|
|
2428
1962
|
const { Retry } = await import("@theokit/sdk/retry");
|
|
2429
|
-
return Retry.create(open, {
|
|
2430
|
-
...retry,
|
|
2431
|
-
signal: retry.signal ?? signal
|
|
2432
|
-
});
|
|
1963
|
+
return Retry.create(open, { ...retry, signal: retry.signal ?? signal });
|
|
2433
1964
|
}
|
|
2434
|
-
__name(startRound, "startRound");
|
|
2435
1965
|
async function* consumeOneRound(factory, prompt, sessionId, signal, retry) {
|
|
2436
1966
|
const r = {
|
|
2437
1967
|
responseText: "",
|
|
@@ -2467,16 +1997,19 @@ async function* consumeOneRound(factory, prompt, sessionId, signal, retry) {
|
|
|
2467
1997
|
r.finishReason = deriveFinishReason(signals);
|
|
2468
1998
|
return r;
|
|
2469
1999
|
}
|
|
2470
|
-
__name(consumeOneRound, "consumeOneRound");
|
|
2471
2000
|
function ceilingRoundFactory(factory, round, maxIterations) {
|
|
2472
2001
|
if (round !== maxIterations) return factory;
|
|
2473
|
-
return (m, s) => factory(m, s, {
|
|
2474
|
-
disableTools: true
|
|
2475
|
-
});
|
|
2002
|
+
return (m, s) => factory(m, s, { disableTools: true });
|
|
2476
2003
|
}
|
|
2477
|
-
__name(ceilingRoundFactory, "ceilingRoundFactory");
|
|
2478
2004
|
async function* runReflectiveLoopStream(factory, message, sessionId, config) {
|
|
2479
|
-
const {
|
|
2005
|
+
const {
|
|
2006
|
+
loop,
|
|
2007
|
+
reflection,
|
|
2008
|
+
budget = Number.POSITIVE_INFINITY,
|
|
2009
|
+
signal,
|
|
2010
|
+
agentName = loop.name,
|
|
2011
|
+
retry
|
|
2012
|
+
} = config;
|
|
2480
2013
|
const acc = {
|
|
2481
2014
|
response: "",
|
|
2482
2015
|
toolCalls: [],
|
|
@@ -2497,13 +2030,10 @@ async function* runReflectiveLoopStream(factory, message, sessionId, config) {
|
|
|
2497
2030
|
while (!signal?.aborted) {
|
|
2498
2031
|
const prompt = buildPrompt(round, loop.maxIterations, message, feedback);
|
|
2499
2032
|
const roundFactory = ceilingRoundFactory(factory, round, loop.maxIterations);
|
|
2500
|
-
const r = yield* consumeRoundOrThrow(
|
|
2501
|
-
factory: roundFactory,
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
signal,
|
|
2505
|
-
retry
|
|
2506
|
-
}, agentName);
|
|
2033
|
+
const r = yield* consumeRoundOrThrow(
|
|
2034
|
+
{ factory: roundFactory, prompt, sessionId, signal, retry },
|
|
2035
|
+
agentName
|
|
2036
|
+
);
|
|
2507
2037
|
acc.response += r.responseText;
|
|
2508
2038
|
acc.toolCalls.push(...r.toolCalls);
|
|
2509
2039
|
accumulateUsage(acc, r);
|
|
@@ -2525,7 +2055,12 @@ async function* runReflectiveLoopStream(factory, message, sessionId, config) {
|
|
|
2525
2055
|
};
|
|
2526
2056
|
const reflectionResult = reflection.reflect(outcome, reflectionContext);
|
|
2527
2057
|
if (!(reflectionResult.continue && loop.shouldContinue(outcome) && round < loop.maxIterations)) {
|
|
2528
|
-
const reason = terminalReason(
|
|
2058
|
+
const reason = terminalReason(
|
|
2059
|
+
reflectionResult.continue,
|
|
2060
|
+
r.finishReason,
|
|
2061
|
+
round,
|
|
2062
|
+
loop.maxIterations
|
|
2063
|
+
);
|
|
2529
2064
|
return finalize(acc, round, reason, loop.name);
|
|
2530
2065
|
}
|
|
2531
2066
|
feedback = reflectionResult.feedback;
|
|
@@ -2534,20 +2069,15 @@ async function* runReflectiveLoopStream(factory, message, sessionId, config) {
|
|
|
2534
2069
|
acc.rounds = round - 1;
|
|
2535
2070
|
return acc;
|
|
2536
2071
|
}
|
|
2537
|
-
__name(runReflectiveLoopStream, "runReflectiveLoopStream");
|
|
2538
2072
|
async function runReflectiveLoop(factory, message, sessionId, config) {
|
|
2539
2073
|
const gen = runReflectiveLoopStream(factory, message, sessionId, config);
|
|
2540
2074
|
let res = await gen.next();
|
|
2541
2075
|
while (!res.done) res = await gen.next();
|
|
2542
2076
|
return res.value;
|
|
2543
2077
|
}
|
|
2544
|
-
__name(runReflectiveLoop, "runReflectiveLoop");
|
|
2545
2078
|
|
|
2546
2079
|
// src/loop/agent-runner.ts
|
|
2547
2080
|
var AgentRunner = class {
|
|
2548
|
-
static {
|
|
2549
|
-
__name(this, "AgentRunner");
|
|
2550
|
-
}
|
|
2551
2081
|
compiled;
|
|
2552
2082
|
agentName;
|
|
2553
2083
|
/** The resolved terminal-decision strategy (parity with `delegate()`). */
|
|
@@ -2557,18 +2087,18 @@ var AgentRunner = class {
|
|
|
2557
2087
|
/** The resolved between-round reflection (default or `.reflection(custom)` override). */
|
|
2558
2088
|
reflectionStrategy;
|
|
2559
2089
|
/**
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2090
|
+
* Recorded streaming preference. The reflective loop currently always streams via
|
|
2091
|
+
* the SDK `Run.stream()`; a non-streaming collect mode is future work — the flag is
|
|
2092
|
+
* captured + exposed here, not yet branched on (honest per G10: documented, not a
|
|
2093
|
+
* silent no-op).
|
|
2094
|
+
*/
|
|
2565
2095
|
streamEnabled;
|
|
2566
2096
|
/**
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2097
|
+
* V4-F: the resolved compaction strategy (from `@Compaction` or `.compaction()`),
|
|
2098
|
+
* or `undefined` when neither is declared — compaction is opt-in (EC-4). CALLABLE
|
|
2099
|
+
* by the app (ADR D1: `runner.compaction?.compact(messages, { summarize })`); the
|
|
2100
|
+
* reflective loop does NOT auto-invoke it (the SDK owns per-turn context).
|
|
2101
|
+
*/
|
|
2572
2102
|
compaction;
|
|
2573
2103
|
constructor(state) {
|
|
2574
2104
|
this.compiled = state.compiled;
|
|
@@ -2584,35 +2114,41 @@ var AgentRunner = class {
|
|
|
2584
2114
|
return new AgentRunnerBuilder(spec);
|
|
2585
2115
|
}
|
|
2586
2116
|
/**
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2117
|
+
* V4-D-stream: stream the agent's events LIVE across the reflective loop, returning
|
|
2118
|
+
* the aggregated {@link DelegationResult} as the generator's return value. This is the
|
|
2119
|
+
* on-ramp for streaming-first apps (SSE) — `runReflectiveLoopStream` yields every
|
|
2120
|
+
* round's events before the loop terminates. `streamEnabled` is honored: when the
|
|
2121
|
+
* builder set `.stream(false)`, callers should use {@link run} instead.
|
|
2122
|
+
*/
|
|
2593
2123
|
stream(message, opts) {
|
|
2594
2124
|
const guardrails = this.compiled.guardrails;
|
|
2595
2125
|
if (guardrails && guardrails.length > 0) {
|
|
2596
|
-
const runUnguarded =
|
|
2597
|
-
return (
|
|
2126
|
+
const runUnguarded = (m) => this.streamUnguarded(m, opts);
|
|
2127
|
+
return (async function* guarded() {
|
|
2598
2128
|
const safe = await runInputGuards(message, guardrails);
|
|
2599
|
-
return yield* moderateOutputStream(
|
|
2600
|
-
|
|
2129
|
+
return yield* moderateOutputStream(
|
|
2130
|
+
runUnguarded(safe),
|
|
2131
|
+
guardrails,
|
|
2132
|
+
(e) => e.type === "text_delta" && typeof e.content === "string" ? e.content : void 0
|
|
2133
|
+
);
|
|
2134
|
+
})();
|
|
2601
2135
|
}
|
|
2602
2136
|
return this.streamUnguarded(message, opts);
|
|
2603
2137
|
}
|
|
2604
2138
|
/** The core stream path, after input guardrails have run (M9). */
|
|
2605
2139
|
streamUnguarded(message, opts) {
|
|
2606
|
-
const tools = opts.tools ? [
|
|
2607
|
-
...opts.tools
|
|
2608
|
-
] : this.compiled.tools;
|
|
2140
|
+
const tools = opts.tools ? [...opts.tools] : this.compiled.tools;
|
|
2609
2141
|
const loop = this.resolvePerRunLoop(opts.maxIterations);
|
|
2610
2142
|
const streamFactory = opts.streamFactory ?? createSdkAgentStream(this.compiled, tools, opts.apiKey, {
|
|
2611
2143
|
model: opts.model,
|
|
2612
2144
|
reasoningEffort: opts.reasoningEffort,
|
|
2145
|
+
// M1: per-run extended-thinking effort
|
|
2613
2146
|
parseThinkTags: opts.parseThinkTags,
|
|
2147
|
+
// M2: per-run <think>-tag extraction opt-in
|
|
2614
2148
|
stripToolDialect: opts.stripToolDialect,
|
|
2149
|
+
// theocode#32: per-run tool-dialect strip opt-in
|
|
2615
2150
|
recoverLeakedToolCalls: opts.recoverLeakedToolCalls,
|
|
2151
|
+
// theokit#58: per-run leaked-dialect recovery opt-in
|
|
2616
2152
|
cwd: opts.cwd,
|
|
2617
2153
|
baseDir: opts.baseDir,
|
|
2618
2154
|
plugins: opts.plugins,
|
|
@@ -2620,6 +2156,7 @@ var AgentRunner = class {
|
|
|
2620
2156
|
agents: opts.agents,
|
|
2621
2157
|
budgetTracker: opts.budgetTracker,
|
|
2622
2158
|
sdkTools: opts.sdkTools
|
|
2159
|
+
// V4-Q: pre-built SDK tools forwarded raw
|
|
2623
2160
|
});
|
|
2624
2161
|
const sessionId = opts.sessionId ?? `runner-${crypto.randomUUID()}`;
|
|
2625
2162
|
return runReflectiveLoopStream(streamFactory, message, sessionId, {
|
|
@@ -2629,16 +2166,17 @@ var AgentRunner = class {
|
|
|
2629
2166
|
agentName: this.agentName,
|
|
2630
2167
|
signal: opts.signal,
|
|
2631
2168
|
retry: opts.retry
|
|
2169
|
+
// V4-P: per-round transient retry (opt-in)
|
|
2632
2170
|
});
|
|
2633
2171
|
}
|
|
2634
2172
|
/** Run the agent to a terminal result via the shared reflective loop (collect mode). */
|
|
2635
2173
|
/**
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2174
|
+
* Apply a per-call `maxIterations` override (M54 D4). A custom strategy must NOT be re-resolved by
|
|
2175
|
+
* name — its name is outside the `z.enum`, which would throw — and its `shouldContinue` closure
|
|
2176
|
+
* must survive; since the runner enforces the ceiling via `round < loop.maxIterations` (T1.1),
|
|
2177
|
+
* overriding just that field bounds a custom without touching its logic. A built-in keeps the
|
|
2178
|
+
* by-name re-resolution (zod fail-loud on `< 1`) — unchanged, zero-behavior.
|
|
2179
|
+
*/
|
|
2642
2180
|
resolvePerRunLoop(maxIterations) {
|
|
2643
2181
|
if (maxIterations == null) return this.loopStrategy;
|
|
2644
2182
|
if (this.loopStrategyIsCustom) {
|
|
@@ -2657,40 +2195,37 @@ var AgentRunner = class {
|
|
|
2657
2195
|
}
|
|
2658
2196
|
};
|
|
2659
2197
|
var AgentRunnerBuilder = class {
|
|
2660
|
-
|
|
2661
|
-
|
|
2198
|
+
constructor(spec) {
|
|
2199
|
+
this.spec = spec;
|
|
2662
2200
|
}
|
|
2663
2201
|
spec;
|
|
2664
2202
|
reflectionOverride;
|
|
2665
2203
|
streamEnabled = true;
|
|
2666
2204
|
compactionOverride;
|
|
2667
2205
|
loopStrategyOverride;
|
|
2668
|
-
constructor(spec) {
|
|
2669
|
-
this.spec = spec;
|
|
2670
|
-
}
|
|
2671
2206
|
/** Override the default reflection strategy (OCP — plan Drawback #2). No arg ⇒ keep default. */
|
|
2672
2207
|
reflection(strategy) {
|
|
2673
2208
|
if (strategy) this.reflectionOverride = strategy;
|
|
2674
2209
|
return this;
|
|
2675
2210
|
}
|
|
2676
2211
|
/**
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2212
|
+
* M54 — inject a custom terminal-decision strategy (the fourth OCP axis, alongside
|
|
2213
|
+
* `.reflection()`/`.compaction()`/`streamFactory`). WINS over the strategy the spec's name would
|
|
2214
|
+
* resolve to, exactly as `.compaction()` outranks the spec. The runner caps ANY strategy at
|
|
2215
|
+
* `custom.maxIterations` (T1.1), so a `shouldContinue: () => true` still terminates — never an
|
|
2216
|
+
* infinite loop.
|
|
2217
|
+
*
|
|
2218
|
+
* @example
|
|
2219
|
+
* ```ts
|
|
2220
|
+
* // Stop as soon as the confidence in the last round crosses 0.9, else run to the ceiling.
|
|
2221
|
+
* const stopWhenConfident: LoopStrategy = {
|
|
2222
|
+
* name: 'confident',
|
|
2223
|
+
* maxIterations: 8,
|
|
2224
|
+
* shouldContinue: (o) => !o.responseText.includes('confidence: high'),
|
|
2225
|
+
* }
|
|
2226
|
+
* AgentRunner.fromSpec(spec).loopStrategy(stopWhenConfident).build()
|
|
2227
|
+
* ```
|
|
2228
|
+
*/
|
|
2694
2229
|
loopStrategy(custom) {
|
|
2695
2230
|
assertValidCustomLoopStrategy(custom);
|
|
2696
2231
|
this.loopStrategyOverride = custom;
|
|
@@ -2702,15 +2237,12 @@ var AgentRunnerBuilder = class {
|
|
|
2702
2237
|
return this;
|
|
2703
2238
|
}
|
|
2704
2239
|
/**
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2240
|
+
* V4-F: declare the compaction strategy (e.g. `.compaction('token-budget', { keepTokens: 8000 })`).
|
|
2241
|
+
* Resolved + validated at {@link build} (EC-5 — fail-fast there, not here). This builder
|
|
2242
|
+
* call WINS over a `@Compaction` decorator on the same agent (EC-1 — explicit override).
|
|
2243
|
+
*/
|
|
2709
2244
|
compaction(name, options = {}) {
|
|
2710
|
-
this.compactionOverride = {
|
|
2711
|
-
name,
|
|
2712
|
-
keepTokens: options.keepTokens
|
|
2713
|
-
};
|
|
2245
|
+
this.compactionOverride = { name, keepTokens: options.keepTokens };
|
|
2714
2246
|
return this;
|
|
2715
2247
|
}
|
|
2716
2248
|
/** Resolve strategies from the spec — the compile→execute boundary (no I/O). */
|
|
@@ -2721,9 +2253,7 @@ var AgentRunnerBuilder = class {
|
|
|
2721
2253
|
const loopStrategy = this.loopStrategyOverride ?? resolveLoopStrategy(strategy, spec.maxIterations);
|
|
2722
2254
|
const reflectionStrategy = this.reflectionOverride ?? (strategy === "plan-act-reflect" ? ladderReflectionStrategy : noopReflectionStrategy);
|
|
2723
2255
|
const compactionDecl = this.compactionOverride ?? spec.compaction;
|
|
2724
|
-
const compaction = compactionDecl ? resolveCompactionStrategy(compactionDecl.name, {
|
|
2725
|
-
keepTokens: compactionDecl.keepTokens
|
|
2726
|
-
}) : void 0;
|
|
2256
|
+
const compaction = compactionDecl ? resolveCompactionStrategy(compactionDecl.name, { keepTokens: compactionDecl.keepTokens }) : void 0;
|
|
2727
2257
|
return new AgentRunner({
|
|
2728
2258
|
compiled: spec.compiled,
|
|
2729
2259
|
agentName: spec.name,
|
|
@@ -2740,18 +2270,15 @@ var AgentRunnerBuilder = class {
|
|
|
2740
2270
|
import { runGoalLoop } from "@theokit/sdk";
|
|
2741
2271
|
import { JudgeCredentialError } from "@theokit/sdk";
|
|
2742
2272
|
var GoalRunner = class {
|
|
2743
|
-
static {
|
|
2744
|
-
__name(this, "GoalRunner");
|
|
2745
|
-
}
|
|
2746
|
-
agent;
|
|
2747
2273
|
constructor(agent) {
|
|
2748
2274
|
this.agent = agent;
|
|
2749
2275
|
}
|
|
2276
|
+
agent;
|
|
2750
2277
|
/**
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2278
|
+
* Drive `goal` to completion against the bound agent. Returns the SAME async generator `runGoalLoop`
|
|
2279
|
+
* returns — yielding `GoalEvent`s, resolving a `GoalResult`. `deps` (judge/clock overrides) threads
|
|
2280
|
+
* straight through; a test seam for the judge lives there, exactly as on the free function.
|
|
2281
|
+
*/
|
|
2755
2282
|
run(goal, options, deps) {
|
|
2756
2283
|
return runGoalLoop(this.agent, goal, options, deps);
|
|
2757
2284
|
}
|
|
@@ -2765,22 +2292,14 @@ function requireApiKey(opts, agentName) {
|
|
|
2765
2292
|
}
|
|
2766
2293
|
return apiKey;
|
|
2767
2294
|
}
|
|
2768
|
-
__name(requireApiKey, "requireApiKey");
|
|
2769
2295
|
function mergeTools(parentTools, subTools) {
|
|
2770
2296
|
const subToolNames = new Set(subTools.map((t) => t.name));
|
|
2771
2297
|
const inherited = parentTools.filter((t) => !subToolNames.has(t.name));
|
|
2772
|
-
return [
|
|
2773
|
-
...inherited,
|
|
2774
|
-
...subTools
|
|
2775
|
-
];
|
|
2298
|
+
return [...inherited, ...subTools];
|
|
2776
2299
|
}
|
|
2777
|
-
__name(mergeTools, "mergeTools");
|
|
2778
2300
|
async function delegate(spec, message, opts = {}) {
|
|
2779
2301
|
const apiKey = requireApiKey(opts, spec.name);
|
|
2780
|
-
const effectiveMessage = opts.onDelegationStart ? await opts.onDelegationStart({
|
|
2781
|
-
subAgent: spec.name,
|
|
2782
|
-
input: message
|
|
2783
|
-
}) : message;
|
|
2302
|
+
const effectiveMessage = opts.onDelegationStart ? await opts.onDelegationStart({ subAgent: spec.name, input: message }) : message;
|
|
2784
2303
|
const { compiled } = spec;
|
|
2785
2304
|
const allTools = mergeTools(opts.parentTools ?? [], compiled.tools);
|
|
2786
2305
|
const budget = Math.min(opts.budget ?? Infinity, opts.parentBudgetRemaining ?? Infinity);
|
|
@@ -2794,7 +2313,10 @@ async function delegate(spec, message, opts = {}) {
|
|
|
2794
2313
|
sdkTools: opts.sdkTools
|
|
2795
2314
|
});
|
|
2796
2315
|
const sessionId = opts.sessionId ?? `sub-${crypto.randomUUID()}`;
|
|
2797
|
-
const loopStrategy = resolveLoopStrategy(
|
|
2316
|
+
const loopStrategy = resolveLoopStrategy(
|
|
2317
|
+
spec.strategy ?? "simple-chat",
|
|
2318
|
+
opts.maxIterations ?? spec.maxIterations
|
|
2319
|
+
);
|
|
2798
2320
|
const reflection = opts.reflection ?? (loopStrategy.name === "plan-act-reflect" ? ladderReflectionStrategy : noopReflectionStrategy);
|
|
2799
2321
|
const result = await runReflectiveLoop(streamFactory, effectiveMessage, sessionId, {
|
|
2800
2322
|
loop: loopStrategy,
|
|
@@ -2803,16 +2325,13 @@ async function delegate(spec, message, opts = {}) {
|
|
|
2803
2325
|
agentName: spec.name,
|
|
2804
2326
|
signal: opts.signal,
|
|
2805
2327
|
retry: opts.retry
|
|
2328
|
+
// V4-T: per-round transient retry (V4-P) on the delegate path
|
|
2806
2329
|
});
|
|
2807
2330
|
if (opts.onDelegationComplete) {
|
|
2808
|
-
return await opts.onDelegationComplete({
|
|
2809
|
-
subAgent: spec.name,
|
|
2810
|
-
result
|
|
2811
|
-
});
|
|
2331
|
+
return await opts.onDelegationComplete({ subAgent: spec.name, result });
|
|
2812
2332
|
}
|
|
2813
2333
|
return result;
|
|
2814
2334
|
}
|
|
2815
|
-
__name(delegate, "delegate");
|
|
2816
2335
|
|
|
2817
2336
|
// src/bridge/api-error-handler.ts
|
|
2818
2337
|
var DEFAULT_MAX_ATTEMPTS = 3;
|
|
@@ -2824,10 +2343,7 @@ async function runWithApiErrorHandling(thunk, policy) {
|
|
|
2824
2343
|
try {
|
|
2825
2344
|
return await thunk();
|
|
2826
2345
|
} catch (error) {
|
|
2827
|
-
const decision = await policy.processApiError({
|
|
2828
|
-
error,
|
|
2829
|
-
attempt
|
|
2830
|
-
});
|
|
2346
|
+
const decision = await policy.processApiError({ error, attempt });
|
|
2831
2347
|
if (decision.retry && attempt < maxAttempts) continue;
|
|
2832
2348
|
if (!decision.retry && "fallback" in decision && decision.fallback !== void 0) {
|
|
2833
2349
|
return decision.fallback;
|
|
@@ -2836,11 +2352,9 @@ async function runWithApiErrorHandling(thunk, policy) {
|
|
|
2836
2352
|
}
|
|
2837
2353
|
}
|
|
2838
2354
|
}
|
|
2839
|
-
__name(runWithApiErrorHandling, "runWithApiErrorHandling");
|
|
2840
2355
|
function createApiErrorHandler(policy) {
|
|
2841
2356
|
return (thunk) => runWithApiErrorHandling(thunk, policy);
|
|
2842
2357
|
}
|
|
2843
|
-
__name(createApiErrorHandler, "createApiErrorHandler");
|
|
2844
2358
|
|
|
2845
2359
|
// src/bridge/delegation-scoring.ts
|
|
2846
2360
|
function delegateBackground(subAgent, message, opts = {}) {
|
|
@@ -2851,20 +2365,24 @@ function delegateBackground(subAgent, message, opts = {}) {
|
|
|
2851
2365
|
});
|
|
2852
2366
|
promise.catch(() => void 0);
|
|
2853
2367
|
return {
|
|
2854
|
-
wait:
|
|
2855
|
-
settled:
|
|
2368
|
+
wait: () => promise,
|
|
2369
|
+
settled: () => isSettled
|
|
2856
2370
|
};
|
|
2857
2371
|
}
|
|
2858
|
-
__name(delegateBackground, "delegateBackground");
|
|
2859
2372
|
var DEFAULT_MAX_ROUNDS = 3;
|
|
2860
2373
|
function defaultFeedbackTemplate(message, feedback) {
|
|
2861
2374
|
return `${message}
|
|
2862
2375
|
|
|
2863
2376
|
Feedback from the reviewer (address this): ${feedback}`;
|
|
2864
2377
|
}
|
|
2865
|
-
__name(defaultFeedbackTemplate, "defaultFeedbackTemplate");
|
|
2866
2378
|
async function delegateWithScoring(subAgent, message, opts) {
|
|
2867
|
-
const {
|
|
2379
|
+
const {
|
|
2380
|
+
scorer,
|
|
2381
|
+
maxRounds: maxRoundsOpt = DEFAULT_MAX_ROUNDS,
|
|
2382
|
+
delegateFn = delegate,
|
|
2383
|
+
feedbackTemplate = defaultFeedbackTemplate,
|
|
2384
|
+
...delegateOpts
|
|
2385
|
+
} = opts;
|
|
2868
2386
|
const maxRounds = Math.max(1, maxRoundsOpt);
|
|
2869
2387
|
const verdicts = [];
|
|
2870
2388
|
let currentMessage = message;
|
|
@@ -2875,12 +2393,7 @@ async function delegateWithScoring(subAgent, message, opts) {
|
|
|
2875
2393
|
const verdict = await scorer(result);
|
|
2876
2394
|
verdicts.push(verdict);
|
|
2877
2395
|
if (verdict.pass) {
|
|
2878
|
-
return {
|
|
2879
|
-
result,
|
|
2880
|
-
rounds: round,
|
|
2881
|
-
passed: true,
|
|
2882
|
-
verdicts
|
|
2883
|
-
};
|
|
2396
|
+
return { result, rounds: round, passed: true, verdicts };
|
|
2884
2397
|
}
|
|
2885
2398
|
if (verdict.feedback) currentMessage = feedbackTemplate(message, verdict.feedback);
|
|
2886
2399
|
}
|
|
@@ -2894,7 +2407,6 @@ async function delegateWithScoring(subAgent, message, opts) {
|
|
|
2894
2407
|
verdicts
|
|
2895
2408
|
};
|
|
2896
2409
|
}
|
|
2897
|
-
__name(delegateWithScoring, "delegateWithScoring");
|
|
2898
2410
|
|
|
2899
2411
|
// src/bridge/mcp-resolver.ts
|
|
2900
2412
|
async function resolveMcpServers(selection, ctx) {
|
|
@@ -2906,7 +2418,6 @@ async function resolveMcpServers(selection, ctx) {
|
|
|
2906
2418
|
}
|
|
2907
2419
|
return resolved;
|
|
2908
2420
|
}
|
|
2909
|
-
__name(resolveMcpServers, "resolveMcpServers");
|
|
2910
2421
|
function mcpRegistry(config) {
|
|
2911
2422
|
const registry = config.registry;
|
|
2912
2423
|
if (registry === "composio") {
|
|
@@ -2914,17 +2425,8 @@ function mcpRegistry(config) {
|
|
|
2914
2425
|
return {
|
|
2915
2426
|
composio: {
|
|
2916
2427
|
command: "npx",
|
|
2917
|
-
args: [
|
|
2918
|
-
|
|
2919
|
-
"@composio/mcp",
|
|
2920
|
-
...apps.length > 0 ? [
|
|
2921
|
-
"--apps",
|
|
2922
|
-
apps.join(",")
|
|
2923
|
-
] : []
|
|
2924
|
-
],
|
|
2925
|
-
env: {
|
|
2926
|
-
COMPOSIO_API_KEY: config.apiKey
|
|
2927
|
-
}
|
|
2428
|
+
args: ["-y", "@composio/mcp", ...apps.length > 0 ? ["--apps", apps.join(",")] : []],
|
|
2429
|
+
env: { COMPOSIO_API_KEY: config.apiKey }
|
|
2928
2430
|
}
|
|
2929
2431
|
};
|
|
2930
2432
|
}
|
|
@@ -2936,30 +2438,23 @@ function mcpRegistry(config) {
|
|
|
2936
2438
|
"-y",
|
|
2937
2439
|
"@mcp.run/cli",
|
|
2938
2440
|
"serve",
|
|
2939
|
-
...config.profile ? [
|
|
2940
|
-
"--profile",
|
|
2941
|
-
config.profile
|
|
2942
|
-
] : []
|
|
2441
|
+
...config.profile ? ["--profile", config.profile] : []
|
|
2943
2442
|
],
|
|
2944
|
-
env: {
|
|
2945
|
-
MCP_RUN_API_KEY: config.apiKey
|
|
2946
|
-
}
|
|
2443
|
+
env: { MCP_RUN_API_KEY: config.apiKey }
|
|
2947
2444
|
}
|
|
2948
2445
|
};
|
|
2949
2446
|
}
|
|
2950
|
-
throw new Error(
|
|
2447
|
+
throw new Error(
|
|
2448
|
+
`mcpRegistry: unknown registry ${JSON.stringify(registry)} (supported: 'composio', 'mcp.run').`
|
|
2449
|
+
);
|
|
2951
2450
|
}
|
|
2952
|
-
__name(mcpRegistry, "mcpRegistry");
|
|
2953
2451
|
function mcpToolApprovals(specs) {
|
|
2954
2452
|
const out = {};
|
|
2955
2453
|
for (const [tool, spec] of Object.entries(specs)) {
|
|
2956
|
-
out[tool] = typeof spec === "string" ? {
|
|
2957
|
-
question: spec
|
|
2958
|
-
} : spec;
|
|
2454
|
+
out[tool] = typeof spec === "string" ? { question: spec } : spec;
|
|
2959
2455
|
}
|
|
2960
2456
|
return out;
|
|
2961
2457
|
}
|
|
2962
|
-
__name(mcpToolApprovals, "mcpToolApprovals");
|
|
2963
2458
|
|
|
2964
2459
|
// src/bridge/mcp-file.ts
|
|
2965
2460
|
import { existsSync, readFileSync } from "fs";
|
|
@@ -2971,11 +2466,7 @@ function warningChannel(opts) {
|
|
|
2971
2466
|
`);
|
|
2972
2467
|
});
|
|
2973
2468
|
}
|
|
2974
|
-
__name(warningChannel, "warningChannel");
|
|
2975
2469
|
var McpFileError = class extends TheokitAgentError {
|
|
2976
|
-
static {
|
|
2977
|
-
__name(this, "McpFileError");
|
|
2978
|
-
}
|
|
2979
2470
|
name = "McpFileError";
|
|
2980
2471
|
constructor(message) {
|
|
2981
2472
|
super(`[@theokit/agents] ${message}`);
|
|
@@ -2989,17 +2480,16 @@ function loadMcpJson(cwd, opts = {}) {
|
|
|
2989
2480
|
try {
|
|
2990
2481
|
text = readFileSync(path, "utf8");
|
|
2991
2482
|
} catch (err) {
|
|
2992
|
-
throw new McpFileError(`failed to read ${path}: ${
|
|
2483
|
+
throw new McpFileError(`failed to read ${path}: ${describeIt(err)}`);
|
|
2993
2484
|
}
|
|
2994
2485
|
let parsed;
|
|
2995
2486
|
try {
|
|
2996
2487
|
parsed = JSON.parse(text);
|
|
2997
2488
|
} catch (err) {
|
|
2998
|
-
throw new McpFileError(`${path} is not valid JSON: ${
|
|
2489
|
+
throw new McpFileError(`${path} is not valid JSON: ${describeIt(err)}`);
|
|
2999
2490
|
}
|
|
3000
2491
|
return parseMcpJson(parsed, path, warningChannel(opts));
|
|
3001
2492
|
}
|
|
3002
|
-
__name(loadMcpJson, "loadMcpJson");
|
|
3003
2493
|
function parseMcpJson(raw, source, onWarn) {
|
|
3004
2494
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
3005
2495
|
throw new McpFileError(`${source}: root must be a JSON object with an "mcpServers" key.`);
|
|
@@ -3011,91 +2501,82 @@ function parseMcpJson(raw, source, onWarn) {
|
|
|
3011
2501
|
}
|
|
3012
2502
|
const out = {};
|
|
3013
2503
|
for (const [name, entryRaw] of Object.entries(serversRaw)) {
|
|
3014
|
-
const
|
|
3015
|
-
if (
|
|
3016
|
-
onWarn(`${source}: server "${name}"
|
|
2504
|
+
const reason = validateEntry(name, entryRaw);
|
|
2505
|
+
if (reason !== void 0) {
|
|
2506
|
+
onWarn(`${source}: server "${name}" ignored \u2014 ${reason}`);
|
|
3017
2507
|
continue;
|
|
3018
2508
|
}
|
|
3019
2509
|
out[name] = buildEntry(entryRaw);
|
|
3020
2510
|
}
|
|
3021
2511
|
return out;
|
|
3022
2512
|
}
|
|
3023
|
-
|
|
3024
|
-
function validarEntrada(name, entryRaw) {
|
|
2513
|
+
function validateEntry(name, entryRaw) {
|
|
3025
2514
|
if (typeof entryRaw !== "object" || entryRaw === null || Array.isArray(entryRaw)) {
|
|
3026
|
-
return "
|
|
2515
|
+
return "the entry must be an object.";
|
|
3027
2516
|
}
|
|
3028
2517
|
const entry = entryRaw;
|
|
3029
|
-
const
|
|
3030
|
-
const
|
|
3031
|
-
if (
|
|
3032
|
-
if (!
|
|
3033
|
-
return
|
|
3034
|
-
}
|
|
3035
|
-
|
|
3036
|
-
function validarStdio(entry) {
|
|
2518
|
+
const hasUrl = entry.url !== void 0;
|
|
2519
|
+
const hasCommand = entry.command !== void 0;
|
|
2520
|
+
if (hasUrl && hasCommand) return 'declares both "command" and "url" \u2014 pick one transport.';
|
|
2521
|
+
if (!hasUrl && !hasCommand) return 'requires "command" (stdio) or "url" (http/sse).';
|
|
2522
|
+
return hasUrl ? validateRemote(entry) : validateStdio(entry);
|
|
2523
|
+
}
|
|
2524
|
+
function validateStdio(entry) {
|
|
3037
2525
|
if (typeof entry.command !== "string" || entry.command.length === 0) {
|
|
3038
|
-
return '
|
|
3039
|
-
}
|
|
3040
|
-
if (entry.args !== void 0 && !isStringArray(entry.args))
|
|
3041
|
-
|
|
3042
|
-
if (entry.
|
|
2526
|
+
return 'field "command" must be a non-empty string.';
|
|
2527
|
+
}
|
|
2528
|
+
if (entry.args !== void 0 && !isStringArray(entry.args))
|
|
2529
|
+
return 'field "args" must be an array of strings.';
|
|
2530
|
+
if (entry.env !== void 0 && !isStringRecord(entry.env))
|
|
2531
|
+
return 'field "env" must be a map of strings.';
|
|
2532
|
+
if (entry.cwd !== void 0 && typeof entry.cwd !== "string")
|
|
2533
|
+
return 'field "cwd" must be a string.';
|
|
3043
2534
|
return void 0;
|
|
3044
2535
|
}
|
|
3045
|
-
|
|
3046
|
-
function validarRemoto(entry) {
|
|
2536
|
+
function validateRemote(entry) {
|
|
3047
2537
|
if (typeof entry.url !== "string" || entry.url.length === 0) {
|
|
3048
|
-
return '
|
|
2538
|
+
return 'field "url" must be a non-empty string.';
|
|
3049
2539
|
}
|
|
3050
2540
|
try {
|
|
3051
2541
|
new URL(entry.url);
|
|
3052
2542
|
} catch {
|
|
3053
|
-
return '
|
|
2543
|
+
return 'field "url" is not a valid URL.';
|
|
3054
2544
|
}
|
|
3055
2545
|
if (entry.type !== void 0 && entry.type !== "http" && entry.type !== "sse") {
|
|
3056
|
-
return '
|
|
2546
|
+
return 'field "type" must be "http" or "sse".';
|
|
3057
2547
|
}
|
|
3058
2548
|
if (entry.headers !== void 0 && !isStringRecord(entry.headers)) {
|
|
3059
|
-
return '
|
|
2549
|
+
return 'field "headers" must be a map of strings.';
|
|
3060
2550
|
}
|
|
3061
2551
|
if (entry.requestTimeoutMs !== void 0 && typeof entry.requestTimeoutMs !== "number") {
|
|
3062
|
-
return '
|
|
2552
|
+
return 'field "requestTimeoutMs" must be a number.';
|
|
3063
2553
|
}
|
|
3064
2554
|
return void 0;
|
|
3065
2555
|
}
|
|
3066
|
-
__name(validarRemoto, "validarRemoto");
|
|
3067
2556
|
function buildEntry(entry) {
|
|
3068
2557
|
if (entry.url !== void 0) {
|
|
3069
|
-
const remote = {
|
|
3070
|
-
url: entry.url
|
|
3071
|
-
};
|
|
2558
|
+
const remote = { url: entry.url };
|
|
3072
2559
|
if (entry.type !== void 0) remote.type = entry.type;
|
|
3073
2560
|
if (entry.headers !== void 0) remote.headers = entry.headers;
|
|
3074
2561
|
if (entry.auth !== void 0) remote.auth = entry.auth;
|
|
3075
2562
|
if (entry.requestTimeoutMs !== void 0) remote.requestTimeoutMs = entry.requestTimeoutMs;
|
|
3076
2563
|
return remote;
|
|
3077
2564
|
}
|
|
3078
|
-
const stdio = {
|
|
3079
|
-
command: entry.command
|
|
3080
|
-
};
|
|
2565
|
+
const stdio = { command: entry.command };
|
|
3081
2566
|
if (entry.args !== void 0) stdio.args = entry.args;
|
|
3082
2567
|
if (entry.env !== void 0) stdio.env = entry.env;
|
|
3083
2568
|
if (entry.cwd !== void 0) stdio.cwd = entry.cwd;
|
|
3084
2569
|
return stdio;
|
|
3085
2570
|
}
|
|
3086
|
-
|
|
3087
|
-
function descrever(err) {
|
|
2571
|
+
function describeIt(err) {
|
|
3088
2572
|
return err instanceof Error ? err.message : String(err);
|
|
3089
2573
|
}
|
|
3090
|
-
__name(descrever, "descrever");
|
|
3091
2574
|
function isStringArray(v) {
|
|
3092
2575
|
return Array.isArray(v) && v.every((x) => typeof x === "string");
|
|
3093
2576
|
}
|
|
3094
|
-
__name(isStringArray, "isStringArray");
|
|
3095
2577
|
function isStringRecord(v) {
|
|
3096
2578
|
return typeof v === "object" && v !== null && !Array.isArray(v) && Object.values(v).every((x) => typeof x === "string");
|
|
3097
2579
|
}
|
|
3098
|
-
__name(isStringRecord, "isStringRecord");
|
|
3099
2580
|
|
|
3100
2581
|
// src/manifest/agent-manifest.ts
|
|
3101
2582
|
function generateAgentManifest(sources) {
|
|
@@ -3113,15 +2594,17 @@ function generateAgentManifest(sources) {
|
|
|
3113
2594
|
},
|
|
3114
2595
|
guards: r.guards.map((g) => g.name),
|
|
3115
2596
|
interceptors: r.interceptors.map((i) => i.name),
|
|
3116
|
-
tools: r.toolboxes.flatMap(
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
2597
|
+
tools: r.toolboxes.flatMap(
|
|
2598
|
+
(tb) => tb.tools.map((t) => ({
|
|
2599
|
+
name: tb.namespace ? `${tb.namespace}.${t.config.name}` : t.config.name,
|
|
2600
|
+
description: t.config.description,
|
|
2601
|
+
risk: t.config.risk,
|
|
2602
|
+
approval: t.approval !== void 0,
|
|
2603
|
+
capabilities: t.capabilities,
|
|
2604
|
+
trace: t.trace,
|
|
2605
|
+
audit: t.audit
|
|
2606
|
+
}))
|
|
2607
|
+
),
|
|
3125
2608
|
gateway: r.gateway ? {
|
|
3126
2609
|
platforms: r.gateway.platforms,
|
|
3127
2610
|
sessionStrategy: r.gateway.sessionStrategy ?? "per-user"
|
|
@@ -3138,7 +2621,6 @@ function generateAgentManifest(sources) {
|
|
|
3138
2621
|
}))
|
|
3139
2622
|
};
|
|
3140
2623
|
}
|
|
3141
|
-
__name(generateAgentManifest, "generateAgentManifest");
|
|
3142
2624
|
|
|
3143
2625
|
// src/theokit-plugin.ts
|
|
3144
2626
|
function validateUniqueRoutes(results) {
|
|
@@ -3146,12 +2628,13 @@ function validateUniqueRoutes(results) {
|
|
|
3146
2628
|
for (const r of results) {
|
|
3147
2629
|
const existing = seen.get(r.route);
|
|
3148
2630
|
if (existing !== void 0) {
|
|
3149
|
-
throw new Error(
|
|
2631
|
+
throw new Error(
|
|
2632
|
+
`[@theokit/agents] Duplicate agent route '${r.route}': both '${existing}' and '${r.agentConfig.name}' declare it.`
|
|
2633
|
+
);
|
|
3150
2634
|
}
|
|
3151
2635
|
seen.set(r.route, r.agentConfig.name);
|
|
3152
2636
|
}
|
|
3153
2637
|
}
|
|
3154
|
-
__name(validateUniqueRoutes, "validateUniqueRoutes");
|
|
3155
2638
|
function agentsPlugin(opts) {
|
|
3156
2639
|
let routes = null;
|
|
3157
2640
|
return {
|
|
@@ -3169,30 +2652,23 @@ function agentsPlugin(opts) {
|
|
|
3169
2652
|
}
|
|
3170
2653
|
};
|
|
3171
2654
|
}
|
|
3172
|
-
__name(agentsPlugin, "agentsPlugin");
|
|
3173
2655
|
function initRoutes(opts) {
|
|
3174
2656
|
const allRoutes = [];
|
|
3175
2657
|
const routeIdentities = [];
|
|
3176
2658
|
for (const entry of opts.agents) {
|
|
3177
|
-
routeIdentities.push({
|
|
3178
|
-
route: entry.route,
|
|
3179
|
-
agentConfig: {
|
|
3180
|
-
name: entry.name
|
|
3181
|
-
}
|
|
3182
|
-
});
|
|
2659
|
+
routeIdentities.push({ route: entry.route, agentConfig: { name: entry.name } });
|
|
3183
2660
|
const createRun = opts.createRunFactory ? opts.createRunFactory(entry.compiled) : defaultCreateRun(entry.compiled);
|
|
3184
|
-
allRoutes.push(
|
|
3185
|
-
|
|
3186
|
-
route: entry.route
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
2661
|
+
allRoutes.push(
|
|
2662
|
+
...generateAgentRoutes({
|
|
2663
|
+
walkResult: { route: entry.route },
|
|
2664
|
+
compiledOptions: entry.compiled,
|
|
2665
|
+
createRun
|
|
2666
|
+
})
|
|
2667
|
+
);
|
|
3191
2668
|
}
|
|
3192
2669
|
validateUniqueRoutes(routeIdentities);
|
|
3193
2670
|
return compileRoutePatterns(allRoutes);
|
|
3194
2671
|
}
|
|
3195
|
-
__name(initRoutes, "initRoutes");
|
|
3196
2672
|
function defaultCreateRun(compiled) {
|
|
3197
2673
|
return async function* (_message, _sessionId) {
|
|
3198
2674
|
await Promise.resolve();
|
|
@@ -3209,18 +2685,13 @@ function defaultCreateRun(compiled) {
|
|
|
3209
2685
|
};
|
|
3210
2686
|
};
|
|
3211
2687
|
}
|
|
3212
|
-
__name(defaultCreateRun, "defaultCreateRun");
|
|
3213
2688
|
function compileRoutePatterns(routes) {
|
|
3214
2689
|
return routes.map((r) => {
|
|
3215
2690
|
if (!r.path.includes(":")) return r;
|
|
3216
2691
|
const regexSource = r.path.replace(/:[^/]+/g, "[^/]+");
|
|
3217
|
-
return {
|
|
3218
|
-
...r,
|
|
3219
|
-
regex: RegExp(`^${regexSource}$`)
|
|
3220
|
-
};
|
|
2692
|
+
return { ...r, regex: RegExp(`^${regexSource}$`) };
|
|
3221
2693
|
});
|
|
3222
2694
|
}
|
|
3223
|
-
__name(compileRoutePatterns, "compileRoutePatterns");
|
|
3224
2695
|
function matchRoute(routes, method, pathname) {
|
|
3225
2696
|
return routes.find((r) => {
|
|
3226
2697
|
if (r.method !== method) return false;
|
|
@@ -3228,7 +2699,6 @@ function matchRoute(routes, method, pathname) {
|
|
|
3228
2699
|
return r.path === pathname;
|
|
3229
2700
|
});
|
|
3230
2701
|
}
|
|
3231
|
-
__name(matchRoute, "matchRoute");
|
|
3232
2702
|
|
|
3233
2703
|
export {
|
|
3234
2704
|
ConfigurationError,
|
|
@@ -3309,4 +2779,4 @@ export {
|
|
|
3309
2779
|
generateAgentManifest,
|
|
3310
2780
|
agentsPlugin
|
|
3311
2781
|
};
|
|
3312
|
-
//# sourceMappingURL=chunk-
|
|
2782
|
+
//# sourceMappingURL=chunk-PHUNONZT.js.map
|