zeitlich 0.2.13 → 0.2.15
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/README.md +61 -50
- package/dist/adapters/sandbox/daytona/index.cjs +205 -0
- package/dist/adapters/sandbox/daytona/index.cjs.map +1 -0
- package/dist/adapters/sandbox/daytona/index.d.cts +86 -0
- package/dist/adapters/sandbox/daytona/index.d.ts +86 -0
- package/dist/adapters/sandbox/daytona/index.js +202 -0
- package/dist/adapters/sandbox/daytona/index.js.map +1 -0
- package/dist/adapters/sandbox/inmemory/index.cjs +174 -0
- package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -0
- package/dist/adapters/sandbox/inmemory/index.d.cts +28 -0
- package/dist/adapters/sandbox/inmemory/index.d.ts +28 -0
- package/dist/adapters/sandbox/inmemory/index.js +172 -0
- package/dist/adapters/sandbox/inmemory/index.js.map +1 -0
- package/dist/adapters/sandbox/virtual/index.cjs +405 -0
- package/dist/adapters/sandbox/virtual/index.cjs.map +1 -0
- package/dist/adapters/sandbox/virtual/index.d.cts +85 -0
- package/dist/adapters/sandbox/virtual/index.d.ts +85 -0
- package/dist/adapters/sandbox/virtual/index.js +400 -0
- package/dist/adapters/sandbox/virtual/index.js.map +1 -0
- package/dist/adapters/thread/google-genai/index.cjs +306 -0
- package/dist/adapters/thread/google-genai/index.cjs.map +1 -0
- package/dist/adapters/thread/google-genai/index.d.cts +145 -0
- package/dist/adapters/thread/google-genai/index.d.ts +145 -0
- package/dist/adapters/thread/google-genai/index.js +300 -0
- package/dist/adapters/thread/google-genai/index.js.map +1 -0
- package/dist/adapters/{langchain → thread/langchain}/index.cjs +29 -9
- package/dist/adapters/thread/langchain/index.cjs.map +1 -0
- package/dist/adapters/{langchain → thread/langchain}/index.d.cts +17 -21
- package/dist/adapters/{langchain → thread/langchain}/index.d.ts +17 -21
- package/dist/adapters/{langchain → thread/langchain}/index.js +29 -9
- package/dist/adapters/thread/langchain/index.js.map +1 -0
- package/dist/index.cjs +866 -567
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +235 -74
- package/dist/index.d.ts +235 -74
- package/dist/index.js +854 -562
- package/dist/index.js.map +1 -1
- package/dist/{thread-manager-qc0g5Rvd.d.cts → types-35POpVfa.d.cts} +7 -6
- package/dist/{thread-manager-qc0g5Rvd.d.ts → types-35POpVfa.d.ts} +7 -6
- package/dist/types-BMXzv7TN.d.cts +476 -0
- package/dist/types-BMXzv7TN.d.ts +476 -0
- package/dist/types-BVP87m_W.d.cts +121 -0
- package/dist/types-BWvIYK28.d.ts +391 -0
- package/dist/types-CDubRtad.d.cts +115 -0
- package/dist/types-CDubRtad.d.ts +115 -0
- package/dist/types-CwwgQ_9H.d.ts +121 -0
- package/dist/types-Dje1TdH6.d.cts +391 -0
- package/dist/workflow.cjs +460 -321
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +271 -222
- package/dist/workflow.d.ts +271 -222
- package/dist/workflow.js +456 -319
- package/dist/workflow.js.map +1 -1
- package/package.json +65 -8
- package/src/adapters/sandbox/daytona/filesystem.ts +136 -0
- package/src/adapters/sandbox/daytona/index.ts +149 -0
- package/src/adapters/sandbox/daytona/types.ts +34 -0
- package/src/adapters/sandbox/inmemory/index.ts +213 -0
- package/src/adapters/sandbox/virtual/filesystem.ts +345 -0
- package/src/adapters/sandbox/virtual/index.ts +88 -0
- package/src/adapters/sandbox/virtual/mutations.ts +38 -0
- package/src/adapters/sandbox/virtual/provider.ts +101 -0
- package/src/adapters/sandbox/virtual/tree.ts +82 -0
- package/src/adapters/sandbox/virtual/types.ts +127 -0
- package/src/adapters/sandbox/virtual/virtual-sandbox.test.ts +523 -0
- package/src/adapters/sandbox/virtual/with-virtual-sandbox.ts +91 -0
- package/src/adapters/thread/google-genai/activities.ts +132 -0
- package/src/adapters/thread/google-genai/index.ts +41 -0
- package/src/adapters/thread/google-genai/model-invoker.ts +154 -0
- package/src/adapters/thread/google-genai/thread-manager.ts +169 -0
- package/src/adapters/{langchain → thread/langchain}/activities.ts +22 -15
- package/src/adapters/{langchain → thread/langchain}/index.ts +1 -1
- package/src/adapters/{langchain → thread/langchain}/model-invoker.ts +15 -18
- package/src/adapters/{langchain → thread/langchain}/thread-manager.ts +1 -1
- package/src/index.ts +32 -24
- package/src/lib/activity.ts +87 -0
- package/src/lib/hooks/index.ts +11 -0
- package/src/lib/hooks/types.ts +98 -0
- package/src/lib/model/helpers.ts +6 -0
- package/src/lib/model/index.ts +13 -0
- package/src/lib/{model-invoker.ts → model/types.ts} +18 -1
- package/src/lib/sandbox/index.ts +19 -0
- package/src/lib/sandbox/manager.ts +76 -0
- package/src/lib/sandbox/sandbox.test.ts +158 -0
- package/src/lib/{fs.ts → sandbox/tree.ts} +6 -6
- package/src/lib/sandbox/types.ts +164 -0
- package/src/lib/session/index.ts +11 -0
- package/src/lib/{session.ts → session/session.ts} +83 -50
- package/src/lib/session/types.ts +95 -0
- package/src/lib/skills/fs-provider.ts +16 -15
- package/src/lib/skills/handler.ts +31 -0
- package/src/lib/skills/index.ts +5 -1
- package/src/lib/skills/register.ts +20 -0
- package/src/lib/skills/tool.ts +47 -0
- package/src/lib/state/index.ts +9 -0
- package/src/lib/{state-manager.ts → state/manager.ts} +10 -147
- package/src/lib/state/types.ts +134 -0
- package/src/lib/subagent/define.ts +71 -0
- package/src/lib/subagent/handler.ts +99 -0
- package/src/lib/subagent/index.ts +13 -0
- package/src/lib/subagent/register.ts +68 -0
- package/src/lib/subagent/tool.ts +80 -0
- package/src/lib/subagent/types.ts +92 -0
- package/src/lib/thread/index.ts +7 -0
- package/src/lib/{thread-manager.ts → thread/manager.ts} +20 -33
- package/src/lib/thread/types.ts +39 -0
- package/src/lib/tool-router/auto-append.ts +55 -0
- package/src/lib/tool-router/index.ts +41 -0
- package/src/lib/tool-router/router.ts +462 -0
- package/src/lib/tool-router/types.ts +478 -0
- package/src/lib/tool-router/with-sandbox.ts +70 -0
- package/src/lib/types.ts +5 -382
- package/src/tools/bash/bash.test.ts +53 -55
- package/src/tools/bash/handler.ts +23 -51
- package/src/tools/edit/handler.ts +67 -81
- package/src/tools/glob/handler.ts +60 -17
- package/src/tools/read-file/handler.ts +67 -0
- package/src/tools/read-skill/handler.ts +1 -31
- package/src/tools/read-skill/tool.ts +5 -47
- package/src/tools/subagent/handler.ts +1 -100
- package/src/tools/subagent/tool.ts +5 -93
- package/src/tools/task-create/handler.ts +1 -1
- package/src/tools/task-get/handler.ts +1 -1
- package/src/tools/task-list/handler.ts +1 -1
- package/src/tools/task-update/handler.ts +1 -1
- package/src/tools/write-file/handler.ts +47 -0
- package/src/workflow.ts +88 -47
- package/tsup.config.ts +8 -1
- package/dist/adapters/langchain/index.cjs.map +0 -1
- package/dist/adapters/langchain/index.js.map +0 -1
- package/dist/model-invoker-y_zlyMqu.d.cts +0 -892
- package/dist/model-invoker-y_zlyMqu.d.ts +0 -892
- package/src/lib/tool-router.ts +0 -977
- package/src/lib/workflow-helpers.ts +0 -50
- /package/src/lib/{thread-id.ts → thread/id.ts} +0 -0
package/dist/workflow.js
CHANGED
|
@@ -1,148 +1,8 @@
|
|
|
1
1
|
import { uuid4, setHandler, defineUpdate, ApplicationFailure, condition, proxyActivities, defineQuery, workflowInfo, executeChild } from '@temporalio/workflow';
|
|
2
2
|
import z14, { z } from 'zod';
|
|
3
|
+
import { ApplicationFailure as ApplicationFailure$1 } from '@temporalio/common';
|
|
3
4
|
|
|
4
|
-
// src/lib/session.ts
|
|
5
|
-
var SUBAGENT_TOOL_NAME = "Subagent";
|
|
6
|
-
function buildSubagentDescription(subagents) {
|
|
7
|
-
const subagentList = subagents.map((s) => {
|
|
8
|
-
const continuation = s.allowThreadContinuation ? "\n*(Supports thread continuation \u2014 pass a threadId to resume a previous conversation)*" : "";
|
|
9
|
-
return `## ${s.agentName}
|
|
10
|
-
${s.description}${continuation}`;
|
|
11
|
-
}).join("\n\n");
|
|
12
|
-
return `The ${SUBAGENT_TOOL_NAME} tool launches specialized agents (subagents) that autonomously handle complex work. Each agent type has specific capabilities and tools available to it.
|
|
13
|
-
|
|
14
|
-
# Available subagents:
|
|
15
|
-
${subagentList}
|
|
16
|
-
`;
|
|
17
|
-
}
|
|
18
|
-
function createSubagentTool(subagents) {
|
|
19
|
-
if (subagents.length === 0) {
|
|
20
|
-
throw new Error("createTaskTool requires at least one subagent");
|
|
21
|
-
}
|
|
22
|
-
const names = subagents.map((s) => s.agentName);
|
|
23
|
-
const hasThreadContinuation = subagents.some(
|
|
24
|
-
(s) => s.allowThreadContinuation
|
|
25
|
-
);
|
|
26
|
-
const baseFields = {
|
|
27
|
-
subagent: z14.enum(names).describe("The type of subagent to launch"),
|
|
28
|
-
description: z14.string().describe("A short (3-5 word) description of the task"),
|
|
29
|
-
prompt: z14.string().describe("The task for the agent to perform")
|
|
30
|
-
};
|
|
31
|
-
const schema = hasThreadContinuation ? z14.object({
|
|
32
|
-
...baseFields,
|
|
33
|
-
threadId: z14.string().nullable().describe(
|
|
34
|
-
"Thread ID to continue an existing conversation, or null to start a new one"
|
|
35
|
-
)
|
|
36
|
-
}) : z14.object(baseFields);
|
|
37
|
-
return {
|
|
38
|
-
name: SUBAGENT_TOOL_NAME,
|
|
39
|
-
description: buildSubagentDescription(subagents),
|
|
40
|
-
schema
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
var BASE62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
44
|
-
function getShortId(length = 12) {
|
|
45
|
-
const hex = uuid4().replace(/-/g, "");
|
|
46
|
-
let result = "";
|
|
47
|
-
for (let i = 0; i < length; i++) {
|
|
48
|
-
const byte = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
49
|
-
result += BASE62[byte % BASE62.length];
|
|
50
|
-
}
|
|
51
|
-
return result;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// src/tools/subagent/handler.ts
|
|
55
|
-
function createSubagentHandler(subagents) {
|
|
56
|
-
const { taskQueue: parentTaskQueue } = workflowInfo();
|
|
57
|
-
return async (args) => {
|
|
58
|
-
const config = subagents.find((s) => s.agentName === args.subagent);
|
|
59
|
-
if (!config) {
|
|
60
|
-
throw new Error(
|
|
61
|
-
`Unknown subagent: ${args.subagent}. Available: ${subagents.map((s) => s.agentName).join(", ")}`
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
const childWorkflowId = `${args.subagent}-${getShortId()}`;
|
|
65
|
-
const input = {
|
|
66
|
-
prompt: args.prompt,
|
|
67
|
-
...config.context && { context: config.context },
|
|
68
|
-
...args.threadId && config.allowThreadContinuation && { threadId: args.threadId }
|
|
69
|
-
};
|
|
70
|
-
const childOpts = {
|
|
71
|
-
workflowId: childWorkflowId,
|
|
72
|
-
args: [input],
|
|
73
|
-
taskQueue: config.taskQueue ?? parentTaskQueue
|
|
74
|
-
};
|
|
75
|
-
const { toolResponse, data, usage, threadId: childThreadId } = typeof config.workflow === "string" ? await executeChild(config.workflow, childOpts) : await executeChild(config.workflow, childOpts);
|
|
76
|
-
if (!toolResponse) {
|
|
77
|
-
return {
|
|
78
|
-
toolResponse: "Subagent workflow returned no response",
|
|
79
|
-
data: null,
|
|
80
|
-
...usage && { usage }
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
const validated = config.resultSchema ? config.resultSchema.safeParse(data) : null;
|
|
84
|
-
if (validated && !validated.success) {
|
|
85
|
-
return {
|
|
86
|
-
toolResponse: `Subagent workflow returned invalid data: ${validated.error.message}`,
|
|
87
|
-
data: null,
|
|
88
|
-
...usage && { usage }
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
let finalToolResponse = toolResponse;
|
|
92
|
-
if (config.allowThreadContinuation && childThreadId) {
|
|
93
|
-
finalToolResponse = typeof toolResponse === "string" ? `${toolResponse}
|
|
94
|
-
|
|
95
|
-
[Thread ID: ${childThreadId}]` : toolResponse;
|
|
96
|
-
}
|
|
97
|
-
return {
|
|
98
|
-
toolResponse: finalToolResponse,
|
|
99
|
-
data: validated ? validated.data : data,
|
|
100
|
-
...usage && { usage }
|
|
101
|
-
};
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
var READ_SKILL_TOOL_NAME = "ReadSkill";
|
|
105
|
-
function buildReadSkillDescription(skills) {
|
|
106
|
-
const skillList = skills.map((s) => `- **${s.name}**: ${s.description}`).join("\n");
|
|
107
|
-
return `Load the full instructions for a skill. Read the skill before following its instructions.
|
|
108
|
-
|
|
109
|
-
# Available skills:
|
|
110
|
-
${skillList}
|
|
111
|
-
`;
|
|
112
|
-
}
|
|
113
|
-
function createReadSkillTool(skills) {
|
|
114
|
-
if (skills.length === 0) {
|
|
115
|
-
throw new Error("createReadSkillTool requires at least one skill");
|
|
116
|
-
}
|
|
117
|
-
const names = skills.map((s) => s.name);
|
|
118
|
-
return {
|
|
119
|
-
name: READ_SKILL_TOOL_NAME,
|
|
120
|
-
description: buildReadSkillDescription(skills),
|
|
121
|
-
schema: z14.object({
|
|
122
|
-
skill_name: z14.enum(names).describe("The name of the skill to load")
|
|
123
|
-
})
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// src/tools/read-skill/handler.ts
|
|
128
|
-
function createReadSkillHandler(skills) {
|
|
129
|
-
const skillMap = new Map(skills.map((s) => [s.name, s]));
|
|
130
|
-
return (args) => {
|
|
131
|
-
const skill = skillMap.get(args.skill_name);
|
|
132
|
-
if (!skill) {
|
|
133
|
-
return {
|
|
134
|
-
toolResponse: JSON.stringify({
|
|
135
|
-
error: `Skill "${args.skill_name}" not found`
|
|
136
|
-
}),
|
|
137
|
-
data: null
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
return {
|
|
141
|
-
toolResponse: skill.instructions,
|
|
142
|
-
data: null
|
|
143
|
-
};
|
|
144
|
-
};
|
|
145
|
-
}
|
|
5
|
+
// src/lib/session/session.ts
|
|
146
6
|
function createToolRouter(options) {
|
|
147
7
|
const { appendToolResult } = options;
|
|
148
8
|
const toolMap = /* @__PURE__ */ new Map();
|
|
@@ -150,45 +10,12 @@ function createToolRouter(options) {
|
|
|
150
10
|
toolMap.set(tool.name, tool);
|
|
151
11
|
}
|
|
152
12
|
const isEnabled = (tool) => tool.enabled ?? true;
|
|
153
|
-
if (options.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
for (const s of options.subagents) {
|
|
157
|
-
if (s.hooks) subagentHooksMap.set(s.agentName, s.hooks);
|
|
158
|
-
}
|
|
159
|
-
const resolveSubagentName = (args) => args.subagent;
|
|
160
|
-
toolMap.set(SUBAGENT_TOOL_NAME, {
|
|
161
|
-
...createSubagentTool(options.subagents),
|
|
162
|
-
handler: createSubagentHandler(options.subagents),
|
|
163
|
-
...subagentHooksMap.size > 0 && {
|
|
164
|
-
hooks: {
|
|
165
|
-
onPreToolUse: async (ctx) => {
|
|
166
|
-
const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
|
|
167
|
-
return hooks?.onPreExecution?.(ctx) ?? {};
|
|
168
|
-
},
|
|
169
|
-
onPostToolUse: async (ctx) => {
|
|
170
|
-
const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
|
|
171
|
-
await hooks?.onPostExecution?.(ctx);
|
|
172
|
-
},
|
|
173
|
-
onPostToolUseFailure: async (ctx) => {
|
|
174
|
-
const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
|
|
175
|
-
return hooks?.onExecutionFailure?.(ctx) ?? {};
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
});
|
|
13
|
+
if (options.plugins) {
|
|
14
|
+
for (const plugin of options.plugins) {
|
|
15
|
+
toolMap.set(plugin.name, plugin);
|
|
180
16
|
}
|
|
181
17
|
}
|
|
182
|
-
|
|
183
|
-
toolMap.set(READ_SKILL_TOOL_NAME, {
|
|
184
|
-
...createReadSkillTool(options.skills),
|
|
185
|
-
handler: createReadSkillHandler(options.skills)
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
async function processToolCall(toolCall, turn, handlerContext) {
|
|
189
|
-
const startTime = Date.now();
|
|
190
|
-
const tool = toolMap.get(toolCall.name);
|
|
191
|
-
const toolHooks = tool?.hooks;
|
|
18
|
+
async function runPreHooks(toolCall, tool, turn) {
|
|
192
19
|
let effectiveArgs = toolCall.args;
|
|
193
20
|
if (options.hooks?.onPreToolUse) {
|
|
194
21
|
const preResult = await options.hooks.onPreToolUse({
|
|
@@ -196,58 +23,105 @@ function createToolRouter(options) {
|
|
|
196
23
|
threadId: options.threadId,
|
|
197
24
|
turn
|
|
198
25
|
});
|
|
199
|
-
if (preResult?.skip) {
|
|
200
|
-
|
|
201
|
-
threadId: options.threadId,
|
|
202
|
-
toolCallId: toolCall.id,
|
|
203
|
-
toolName: toolCall.name,
|
|
204
|
-
content: JSON.stringify({
|
|
205
|
-
skipped: true,
|
|
206
|
-
reason: "Skipped by PreToolUse hook"
|
|
207
|
-
})
|
|
208
|
-
});
|
|
209
|
-
return null;
|
|
210
|
-
}
|
|
211
|
-
if (preResult?.modifiedArgs !== void 0) {
|
|
26
|
+
if (preResult?.skip) return { skip: true };
|
|
27
|
+
if (preResult?.modifiedArgs !== void 0)
|
|
212
28
|
effectiveArgs = preResult.modifiedArgs;
|
|
213
|
-
}
|
|
214
29
|
}
|
|
215
|
-
if (
|
|
216
|
-
const preResult = await
|
|
30
|
+
if (tool?.hooks?.onPreToolUse) {
|
|
31
|
+
const preResult = await tool.hooks.onPreToolUse({
|
|
217
32
|
args: effectiveArgs,
|
|
218
33
|
threadId: options.threadId,
|
|
219
34
|
turn
|
|
220
35
|
});
|
|
221
|
-
if (preResult?.skip) {
|
|
222
|
-
|
|
223
|
-
threadId: options.threadId,
|
|
224
|
-
toolCallId: toolCall.id,
|
|
225
|
-
toolName: toolCall.name,
|
|
226
|
-
content: JSON.stringify({
|
|
227
|
-
skipped: true,
|
|
228
|
-
reason: "Skipped by tool PreToolUse hook"
|
|
229
|
-
})
|
|
230
|
-
});
|
|
231
|
-
return null;
|
|
232
|
-
}
|
|
233
|
-
if (preResult?.modifiedArgs !== void 0) {
|
|
36
|
+
if (preResult?.skip) return { skip: true };
|
|
37
|
+
if (preResult?.modifiedArgs !== void 0)
|
|
234
38
|
effectiveArgs = preResult.modifiedArgs;
|
|
235
|
-
}
|
|
236
39
|
}
|
|
40
|
+
return { skip: false, args: effectiveArgs };
|
|
41
|
+
}
|
|
42
|
+
async function runFailureHooks(toolCall, tool, error, effectiveArgs, turn) {
|
|
43
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
44
|
+
const errorStr = String(error);
|
|
45
|
+
if (tool?.hooks?.onPostToolUseFailure) {
|
|
46
|
+
const r = await tool.hooks.onPostToolUseFailure({
|
|
47
|
+
args: effectiveArgs,
|
|
48
|
+
error: err,
|
|
49
|
+
threadId: options.threadId,
|
|
50
|
+
turn
|
|
51
|
+
});
|
|
52
|
+
if (r?.fallbackContent !== void 0)
|
|
53
|
+
return { content: r.fallbackContent, result: { error: errorStr, recovered: true } };
|
|
54
|
+
if (r?.suppress)
|
|
55
|
+
return {
|
|
56
|
+
content: JSON.stringify({ error: errorStr, suppressed: true }),
|
|
57
|
+
result: { error: errorStr, suppressed: true }
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (options.hooks?.onPostToolUseFailure) {
|
|
61
|
+
const r = await options.hooks.onPostToolUseFailure({
|
|
62
|
+
toolCall,
|
|
63
|
+
error: err,
|
|
64
|
+
threadId: options.threadId,
|
|
65
|
+
turn
|
|
66
|
+
});
|
|
67
|
+
if (r?.fallbackContent !== void 0)
|
|
68
|
+
return { content: r.fallbackContent, result: { error: errorStr, recovered: true } };
|
|
69
|
+
if (r?.suppress)
|
|
70
|
+
return {
|
|
71
|
+
content: JSON.stringify({ error: errorStr, suppressed: true }),
|
|
72
|
+
result: { error: errorStr, suppressed: true }
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
throw ApplicationFailure.fromError(error, { nonRetryable: true });
|
|
76
|
+
}
|
|
77
|
+
async function runPostHooks(toolCall, tool, toolResult, effectiveArgs, turn, durationMs) {
|
|
78
|
+
if (tool?.hooks?.onPostToolUse) {
|
|
79
|
+
await tool.hooks.onPostToolUse({
|
|
80
|
+
args: effectiveArgs,
|
|
81
|
+
result: toolResult.data,
|
|
82
|
+
threadId: options.threadId,
|
|
83
|
+
turn,
|
|
84
|
+
durationMs
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
if (options.hooks?.onPostToolUse) {
|
|
88
|
+
await options.hooks.onPostToolUse({
|
|
89
|
+
toolCall,
|
|
90
|
+
result: toolResult,
|
|
91
|
+
threadId: options.threadId,
|
|
92
|
+
turn,
|
|
93
|
+
durationMs
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async function processToolCall(toolCall, turn, sandboxId) {
|
|
98
|
+
const startTime = Date.now();
|
|
99
|
+
const tool = toolMap.get(toolCall.name);
|
|
100
|
+
const preResult = await runPreHooks(toolCall, tool, turn);
|
|
101
|
+
if (preResult.skip) {
|
|
102
|
+
await appendToolResult({
|
|
103
|
+
threadId: options.threadId,
|
|
104
|
+
toolCallId: toolCall.id,
|
|
105
|
+
toolName: toolCall.name,
|
|
106
|
+
content: JSON.stringify({ skipped: true, reason: "Skipped by PreToolUse hook" })
|
|
107
|
+
});
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const effectiveArgs = preResult.args;
|
|
237
111
|
let result;
|
|
238
112
|
let content;
|
|
239
113
|
let resultAppended = false;
|
|
240
114
|
try {
|
|
241
115
|
if (tool) {
|
|
242
|
-
const
|
|
243
|
-
...handlerContext ?? {},
|
|
116
|
+
const routerContext = {
|
|
244
117
|
threadId: options.threadId,
|
|
245
118
|
toolCallId: toolCall.id,
|
|
246
|
-
toolName: toolCall.name
|
|
119
|
+
toolName: toolCall.name,
|
|
120
|
+
...sandboxId !== void 0 && { sandboxId }
|
|
247
121
|
};
|
|
248
122
|
const response = await tool.handler(
|
|
249
123
|
effectiveArgs,
|
|
250
|
-
|
|
124
|
+
routerContext
|
|
251
125
|
);
|
|
252
126
|
result = response.data;
|
|
253
127
|
content = response.toolResponse;
|
|
@@ -257,47 +131,9 @@ function createToolRouter(options) {
|
|
|
257
131
|
content = JSON.stringify(result, null, 2);
|
|
258
132
|
}
|
|
259
133
|
} catch (error) {
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
const failureResult = await toolHooks.onPostToolUseFailure({
|
|
264
|
-
args: effectiveArgs,
|
|
265
|
-
error: err,
|
|
266
|
-
threadId: options.threadId,
|
|
267
|
-
turn
|
|
268
|
-
});
|
|
269
|
-
if (failureResult?.fallbackContent !== void 0) {
|
|
270
|
-
content = failureResult.fallbackContent;
|
|
271
|
-
result = { error: String(error), recovered: true };
|
|
272
|
-
recovered = true;
|
|
273
|
-
} else if (failureResult?.suppress) {
|
|
274
|
-
content = JSON.stringify({ error: String(error), suppressed: true });
|
|
275
|
-
result = { error: String(error), suppressed: true };
|
|
276
|
-
recovered = true;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
if (!recovered && options.hooks?.onPostToolUseFailure) {
|
|
280
|
-
const failureResult = await options.hooks.onPostToolUseFailure({
|
|
281
|
-
toolCall,
|
|
282
|
-
error: err,
|
|
283
|
-
threadId: options.threadId,
|
|
284
|
-
turn
|
|
285
|
-
});
|
|
286
|
-
if (failureResult?.fallbackContent !== void 0) {
|
|
287
|
-
content = failureResult.fallbackContent;
|
|
288
|
-
result = { error: String(error), recovered: true };
|
|
289
|
-
recovered = true;
|
|
290
|
-
} else if (failureResult?.suppress) {
|
|
291
|
-
content = JSON.stringify({ error: String(error), suppressed: true });
|
|
292
|
-
result = { error: String(error), suppressed: true };
|
|
293
|
-
recovered = true;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
if (!recovered) {
|
|
297
|
-
throw ApplicationFailure.fromError(error, {
|
|
298
|
-
nonRetryable: true
|
|
299
|
-
});
|
|
300
|
-
}
|
|
134
|
+
const recovery = await runFailureHooks(toolCall, tool, error, effectiveArgs, turn);
|
|
135
|
+
result = recovery.result;
|
|
136
|
+
content = recovery.content;
|
|
301
137
|
}
|
|
302
138
|
if (!resultAppended) {
|
|
303
139
|
await appendToolResult({
|
|
@@ -312,29 +148,10 @@ function createToolRouter(options) {
|
|
|
312
148
|
name: toolCall.name,
|
|
313
149
|
data: result
|
|
314
150
|
};
|
|
315
|
-
|
|
316
|
-
if (toolHooks?.onPostToolUse) {
|
|
317
|
-
await toolHooks.onPostToolUse({
|
|
318
|
-
args: effectiveArgs,
|
|
319
|
-
result,
|
|
320
|
-
threadId: options.threadId,
|
|
321
|
-
turn,
|
|
322
|
-
durationMs
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
if (options.hooks?.onPostToolUse) {
|
|
326
|
-
await options.hooks.onPostToolUse({
|
|
327
|
-
toolCall,
|
|
328
|
-
result: toolResult,
|
|
329
|
-
threadId: options.threadId,
|
|
330
|
-
turn,
|
|
331
|
-
durationMs
|
|
332
|
-
});
|
|
333
|
-
}
|
|
151
|
+
await runPostHooks(toolCall, tool, toolResult, effectiveArgs, turn, Date.now() - startTime);
|
|
334
152
|
return toolResult;
|
|
335
153
|
}
|
|
336
154
|
return {
|
|
337
|
-
// --- Methods from registry ---
|
|
338
155
|
hasTools() {
|
|
339
156
|
return Array.from(toolMap.values()).some(isEnabled);
|
|
340
157
|
},
|
|
@@ -358,32 +175,25 @@ function createToolRouter(options) {
|
|
|
358
175
|
return Array.from(toolMap.entries()).filter(([, tool]) => isEnabled(tool)).map(([name]) => name);
|
|
359
176
|
},
|
|
360
177
|
getToolDefinitions() {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
description: tool.description,
|
|
369
|
-
schema: tool.schema,
|
|
370
|
-
strict: tool.strict,
|
|
371
|
-
max_uses: tool.max_uses
|
|
372
|
-
})),
|
|
373
|
-
...activeSubagents.length > 0 ? [createSubagentTool(activeSubagents)] : [],
|
|
374
|
-
...activeSkills.length > 0 ? [createReadSkillTool(activeSkills)] : []
|
|
375
|
-
];
|
|
178
|
+
return Array.from(toolMap).filter(([, tool]) => isEnabled(tool)).map(([name, tool]) => ({
|
|
179
|
+
name,
|
|
180
|
+
description: tool.description,
|
|
181
|
+
schema: tool.schema,
|
|
182
|
+
strict: tool.strict,
|
|
183
|
+
max_uses: tool.max_uses
|
|
184
|
+
}));
|
|
376
185
|
},
|
|
377
|
-
// --- Methods for processing tool calls ---
|
|
378
186
|
async processToolCalls(toolCalls, context) {
|
|
379
187
|
if (toolCalls.length === 0) {
|
|
380
188
|
return [];
|
|
381
189
|
}
|
|
382
190
|
const turn = context?.turn ?? 0;
|
|
383
|
-
const
|
|
191
|
+
const sandboxId = context?.sandboxId;
|
|
384
192
|
if (options.parallel) {
|
|
385
193
|
const results2 = await Promise.all(
|
|
386
|
-
toolCalls.map(
|
|
194
|
+
toolCalls.map(
|
|
195
|
+
(tc) => processToolCall(tc, turn, sandboxId)
|
|
196
|
+
)
|
|
387
197
|
);
|
|
388
198
|
return results2.filter(
|
|
389
199
|
(r) => r !== null
|
|
@@ -391,7 +201,11 @@ function createToolRouter(options) {
|
|
|
391
201
|
}
|
|
392
202
|
const results = [];
|
|
393
203
|
for (const toolCall of toolCalls) {
|
|
394
|
-
const result = await processToolCall(
|
|
204
|
+
const result = await processToolCall(
|
|
205
|
+
toolCall,
|
|
206
|
+
turn,
|
|
207
|
+
sandboxId
|
|
208
|
+
);
|
|
395
209
|
if (result !== null) {
|
|
396
210
|
results.push(result);
|
|
397
211
|
}
|
|
@@ -403,17 +217,16 @@ function createToolRouter(options) {
|
|
|
403
217
|
if (matchingCalls.length === 0) {
|
|
404
218
|
return [];
|
|
405
219
|
}
|
|
406
|
-
const handlerContext = context?.handlerContext ?? {};
|
|
407
220
|
const processOne = async (toolCall) => {
|
|
408
|
-
const
|
|
409
|
-
...handlerContext ?? {},
|
|
221
|
+
const routerContext = {
|
|
410
222
|
threadId: options.threadId,
|
|
411
223
|
toolCallId: toolCall.id,
|
|
412
|
-
toolName: toolCall.name
|
|
224
|
+
toolName: toolCall.name,
|
|
225
|
+
...context?.sandboxId !== void 0 && { sandboxId: context.sandboxId }
|
|
413
226
|
};
|
|
414
227
|
const response = await handler(
|
|
415
228
|
toolCall.args,
|
|
416
|
-
|
|
229
|
+
routerContext
|
|
417
230
|
);
|
|
418
231
|
if (!response.resultAppended) {
|
|
419
232
|
await appendToolResult({
|
|
@@ -438,7 +251,6 @@ function createToolRouter(options) {
|
|
|
438
251
|
}
|
|
439
252
|
return results;
|
|
440
253
|
},
|
|
441
|
-
// --- Utility methods ---
|
|
442
254
|
filterByName(toolCalls, name) {
|
|
443
255
|
return toolCalls.filter(
|
|
444
256
|
(tc) => tc.name === name
|
|
@@ -455,14 +267,207 @@ function createToolRouter(options) {
|
|
|
455
267
|
function defineTool(tool) {
|
|
456
268
|
return tool;
|
|
457
269
|
}
|
|
458
|
-
function defineSubagent(config) {
|
|
459
|
-
return config;
|
|
460
|
-
}
|
|
461
270
|
function hasNoOtherToolCalls(toolCalls, excludeName) {
|
|
462
271
|
return toolCalls.filter((tc) => tc.name !== excludeName).length === 0;
|
|
463
272
|
}
|
|
273
|
+
var BASE62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
274
|
+
function getShortId(length = 12) {
|
|
275
|
+
const hex = uuid4().replace(/-/g, "");
|
|
276
|
+
let result = "";
|
|
277
|
+
for (let i = 0; i < length; i++) {
|
|
278
|
+
const byte = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
279
|
+
result += BASE62[byte % BASE62.length];
|
|
280
|
+
}
|
|
281
|
+
return result;
|
|
282
|
+
}
|
|
283
|
+
var SUBAGENT_TOOL_NAME = "Subagent";
|
|
284
|
+
function buildSubagentDescription(subagents) {
|
|
285
|
+
const subagentList = subagents.map((s) => {
|
|
286
|
+
const continuation = s.allowThreadContinuation ? "\n*(Supports thread continuation \u2014 pass a threadId to resume a previous conversation)*" : "";
|
|
287
|
+
return `## ${s.agentName}
|
|
288
|
+
${s.description}${continuation}`;
|
|
289
|
+
}).join("\n\n");
|
|
290
|
+
return `The ${SUBAGENT_TOOL_NAME} tool launches specialized agents (subagents) that autonomously handle complex work. Each agent type has specific capabilities and tools available to it.
|
|
291
|
+
|
|
292
|
+
# Available subagents:
|
|
293
|
+
${subagentList}
|
|
294
|
+
`;
|
|
295
|
+
}
|
|
296
|
+
function createSubagentTool(subagents) {
|
|
297
|
+
if (subagents.length === 0) {
|
|
298
|
+
throw new Error("createSubagentTool requires at least one subagent");
|
|
299
|
+
}
|
|
300
|
+
const names = subagents.map((s) => s.agentName);
|
|
301
|
+
const hasThreadContinuation = subagents.some(
|
|
302
|
+
(s) => s.allowThreadContinuation
|
|
303
|
+
);
|
|
304
|
+
const baseFields = {
|
|
305
|
+
subagent: z14.enum(names).describe("The type of subagent to launch"),
|
|
306
|
+
description: z14.string().describe("A short (3-5 word) description of the task"),
|
|
307
|
+
prompt: z14.string().describe("The task for the agent to perform")
|
|
308
|
+
};
|
|
309
|
+
const schema = hasThreadContinuation ? z14.object({
|
|
310
|
+
...baseFields,
|
|
311
|
+
threadId: z14.string().nullable().describe(
|
|
312
|
+
"Thread ID to continue an existing conversation, or null to start a new one"
|
|
313
|
+
)
|
|
314
|
+
}) : z14.object(baseFields);
|
|
315
|
+
return {
|
|
316
|
+
name: SUBAGENT_TOOL_NAME,
|
|
317
|
+
description: buildSubagentDescription(subagents),
|
|
318
|
+
schema
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
function createSubagentHandler(subagents) {
|
|
322
|
+
const { taskQueue: parentTaskQueue } = workflowInfo();
|
|
323
|
+
return async (args, context) => {
|
|
324
|
+
const config = subagents.find((s) => s.agentName === args.subagent);
|
|
325
|
+
if (!config) {
|
|
326
|
+
throw new Error(
|
|
327
|
+
`Unknown subagent: ${args.subagent}. Available: ${subagents.map((s) => s.agentName).join(", ")}`
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
const childWorkflowId = `${args.subagent}-${getShortId()}`;
|
|
331
|
+
const { sandboxId: parentSandboxId } = context;
|
|
332
|
+
const inheritSandbox = config.sandbox !== "own" && !!parentSandboxId;
|
|
333
|
+
const input = {
|
|
334
|
+
prompt: args.prompt,
|
|
335
|
+
...config.context && { context: config.context },
|
|
336
|
+
...args.threadId && args.threadId !== null && config.allowThreadContinuation && { previousThreadId: args.threadId },
|
|
337
|
+
...inheritSandbox && { sandboxId: parentSandboxId }
|
|
338
|
+
};
|
|
339
|
+
const childOpts = {
|
|
340
|
+
workflowId: childWorkflowId,
|
|
341
|
+
args: [input],
|
|
342
|
+
taskQueue: config.taskQueue ?? parentTaskQueue
|
|
343
|
+
};
|
|
344
|
+
const {
|
|
345
|
+
toolResponse,
|
|
346
|
+
data,
|
|
347
|
+
usage,
|
|
348
|
+
threadId: childThreadId
|
|
349
|
+
} = typeof config.workflow === "string" ? await executeChild(config.workflow, childOpts) : await executeChild(config.workflow, childOpts);
|
|
350
|
+
if (!toolResponse) {
|
|
351
|
+
return {
|
|
352
|
+
toolResponse: "Subagent workflow returned no response",
|
|
353
|
+
data: null,
|
|
354
|
+
...usage && { usage }
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
const validated = config.resultSchema ? config.resultSchema.safeParse(data) : null;
|
|
358
|
+
if (validated && !validated.success) {
|
|
359
|
+
return {
|
|
360
|
+
toolResponse: `Subagent workflow returned invalid data: ${validated.error.message}`,
|
|
361
|
+
data: null,
|
|
362
|
+
...usage && { usage }
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
let finalToolResponse = toolResponse;
|
|
366
|
+
if (config.allowThreadContinuation && childThreadId) {
|
|
367
|
+
finalToolResponse = typeof toolResponse === "string" ? `${toolResponse}
|
|
368
|
+
|
|
369
|
+
[Thread ID: ${childThreadId}]` : toolResponse;
|
|
370
|
+
}
|
|
371
|
+
return {
|
|
372
|
+
toolResponse: finalToolResponse,
|
|
373
|
+
data: validated ? validated.data : data,
|
|
374
|
+
...usage && { usage }
|
|
375
|
+
};
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// src/lib/subagent/register.ts
|
|
380
|
+
function buildSubagentRegistration(subagents) {
|
|
381
|
+
if (subagents.length === 0) return null;
|
|
382
|
+
const getEnabled = () => subagents.filter((s) => s.enabled ?? true);
|
|
383
|
+
const subagentHooksMap = /* @__PURE__ */ new Map();
|
|
384
|
+
for (const s of subagents) {
|
|
385
|
+
if (s.hooks) subagentHooksMap.set(s.agentName, s.hooks);
|
|
386
|
+
}
|
|
387
|
+
const resolveSubagentName = (args) => args.subagent;
|
|
388
|
+
return {
|
|
389
|
+
name: SUBAGENT_TOOL_NAME,
|
|
390
|
+
get enabled() {
|
|
391
|
+
return getEnabled().length > 0;
|
|
392
|
+
},
|
|
393
|
+
get description() {
|
|
394
|
+
return createSubagentTool(getEnabled()).description;
|
|
395
|
+
},
|
|
396
|
+
get schema() {
|
|
397
|
+
return createSubagentTool(getEnabled()).schema;
|
|
398
|
+
},
|
|
399
|
+
handler: createSubagentHandler(subagents),
|
|
400
|
+
...subagentHooksMap.size > 0 && {
|
|
401
|
+
hooks: {
|
|
402
|
+
onPreToolUse: async (ctx) => {
|
|
403
|
+
const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
|
|
404
|
+
return hooks?.onPreExecution?.(ctx) ?? {};
|
|
405
|
+
},
|
|
406
|
+
onPostToolUse: async (ctx) => {
|
|
407
|
+
const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
|
|
408
|
+
await hooks?.onPostExecution?.(ctx);
|
|
409
|
+
},
|
|
410
|
+
onPostToolUseFailure: async (ctx) => {
|
|
411
|
+
const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
|
|
412
|
+
return hooks?.onExecutionFailure?.(ctx) ?? {};
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
var READ_SKILL_TOOL_NAME = "ReadSkill";
|
|
419
|
+
function buildReadSkillDescription(skills) {
|
|
420
|
+
const skillList = skills.map((s) => `- **${s.name}**: ${s.description}`).join("\n");
|
|
421
|
+
return `Load the full instructions for a skill. Read the skill before following its instructions.
|
|
422
|
+
|
|
423
|
+
# Available skills:
|
|
424
|
+
${skillList}
|
|
425
|
+
`;
|
|
426
|
+
}
|
|
427
|
+
function createReadSkillTool(skills) {
|
|
428
|
+
if (skills.length === 0) {
|
|
429
|
+
throw new Error("createReadSkillTool requires at least one skill");
|
|
430
|
+
}
|
|
431
|
+
const names = skills.map((s) => s.name);
|
|
432
|
+
return {
|
|
433
|
+
name: READ_SKILL_TOOL_NAME,
|
|
434
|
+
description: buildReadSkillDescription(skills),
|
|
435
|
+
schema: z14.object({
|
|
436
|
+
skill_name: z14.enum(names).describe("The name of the skill to load")
|
|
437
|
+
})
|
|
438
|
+
};
|
|
439
|
+
}
|
|
464
440
|
|
|
465
|
-
// src/lib/
|
|
441
|
+
// src/lib/skills/handler.ts
|
|
442
|
+
function createReadSkillHandler(skills) {
|
|
443
|
+
const skillMap = new Map(skills.map((s) => [s.name, s]));
|
|
444
|
+
return (args) => {
|
|
445
|
+
const skill = skillMap.get(args.skill_name);
|
|
446
|
+
if (!skill) {
|
|
447
|
+
return {
|
|
448
|
+
toolResponse: JSON.stringify({
|
|
449
|
+
error: `Skill "${args.skill_name}" not found`
|
|
450
|
+
}),
|
|
451
|
+
data: null
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
return {
|
|
455
|
+
toolResponse: skill.instructions,
|
|
456
|
+
data: null
|
|
457
|
+
};
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// src/lib/skills/register.ts
|
|
462
|
+
function buildSkillRegistration(skills) {
|
|
463
|
+
if (skills.length === 0) return null;
|
|
464
|
+
return {
|
|
465
|
+
...createReadSkillTool(skills),
|
|
466
|
+
handler: createReadSkillHandler(skills)
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// src/lib/session/session.ts
|
|
466
471
|
var createSession = async ({
|
|
467
472
|
threadId: providedThreadId,
|
|
468
473
|
agentName,
|
|
@@ -478,22 +483,34 @@ var createSession = async ({
|
|
|
478
483
|
hooks = {},
|
|
479
484
|
appendSystemPrompt = true,
|
|
480
485
|
continueThread = false,
|
|
481
|
-
waitForInputTimeout = "48h"
|
|
486
|
+
waitForInputTimeout = "48h",
|
|
487
|
+
sandbox: sandboxOps,
|
|
488
|
+
sandboxId: inheritedSandboxId
|
|
482
489
|
}) => {
|
|
483
|
-
const
|
|
490
|
+
const sourceThreadId = continueThread ? providedThreadId : void 0;
|
|
491
|
+
const threadId = continueThread && providedThreadId ? getShortId() : providedThreadId ?? getShortId();
|
|
484
492
|
const {
|
|
485
493
|
appendToolResult,
|
|
486
494
|
appendHumanMessage,
|
|
487
495
|
initializeThread,
|
|
488
|
-
appendSystemMessage
|
|
496
|
+
appendSystemMessage,
|
|
497
|
+
forkThread
|
|
489
498
|
} = threadOps ?? proxyDefaultThreadOps();
|
|
499
|
+
const plugins = [];
|
|
500
|
+
if (subagents) {
|
|
501
|
+
const reg = buildSubagentRegistration(subagents);
|
|
502
|
+
if (reg) plugins.push(reg);
|
|
503
|
+
}
|
|
504
|
+
if (skills) {
|
|
505
|
+
const reg = buildSkillRegistration(skills);
|
|
506
|
+
if (reg) plugins.push(reg);
|
|
507
|
+
}
|
|
490
508
|
const toolRouter = createToolRouter({
|
|
491
509
|
tools,
|
|
492
510
|
appendToolResult,
|
|
493
511
|
threadId,
|
|
494
512
|
hooks,
|
|
495
|
-
|
|
496
|
-
skills,
|
|
513
|
+
plugins,
|
|
497
514
|
parallel: processToolsInParallel
|
|
498
515
|
});
|
|
499
516
|
const callSessionEnd = async (exitReason, turns) => {
|
|
@@ -530,6 +547,17 @@ var createSession = async ({
|
|
|
530
547
|
stateManager.run();
|
|
531
548
|
}
|
|
532
549
|
);
|
|
550
|
+
let sandboxId = inheritedSandboxId;
|
|
551
|
+
const ownsSandbox = !sandboxId && !!sandboxOps;
|
|
552
|
+
if (ownsSandbox) {
|
|
553
|
+
const result = await sandboxOps.createSandbox({ id: threadId });
|
|
554
|
+
sandboxId = result.sandboxId;
|
|
555
|
+
if (result.stateUpdate) {
|
|
556
|
+
stateManager.mergeUpdate(
|
|
557
|
+
result.stateUpdate
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
533
561
|
if (hooks.onSessionStart) {
|
|
534
562
|
await hooks.onSessionStart({
|
|
535
563
|
threadId,
|
|
@@ -538,7 +566,9 @@ var createSession = async ({
|
|
|
538
566
|
});
|
|
539
567
|
}
|
|
540
568
|
const systemPrompt = stateManager.getSystemPrompt();
|
|
541
|
-
if (
|
|
569
|
+
if (continueThread && sourceThreadId) {
|
|
570
|
+
await forkThread(sourceThreadId, threadId);
|
|
571
|
+
} else {
|
|
542
572
|
if (appendSystemPrompt) {
|
|
543
573
|
if (!systemPrompt || systemPrompt.trim() === "") {
|
|
544
574
|
throw ApplicationFailure.create({
|
|
@@ -570,6 +600,7 @@ var createSession = async ({
|
|
|
570
600
|
stateManager.complete();
|
|
571
601
|
exitReason = "completed";
|
|
572
602
|
return {
|
|
603
|
+
threadId,
|
|
573
604
|
finalMessage: message,
|
|
574
605
|
exitReason,
|
|
575
606
|
usage: stateManager.getTotalUsage()
|
|
@@ -593,7 +624,8 @@ var createSession = async ({
|
|
|
593
624
|
const toolCallResults = await toolRouter.processToolCalls(
|
|
594
625
|
parsedToolCalls,
|
|
595
626
|
{
|
|
596
|
-
turn: currentTurn
|
|
627
|
+
turn: currentTurn,
|
|
628
|
+
...sandboxId !== void 0 && { sandboxId }
|
|
597
629
|
}
|
|
598
630
|
);
|
|
599
631
|
for (const result of toolCallResults) {
|
|
@@ -621,8 +653,12 @@ var createSession = async ({
|
|
|
621
653
|
throw ApplicationFailure.fromError(error);
|
|
622
654
|
} finally {
|
|
623
655
|
await callSessionEnd(exitReason, stateManager.getTurns());
|
|
656
|
+
if (ownsSandbox && sandboxId && sandboxOps) {
|
|
657
|
+
await sandboxOps.destroySandbox(sandboxId);
|
|
658
|
+
}
|
|
624
659
|
}
|
|
625
660
|
return {
|
|
661
|
+
threadId,
|
|
626
662
|
finalMessage: null,
|
|
627
663
|
exitReason,
|
|
628
664
|
usage: stateManager.getTotalUsage()
|
|
@@ -643,16 +679,26 @@ function proxyDefaultThreadOps(options) {
|
|
|
643
679
|
}
|
|
644
680
|
);
|
|
645
681
|
}
|
|
682
|
+
function proxySandboxOps(options) {
|
|
683
|
+
return proxyActivities(
|
|
684
|
+
options ?? {
|
|
685
|
+
startToCloseTimeout: "30s",
|
|
686
|
+
retry: {
|
|
687
|
+
maximumAttempts: 3,
|
|
688
|
+
initialInterval: "2s",
|
|
689
|
+
maximumInterval: "30s",
|
|
690
|
+
backoffCoefficient: 2
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
);
|
|
694
|
+
}
|
|
646
695
|
|
|
647
696
|
// src/lib/types.ts
|
|
648
|
-
var agentQueryName = (agentName) => `get${agentName}State`;
|
|
649
|
-
var agentStateChangeUpdateName = (agentName) => `waitFor${agentName}StateChange`;
|
|
650
697
|
function isTerminalStatus(status) {
|
|
651
698
|
return status === "COMPLETED" || status === "FAILED" || status === "CANCELLED";
|
|
652
699
|
}
|
|
653
700
|
function createAgentStateManager({
|
|
654
|
-
initialState
|
|
655
|
-
agentName
|
|
701
|
+
initialState
|
|
656
702
|
}) {
|
|
657
703
|
let status = initialState?.status ?? "RUNNING";
|
|
658
704
|
let version = initialState?.version ?? 0;
|
|
@@ -683,11 +729,9 @@ function createAgentStateManager({
|
|
|
683
729
|
...customState
|
|
684
730
|
};
|
|
685
731
|
}
|
|
686
|
-
const stateQuery = defineQuery(
|
|
687
|
-
agentQueryName(agentName)
|
|
688
|
-
);
|
|
732
|
+
const stateQuery = defineQuery("getAgentState");
|
|
689
733
|
const stateChangeUpdate = defineUpdate(
|
|
690
|
-
|
|
734
|
+
"waitForAgentStateChange"
|
|
691
735
|
);
|
|
692
736
|
setHandler(stateQuery, () => buildState());
|
|
693
737
|
setHandler(stateChangeUpdate, async (lastKnownVersion) => {
|
|
@@ -751,6 +795,10 @@ function createAgentStateManager({
|
|
|
751
795
|
customState[key] = value;
|
|
752
796
|
version++;
|
|
753
797
|
},
|
|
798
|
+
mergeUpdate(update) {
|
|
799
|
+
Object.assign(customState, update);
|
|
800
|
+
version++;
|
|
801
|
+
},
|
|
754
802
|
getCurrentState() {
|
|
755
803
|
return buildState();
|
|
756
804
|
},
|
|
@@ -806,6 +854,95 @@ function createAgentStateManager({
|
|
|
806
854
|
};
|
|
807
855
|
}
|
|
808
856
|
|
|
857
|
+
// src/lib/subagent/define.ts
|
|
858
|
+
function defineSubagent(config) {
|
|
859
|
+
return config;
|
|
860
|
+
}
|
|
861
|
+
var SandboxNotSupportedError = class extends ApplicationFailure$1 {
|
|
862
|
+
constructor(operation) {
|
|
863
|
+
super(
|
|
864
|
+
`Sandbox does not support: ${operation}`,
|
|
865
|
+
"SandboxNotSupportedError",
|
|
866
|
+
true
|
|
867
|
+
);
|
|
868
|
+
}
|
|
869
|
+
};
|
|
870
|
+
var SandboxNotFoundError = class extends ApplicationFailure$1 {
|
|
871
|
+
constructor(sandboxId) {
|
|
872
|
+
super(`Sandbox not found: ${sandboxId}`, "SandboxNotFoundError", true);
|
|
873
|
+
}
|
|
874
|
+
};
|
|
875
|
+
|
|
876
|
+
// src/adapters/sandbox/virtual/mutations.ts
|
|
877
|
+
function applyVirtualTreeMutations(stateManager, mutations) {
|
|
878
|
+
let tree = [...stateManager.get("fileTree")];
|
|
879
|
+
for (const m of mutations) {
|
|
880
|
+
switch (m.type) {
|
|
881
|
+
case "add":
|
|
882
|
+
tree.push(m.entry);
|
|
883
|
+
break;
|
|
884
|
+
case "remove":
|
|
885
|
+
tree = tree.filter((e) => e.path !== m.path);
|
|
886
|
+
break;
|
|
887
|
+
case "update":
|
|
888
|
+
tree = tree.map(
|
|
889
|
+
(e) => e.path === m.path ? { ...e, ...m.entry } : e
|
|
890
|
+
);
|
|
891
|
+
break;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
stateManager.set("fileTree", tree);
|
|
895
|
+
return tree;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
// src/adapters/sandbox/virtual/tree.ts
|
|
899
|
+
var buildTree = (entries) => {
|
|
900
|
+
const root = { name: "/", children: /* @__PURE__ */ new Map(), isFile: false };
|
|
901
|
+
for (const entry of entries) {
|
|
902
|
+
const parts = entry.path.split("/").filter(Boolean);
|
|
903
|
+
let current = root;
|
|
904
|
+
for (const part of parts) {
|
|
905
|
+
let child = current.children.get(part);
|
|
906
|
+
if (!child) {
|
|
907
|
+
child = { name: part, children: /* @__PURE__ */ new Map(), isFile: false };
|
|
908
|
+
current.children.set(part, child);
|
|
909
|
+
}
|
|
910
|
+
current = child;
|
|
911
|
+
}
|
|
912
|
+
current.isFile = current.children.size === 0;
|
|
913
|
+
}
|
|
914
|
+
return root;
|
|
915
|
+
};
|
|
916
|
+
var printNode = (node, tab, sort) => {
|
|
917
|
+
const entries = [...node.children.values()];
|
|
918
|
+
if (sort) {
|
|
919
|
+
entries.sort((a, b) => {
|
|
920
|
+
if (!a.isFile && !b.isFile) return a.name.localeCompare(b.name);
|
|
921
|
+
if (!a.isFile) return -1;
|
|
922
|
+
if (!b.isFile) return 1;
|
|
923
|
+
return a.name.localeCompare(b.name);
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
let str = "";
|
|
927
|
+
for (const [i, entry] of entries.entries()) {
|
|
928
|
+
const isLast = i === entries.length - 1;
|
|
929
|
+
const branch = isLast ? "\u2514\u2500" : "\u251C\u2500";
|
|
930
|
+
const childTab = tab + (isLast ? " " : "\u2502 ");
|
|
931
|
+
if (entry.isFile) {
|
|
932
|
+
str += "\n" + tab + branch + " " + entry.name;
|
|
933
|
+
} else {
|
|
934
|
+
const subtree = printNode(entry, childTab, sort);
|
|
935
|
+
str += "\n" + tab + branch + " " + entry.name + "/" + subtree;
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
return str;
|
|
939
|
+
};
|
|
940
|
+
function formatVirtualFileTree(entries, opts = {}) {
|
|
941
|
+
const sort = opts.sort ?? true;
|
|
942
|
+
const root = buildTree(entries);
|
|
943
|
+
return "/" + printNode(root, "", sort);
|
|
944
|
+
}
|
|
945
|
+
|
|
809
946
|
// src/lib/skills/parse.ts
|
|
810
947
|
function parseSkillFile(raw) {
|
|
811
948
|
const trimmed = raw.replace(/^\uFEFF/, "");
|
|
@@ -1228,6 +1365,6 @@ var createAskUserQuestionHandler = () => async (args) => {
|
|
|
1228
1365
|
};
|
|
1229
1366
|
};
|
|
1230
1367
|
|
|
1231
|
-
export {
|
|
1368
|
+
export { SandboxNotFoundError, SandboxNotSupportedError, applyVirtualTreeMutations, askUserQuestionTool, bashTool, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createReadSkillHandler, createReadSkillTool, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createToolRouter, defineSubagent, defineTool, editTool, formatVirtualFileTree, getShortId, globTool, grepTool, hasNoOtherToolCalls, isTerminalStatus, parseSkillFile, proxyDefaultThreadOps, proxySandboxOps, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, writeFileTool };
|
|
1232
1369
|
//# sourceMappingURL=workflow.js.map
|
|
1233
1370
|
//# sourceMappingURL=workflow.js.map
|