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