zeitlich 0.2.28 → 0.2.30
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 +121 -13
- package/dist/{activities-3xj_fEJK.d.ts → activities-BeveyY9b.d.cts} +2 -3
- package/dist/{activities-BzYq6jf7.d.cts → activities-NT3rcw66.d.ts} +2 -3
- package/dist/adapters/sandbox/bedrock/index.cjs.map +1 -1
- package/dist/adapters/sandbox/bedrock/index.d.cts +3 -3
- package/dist/adapters/sandbox/bedrock/index.d.ts +3 -3
- package/dist/adapters/sandbox/bedrock/index.js.map +1 -1
- package/dist/adapters/sandbox/bedrock/workflow.d.cts +2 -2
- package/dist/adapters/sandbox/bedrock/workflow.d.ts +2 -2
- package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/index.d.cts +1 -1
- package/dist/adapters/sandbox/daytona/index.d.ts +1 -1
- package/dist/adapters/sandbox/daytona/index.js.map +1 -1
- package/dist/adapters/sandbox/daytona/workflow.d.cts +1 -1
- package/dist/adapters/sandbox/daytona/workflow.d.ts +1 -1
- package/dist/adapters/sandbox/e2b/index.cjs.map +1 -1
- package/dist/adapters/sandbox/e2b/index.d.cts +1 -1
- package/dist/adapters/sandbox/e2b/index.d.ts +1 -1
- package/dist/adapters/sandbox/e2b/index.js.map +1 -1
- package/dist/adapters/sandbox/e2b/workflow.d.cts +1 -1
- package/dist/adapters/sandbox/e2b/workflow.d.ts +1 -1
- package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.d.cts +1 -1
- package/dist/adapters/sandbox/inmemory/index.d.ts +1 -1
- package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.d.cts +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.d.ts +1 -1
- package/dist/adapters/thread/anthropic/index.cjs +0 -1
- package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/index.d.cts +6 -7
- package/dist/adapters/thread/anthropic/index.d.ts +6 -7
- package/dist/adapters/thread/anthropic/index.js +0 -1
- package/dist/adapters/thread/anthropic/index.js.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.d.cts +5 -6
- package/dist/adapters/thread/anthropic/workflow.d.ts +5 -6
- package/dist/adapters/thread/google-genai/index.cjs +0 -1
- package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/index.d.cts +6 -7
- package/dist/adapters/thread/google-genai/index.d.ts +6 -7
- package/dist/adapters/thread/google-genai/index.js +0 -1
- package/dist/adapters/thread/google-genai/index.js.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.d.cts +5 -6
- package/dist/adapters/thread/google-genai/workflow.d.ts +5 -6
- package/dist/adapters/thread/langchain/index.cjs +0 -1
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +6 -7
- package/dist/adapters/thread/langchain/index.d.ts +6 -7
- package/dist/adapters/thread/langchain/index.js +0 -1
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/adapters/thread/langchain/workflow.d.cts +5 -6
- package/dist/adapters/thread/langchain/workflow.d.ts +5 -6
- package/dist/index.cjs +558 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +136 -22
- package/dist/index.d.ts +136 -22
- package/dist/index.js +554 -52
- package/dist/index.js.map +1 -1
- package/dist/{proxy-7e7v8ccg.d.ts → proxy-BgswT47M.d.ts} +1 -1
- package/dist/{proxy-CsB8r0RR.d.cts → proxy-OJihshQF.d.cts} +1 -1
- package/dist/{thread-manager-D8C5QvLi.d.ts → thread-manager-BS477gj8.d.ts} +1 -1
- package/dist/{thread-manager-DdVFl1IY.d.cts → thread-manager-DH0zv05W.d.cts} +1 -1
- package/dist/{thread-manager-B5qA4v7V.d.ts → thread-manager-iUplxEZt.d.ts} +1 -1
- package/dist/{thread-manager-DFJ3sKKU.d.cts → thread-manager-lfN0V-gH.d.cts} +1 -1
- package/dist/{types-ChAMwU3q.d.cts → types-AujBIMMn.d.cts} +5 -8
- package/dist/{types-ChAMwU3q.d.ts → types-AujBIMMn.d.ts} +5 -8
- package/dist/{types-BZ75HpYd.d.ts → types-CCIc7Eam.d.ts} +1 -1
- package/dist/types-D90Q5aOh.d.ts +1212 -0
- package/dist/{types-BdCdR41N.d.ts → types-DBk-C8zM.d.ts} +1 -1
- package/dist/{types-ZHs2v9Ap.d.cts → types-DUvEZSDe.d.cts} +1 -1
- package/dist/types-DVdT5ybA.d.cts +1212 -0
- package/dist/{types-HbjqzyJH.d.cts → types-DgIVPOa1.d.cts} +1 -1
- package/dist/workflow-Cj4DxGdM.d.cts +750 -0
- package/dist/workflow-CzrBdCcJ.d.ts +750 -0
- package/dist/workflow.cjs +194 -40
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +5 -579
- package/dist/workflow.d.ts +5 -579
- package/dist/workflow.js +193 -42
- package/dist/workflow.js.map +1 -1
- package/package.json +3 -23
- package/src/adapters/thread/anthropic/thread-manager.ts +6 -6
- package/src/adapters/thread/google-genai/thread-manager.ts +6 -6
- package/src/adapters/thread/langchain/thread-manager.ts +6 -6
- package/src/index.ts +8 -0
- package/src/lib/lifecycle.ts +8 -3
- package/src/lib/observability/hooks.ts +117 -0
- package/src/lib/observability/index.ts +13 -0
- package/src/lib/observability/sinks.ts +88 -0
- package/src/lib/sandbox/index.ts +2 -4
- package/src/lib/sandbox/manager.ts +131 -16
- package/src/lib/sandbox/sandbox.test.ts +136 -16
- package/src/lib/sandbox/types.ts +6 -5
- package/src/lib/session/session-edge-cases.integration.test.ts +1 -0
- package/src/lib/session/session.integration.test.ts +7 -39
- package/src/lib/session/session.ts +119 -42
- package/src/lib/session/types.ts +39 -9
- package/src/lib/state/manager.integration.test.ts +1 -0
- package/src/lib/state/types.ts +9 -6
- package/src/lib/subagent/handler.ts +35 -12
- package/src/lib/subagent/register.ts +11 -12
- package/src/lib/subagent/subagent.integration.test.ts +1 -0
- package/src/lib/tool-router/router-edge-cases.integration.test.ts +2 -0
- package/src/lib/tool-router/router.integration.test.ts +2 -0
- package/src/lib/tool-router/router.ts +24 -2
- package/src/lib/types.ts +2 -0
- package/src/{adapters/sandbox/virtual → lib/virtual-fs}/filesystem.ts +4 -4
- package/src/lib/virtual-fs/index.ts +18 -0
- package/src/lib/virtual-fs/manager.ts +48 -0
- package/src/lib/virtual-fs/proxy.ts +45 -0
- package/src/{adapters/sandbox/virtual → lib/virtual-fs}/types.ts +41 -37
- package/src/{adapters/sandbox/virtual/virtual-sandbox.test.ts → lib/virtual-fs/virtual-fs.test.ts} +15 -130
- package/src/lib/virtual-fs/with-virtual-fs.ts +94 -0
- package/src/tools/bash/bash.test.ts +2 -1
- package/src/workflow.ts +25 -8
- package/tsup.config.ts +0 -2
- package/dist/adapters/sandbox/virtual/index.cjs +0 -487
- package/dist/adapters/sandbox/virtual/index.cjs.map +0 -1
- package/dist/adapters/sandbox/virtual/index.d.cts +0 -90
- package/dist/adapters/sandbox/virtual/index.d.ts +0 -90
- package/dist/adapters/sandbox/virtual/index.js +0 -479
- package/dist/adapters/sandbox/virtual/index.js.map +0 -1
- package/dist/adapters/sandbox/virtual/workflow.cjs +0 -33
- package/dist/adapters/sandbox/virtual/workflow.cjs.map +0 -1
- package/dist/adapters/sandbox/virtual/workflow.d.cts +0 -28
- package/dist/adapters/sandbox/virtual/workflow.d.ts +0 -28
- package/dist/adapters/sandbox/virtual/workflow.js +0 -31
- package/dist/adapters/sandbox/virtual/workflow.js.map +0 -1
- package/dist/queries-DVnukByF.d.cts +0 -44
- package/dist/queries-kjlvsUfz.d.ts +0 -44
- package/dist/types-BclYm5Ic.d.cts +0 -581
- package/dist/types-BclYm5Ic.d.ts +0 -581
- package/dist/types-BgsAwN3L.d.cts +0 -125
- package/dist/types-BtqbM1bO.d.ts +0 -490
- package/dist/types-BuCEZ4dF.d.cts +0 -490
- package/dist/types-yU5AINiP.d.ts +0 -125
- package/src/adapters/sandbox/virtual/index.ts +0 -92
- package/src/adapters/sandbox/virtual/provider.ts +0 -121
- package/src/adapters/sandbox/virtual/proxy.ts +0 -53
- package/src/adapters/sandbox/virtual/with-virtual-sandbox.ts +0 -97
- package/src/lib/.env +0 -1
- package/src/tools/bash/.env +0 -1
- /package/src/{adapters/sandbox/virtual → lib/virtual-fs}/mutations.ts +0 -0
- /package/src/{adapters/sandbox/virtual → lib/virtual-fs}/queries.ts +0 -0
- /package/src/{adapters/sandbox/virtual → lib/virtual-fs}/tree.ts +0 -0
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineSignal, uuid4, setHandler, defineUpdate, ApplicationFailure, condition, defineQuery, workflowInfo,
|
|
1
|
+
import { defineSignal, uuid4, setHandler, defineUpdate, ApplicationFailure, log, condition, defineQuery, proxySinks, workflowInfo, proxyActivities, getExternalWorkflowHandle, startChild } from '@temporalio/workflow';
|
|
2
2
|
import z14, { z } from 'zod';
|
|
3
3
|
import { randomUUID, randomFillSync } from 'crypto';
|
|
4
4
|
import { ApplicationFailure as ApplicationFailure$1 } from '@temporalio/common';
|
|
@@ -129,6 +129,11 @@ function createToolRouter(options) {
|
|
|
129
129
|
return null;
|
|
130
130
|
}
|
|
131
131
|
const effectiveArgs = preResult.args;
|
|
132
|
+
log.debug("tool call dispatched", {
|
|
133
|
+
toolName: toolCall.name,
|
|
134
|
+
toolCallId: toolCall.id,
|
|
135
|
+
turn
|
|
136
|
+
});
|
|
132
137
|
let result;
|
|
133
138
|
let content;
|
|
134
139
|
let resultAppended = false;
|
|
@@ -155,6 +160,13 @@ function createToolRouter(options) {
|
|
|
155
160
|
content = JSON.stringify(result, null, 2);
|
|
156
161
|
}
|
|
157
162
|
} catch (error) {
|
|
163
|
+
log.warn("tool call failed", {
|
|
164
|
+
toolName: toolCall.name,
|
|
165
|
+
toolCallId: toolCall.id,
|
|
166
|
+
turn,
|
|
167
|
+
durationMs: Date.now() - startTime,
|
|
168
|
+
error: error instanceof Error ? error.message : String(error)
|
|
169
|
+
});
|
|
158
170
|
const recovery = await runFailureHooks(
|
|
159
171
|
toolCall,
|
|
160
172
|
tool,
|
|
@@ -180,19 +192,26 @@ function createToolRouter(options) {
|
|
|
180
192
|
[uuid4(), config]
|
|
181
193
|
);
|
|
182
194
|
}
|
|
195
|
+
const durationMs = Date.now() - startTime;
|
|
183
196
|
const toolResult = {
|
|
184
197
|
toolCallId: toolCall.id,
|
|
185
198
|
name: toolCall.name,
|
|
186
199
|
data: result,
|
|
187
200
|
...metadata && { metadata }
|
|
188
201
|
};
|
|
202
|
+
log.debug("tool call completed", {
|
|
203
|
+
toolName: toolCall.name,
|
|
204
|
+
toolCallId: toolCall.id,
|
|
205
|
+
turn,
|
|
206
|
+
durationMs
|
|
207
|
+
});
|
|
189
208
|
await runPostHooks(
|
|
190
209
|
toolCall,
|
|
191
210
|
tool,
|
|
192
211
|
toolResult,
|
|
193
212
|
effectiveArgs,
|
|
194
213
|
turn,
|
|
195
|
-
|
|
214
|
+
durationMs
|
|
196
215
|
);
|
|
197
216
|
return toolResult;
|
|
198
217
|
}
|
|
@@ -380,7 +399,7 @@ function resolveSandboxConfig(config) {
|
|
|
380
399
|
if (config === "own") return { source: "own" };
|
|
381
400
|
return { source: "own", shutdown: config.shutdown };
|
|
382
401
|
}
|
|
383
|
-
function createSubagentHandler(subagents
|
|
402
|
+
function createSubagentHandler(subagents) {
|
|
384
403
|
const { taskQueue: parentTaskQueue } = workflowInfo();
|
|
385
404
|
const childResults = /* @__PURE__ */ new Map();
|
|
386
405
|
const pendingDestroys = /* @__PURE__ */ new Map();
|
|
@@ -408,15 +427,16 @@ function createSubagentHandler(subagents, options) {
|
|
|
408
427
|
const continuationThreadId = args.threadId && allowsContinuation ? args.threadId : void 0;
|
|
409
428
|
let thread;
|
|
410
429
|
if (continuationThreadId) {
|
|
411
|
-
thread = {
|
|
430
|
+
thread = {
|
|
431
|
+
mode: threadMode,
|
|
432
|
+
threadId: continuationThreadId
|
|
433
|
+
};
|
|
412
434
|
}
|
|
413
435
|
let sandbox;
|
|
414
436
|
if (sandboxCfg.source === "inherit" && parentSandboxId) {
|
|
415
|
-
const stateUpdate = options?.getSandboxStateForInheritance?.();
|
|
416
437
|
sandbox = {
|
|
417
438
|
mode: "inherit",
|
|
418
|
-
sandboxId: parentSandboxId
|
|
419
|
-
...stateUpdate && { stateUpdate }
|
|
439
|
+
sandboxId: parentSandboxId
|
|
420
440
|
};
|
|
421
441
|
} else if (sandboxCfg.source === "own") {
|
|
422
442
|
const prevSbId = continuationThreadId ? threadSandboxes.get(continuationThreadId) : void 0;
|
|
@@ -435,6 +455,12 @@ function createSubagentHandler(subagents, options) {
|
|
|
435
455
|
args: resolvedContext === void 0 ? [args.prompt, workflowInput] : [args.prompt, workflowInput, resolvedContext],
|
|
436
456
|
taskQueue: config.taskQueue ?? parentTaskQueue
|
|
437
457
|
};
|
|
458
|
+
log.info("subagent spawned", {
|
|
459
|
+
subagent: config.agentName,
|
|
460
|
+
childWorkflowId,
|
|
461
|
+
threadMode,
|
|
462
|
+
sandboxSource: sandboxCfg.source
|
|
463
|
+
});
|
|
438
464
|
const childHandle = await startChild(config.workflow, childOpts);
|
|
439
465
|
const effectiveShutdown = sandboxCfg.shutdown ?? "destroy";
|
|
440
466
|
const shouldDeferDestroy = effectiveShutdown === "pause-until-parent-close" && (sandboxCfg.source === "own" || allowsContinuation && sandboxCfg.source !== "inherit");
|
|
@@ -451,11 +477,20 @@ function createSubagentHandler(subagents, options) {
|
|
|
451
477
|
const childResult = childResults.get(childWorkflowId);
|
|
452
478
|
childResults.delete(childWorkflowId);
|
|
453
479
|
if (!childResult) {
|
|
480
|
+
log.warn("subagent returned no result", {
|
|
481
|
+
subagent: config.agentName,
|
|
482
|
+
childWorkflowId
|
|
483
|
+
});
|
|
454
484
|
return {
|
|
455
485
|
toolResponse: "Subagent workflow did not signal a result",
|
|
456
486
|
data: null
|
|
457
487
|
};
|
|
458
488
|
}
|
|
489
|
+
log.info("subagent completed", {
|
|
490
|
+
subagent: config.agentName,
|
|
491
|
+
childWorkflowId,
|
|
492
|
+
...childResult.usage && { usage: childResult.usage }
|
|
493
|
+
});
|
|
459
494
|
const {
|
|
460
495
|
toolResponse,
|
|
461
496
|
data,
|
|
@@ -521,7 +556,7 @@ function createSubagentHandler(subagents, options) {
|
|
|
521
556
|
}
|
|
522
557
|
|
|
523
558
|
// src/lib/subagent/register.ts
|
|
524
|
-
function buildSubagentRegistration(subagents
|
|
559
|
+
function buildSubagentRegistration(subagents) {
|
|
525
560
|
if (subagents.length === 0) return null;
|
|
526
561
|
const getEnabled = () => subagents.filter(
|
|
527
562
|
(s) => typeof s.enabled === "function" ? s.enabled() : s.enabled ?? true
|
|
@@ -531,9 +566,7 @@ function buildSubagentRegistration(subagents, options) {
|
|
|
531
566
|
if (s.hooks) subagentHooksMap.set(s.agentName, s.hooks);
|
|
532
567
|
}
|
|
533
568
|
const resolveSubagentName = (args) => args.subagent;
|
|
534
|
-
const { handler, destroySubagentSandboxes } = createSubagentHandler(subagents
|
|
535
|
-
getSandboxStateForInheritance: options?.getSandboxStateForInheritance
|
|
536
|
-
});
|
|
569
|
+
const { handler, destroySubagentSandboxes } = createSubagentHandler(subagents);
|
|
537
570
|
const registration = {
|
|
538
571
|
name: SUBAGENT_TOOL_NAME,
|
|
539
572
|
enabled: () => getEnabled().length > 0,
|
|
@@ -672,7 +705,9 @@ async function createSession({
|
|
|
672
705
|
sandboxOps,
|
|
673
706
|
thread: threadInit,
|
|
674
707
|
sandbox: sandboxInit,
|
|
675
|
-
sandboxShutdown = "destroy"
|
|
708
|
+
sandboxShutdown = "destroy",
|
|
709
|
+
virtualFs: virtualFsConfig,
|
|
710
|
+
virtualFsOps
|
|
676
711
|
}) {
|
|
677
712
|
const threadMode = threadInit?.mode ?? "new";
|
|
678
713
|
let threadId;
|
|
@@ -698,11 +733,8 @@ async function createSession({
|
|
|
698
733
|
} = threadOps;
|
|
699
734
|
const plugins = [];
|
|
700
735
|
let destroySubagentSandboxes;
|
|
701
|
-
let sandboxStateGetter;
|
|
702
736
|
if (subagents) {
|
|
703
|
-
const result = buildSubagentRegistration(subagents
|
|
704
|
-
getSandboxStateForInheritance: () => sandboxStateGetter?.()
|
|
705
|
-
});
|
|
737
|
+
const result = buildSubagentRegistration(subagents);
|
|
706
738
|
if (result) {
|
|
707
739
|
plugins.push(result.registration);
|
|
708
740
|
destroySubagentSandboxes = result.destroySubagentSandboxes;
|
|
@@ -758,23 +790,9 @@ async function createSession({
|
|
|
758
790
|
const sandboxMode = sandboxInit?.mode;
|
|
759
791
|
let sandboxId;
|
|
760
792
|
let sandboxOwned = false;
|
|
761
|
-
sandboxStateGetter = () => {
|
|
762
|
-
const fileTree = stateManager.get("fileTree");
|
|
763
|
-
const resolverContext = stateManager.get("resolverContext");
|
|
764
|
-
const workspaceBase = stateManager.get("workspaceBase");
|
|
765
|
-
if (!fileTree && !resolverContext && !workspaceBase) return void 0;
|
|
766
|
-
return {
|
|
767
|
-
...fileTree !== void 0 && { fileTree },
|
|
768
|
-
...resolverContext !== void 0 && { resolverContext },
|
|
769
|
-
...workspaceBase !== void 0 && { workspaceBase }
|
|
770
|
-
};
|
|
771
|
-
};
|
|
772
793
|
if (sandboxMode === "inherit") {
|
|
773
794
|
const inheritInit = sandboxInit;
|
|
774
795
|
sandboxId = inheritInit.sandboxId;
|
|
775
|
-
if (inheritInit.stateUpdate) {
|
|
776
|
-
stateManager.mergeUpdate(inheritInit.stateUpdate);
|
|
777
|
-
}
|
|
778
796
|
if (!sandboxOps) {
|
|
779
797
|
throw ApplicationFailure.create({
|
|
780
798
|
message: "sandboxId provided but no sandboxOps \u2014 cannot manage sandbox lifecycle",
|
|
@@ -803,14 +821,25 @@ async function createSession({
|
|
|
803
821
|
sandboxOwned = true;
|
|
804
822
|
} else if (sandboxOps) {
|
|
805
823
|
const skillFiles = skills ? collectSkillFiles(skills) : void 0;
|
|
806
|
-
const
|
|
807
|
-
|
|
808
|
-
);
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
824
|
+
const ctx = sandboxInit?.ctx;
|
|
825
|
+
const createOptions = skillFiles ? { initialFiles: skillFiles } : void 0;
|
|
826
|
+
const result = await sandboxOps.createSandbox(createOptions, ctx);
|
|
827
|
+
if (result) {
|
|
828
|
+
sandboxId = result.sandboxId;
|
|
829
|
+
sandboxOwned = true;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
if (virtualFsConfig) {
|
|
833
|
+
if (!virtualFsOps) {
|
|
834
|
+
throw ApplicationFailure.create({
|
|
835
|
+
message: "No virtualFsOps provided \u2014 cannot resolve file tree",
|
|
836
|
+
nonRetryable: true
|
|
837
|
+
});
|
|
813
838
|
}
|
|
839
|
+
const result = await virtualFsOps.resolveFileTree(virtualFsConfig.ctx);
|
|
840
|
+
stateManager.mergeUpdate({
|
|
841
|
+
fileTree: result.fileTree
|
|
842
|
+
});
|
|
814
843
|
}
|
|
815
844
|
if (hooks.onSessionStart) {
|
|
816
845
|
await hooks.onSessionStart({
|
|
@@ -819,6 +848,14 @@ async function createSession({
|
|
|
819
848
|
metadata
|
|
820
849
|
});
|
|
821
850
|
}
|
|
851
|
+
log.info("session started", {
|
|
852
|
+
agentName,
|
|
853
|
+
threadId,
|
|
854
|
+
threadMode,
|
|
855
|
+
maxTurns,
|
|
856
|
+
...sandboxId && { sandboxId }
|
|
857
|
+
});
|
|
858
|
+
const sessionStartMs = Date.now();
|
|
822
859
|
const systemPrompt = stateManager.getSystemPrompt();
|
|
823
860
|
if (threadMode === "fork" && sourceThreadId) {
|
|
824
861
|
await forkThread(sourceThreadId, threadId, threadKey);
|
|
@@ -835,12 +872,18 @@ async function createSession({
|
|
|
835
872
|
await initializeThread(threadId, threadKey);
|
|
836
873
|
}
|
|
837
874
|
}
|
|
838
|
-
await appendHumanMessage(
|
|
875
|
+
await appendHumanMessage(
|
|
876
|
+
threadId,
|
|
877
|
+
uuid4(),
|
|
878
|
+
await buildContextMessage(),
|
|
879
|
+
threadKey
|
|
880
|
+
);
|
|
839
881
|
let exitReason = "completed";
|
|
840
882
|
try {
|
|
841
883
|
while (stateManager.isRunning() && !stateManager.isTerminal() && stateManager.getTurns() < maxTurns) {
|
|
842
884
|
stateManager.incrementTurns();
|
|
843
885
|
const currentTurn = stateManager.getTurns();
|
|
886
|
+
log.debug("turn started", { agentName, threadId, turn: currentTurn });
|
|
844
887
|
stateManager.setTools(toolRouter.getToolDefinitions());
|
|
845
888
|
const { message, rawToolCalls, usage } = await runAgent({
|
|
846
889
|
threadId,
|
|
@@ -851,9 +894,24 @@ async function createSession({
|
|
|
851
894
|
if (usage) {
|
|
852
895
|
stateManager.updateUsage(usage);
|
|
853
896
|
}
|
|
897
|
+
log.debug("model response received", {
|
|
898
|
+
agentName,
|
|
899
|
+
threadId,
|
|
900
|
+
turn: currentTurn,
|
|
901
|
+
toolCallCount: rawToolCalls.length,
|
|
902
|
+
...usage && { usage }
|
|
903
|
+
});
|
|
854
904
|
if (!toolRouter.hasTools() || rawToolCalls.length === 0) {
|
|
855
905
|
stateManager.complete();
|
|
856
906
|
exitReason = "completed";
|
|
907
|
+
log.info("session ended", {
|
|
908
|
+
agentName,
|
|
909
|
+
threadId,
|
|
910
|
+
exitReason,
|
|
911
|
+
turns: currentTurn,
|
|
912
|
+
durationMs: Date.now() - sessionStartMs,
|
|
913
|
+
usage: stateManager.getTotalUsage()
|
|
914
|
+
});
|
|
857
915
|
return {
|
|
858
916
|
threadId,
|
|
859
917
|
finalMessage: message,
|
|
@@ -905,9 +963,21 @@ async function createSession({
|
|
|
905
963
|
}
|
|
906
964
|
if (stateManager.getTurns() >= maxTurns && stateManager.isRunning()) {
|
|
907
965
|
exitReason = "max_turns";
|
|
966
|
+
log.warn("session hit max turns", {
|
|
967
|
+
agentName,
|
|
968
|
+
threadId,
|
|
969
|
+
maxTurns
|
|
970
|
+
});
|
|
908
971
|
}
|
|
909
972
|
} catch (error) {
|
|
910
973
|
exitReason = "failed";
|
|
974
|
+
log.error("session failed", {
|
|
975
|
+
agentName,
|
|
976
|
+
threadId,
|
|
977
|
+
turns: stateManager.getTurns(),
|
|
978
|
+
durationMs: Date.now() - sessionStartMs,
|
|
979
|
+
error: error instanceof Error ? error.message : String(error)
|
|
980
|
+
});
|
|
911
981
|
throw ApplicationFailure.fromError(error);
|
|
912
982
|
} finally {
|
|
913
983
|
await callSessionEnd(exitReason, stateManager.getTurns());
|
|
@@ -926,6 +996,14 @@ async function createSession({
|
|
|
926
996
|
await destroySubagentSandboxes();
|
|
927
997
|
}
|
|
928
998
|
}
|
|
999
|
+
log.info("session ended", {
|
|
1000
|
+
agentName,
|
|
1001
|
+
threadId,
|
|
1002
|
+
exitReason,
|
|
1003
|
+
turns: stateManager.getTurns(),
|
|
1004
|
+
durationMs: Date.now() - sessionStartMs,
|
|
1005
|
+
usage: stateManager.getTotalUsage()
|
|
1006
|
+
});
|
|
929
1007
|
return {
|
|
930
1008
|
threadId,
|
|
931
1009
|
finalMessage: null,
|
|
@@ -1263,6 +1341,60 @@ function defineSubagentWorkflow(config, fn) {
|
|
|
1263
1341
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1264
1342
|
});
|
|
1265
1343
|
}
|
|
1344
|
+
function createObservabilityHooks(agentName) {
|
|
1345
|
+
const { zeitlichMetrics } = proxySinks();
|
|
1346
|
+
let sessionStartMs = Date.now();
|
|
1347
|
+
return {
|
|
1348
|
+
onSessionStart: (ctx) => {
|
|
1349
|
+
sessionStartMs = Date.now();
|
|
1350
|
+
zeitlichMetrics.sessionStarted({
|
|
1351
|
+
agentName,
|
|
1352
|
+
threadId: ctx.threadId,
|
|
1353
|
+
metadata: ctx.metadata
|
|
1354
|
+
});
|
|
1355
|
+
},
|
|
1356
|
+
onSessionEnd: (ctx) => {
|
|
1357
|
+
zeitlichMetrics.sessionEnded({
|
|
1358
|
+
agentName,
|
|
1359
|
+
threadId: ctx.threadId,
|
|
1360
|
+
exitReason: ctx.exitReason,
|
|
1361
|
+
turns: ctx.turns,
|
|
1362
|
+
usage: {},
|
|
1363
|
+
durationMs: Date.now() - sessionStartMs
|
|
1364
|
+
});
|
|
1365
|
+
},
|
|
1366
|
+
onPostToolUse: (ctx) => {
|
|
1367
|
+
zeitlichMetrics.toolExecuted({
|
|
1368
|
+
agentName,
|
|
1369
|
+
toolName: ctx.toolCall.name,
|
|
1370
|
+
durationMs: ctx.durationMs,
|
|
1371
|
+
success: true,
|
|
1372
|
+
threadId: ctx.threadId,
|
|
1373
|
+
turn: ctx.turn
|
|
1374
|
+
});
|
|
1375
|
+
},
|
|
1376
|
+
onPostToolUseFailure: (ctx) => {
|
|
1377
|
+
zeitlichMetrics.toolExecuted({
|
|
1378
|
+
agentName,
|
|
1379
|
+
toolName: ctx.toolCall.name,
|
|
1380
|
+
durationMs: 0,
|
|
1381
|
+
success: false,
|
|
1382
|
+
threadId: ctx.threadId,
|
|
1383
|
+
turn: ctx.turn
|
|
1384
|
+
});
|
|
1385
|
+
return {};
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1388
|
+
}
|
|
1389
|
+
function composeHooks(...fns) {
|
|
1390
|
+
return async (...args) => {
|
|
1391
|
+
let lastResult;
|
|
1392
|
+
for (const fn of fns) {
|
|
1393
|
+
lastResult = await fn(...args);
|
|
1394
|
+
}
|
|
1395
|
+
return lastResult;
|
|
1396
|
+
};
|
|
1397
|
+
}
|
|
1266
1398
|
var SandboxNotSupportedError = class extends ApplicationFailure$1 {
|
|
1267
1399
|
constructor(operation) {
|
|
1268
1400
|
super(
|
|
@@ -1278,7 +1410,7 @@ var SandboxNotFoundError = class extends ApplicationFailure$1 {
|
|
|
1278
1410
|
}
|
|
1279
1411
|
};
|
|
1280
1412
|
|
|
1281
|
-
// src/
|
|
1413
|
+
// src/lib/virtual-fs/mutations.ts
|
|
1282
1414
|
function applyVirtualTreeMutations(stateManager, mutations) {
|
|
1283
1415
|
let tree = [...stateManager.get("fileTree")];
|
|
1284
1416
|
for (const m of mutations) {
|
|
@@ -1300,7 +1432,7 @@ function applyVirtualTreeMutations(stateManager, mutations) {
|
|
|
1300
1432
|
return tree;
|
|
1301
1433
|
}
|
|
1302
1434
|
|
|
1303
|
-
// src/
|
|
1435
|
+
// src/lib/virtual-fs/tree.ts
|
|
1304
1436
|
var buildTree = (entries) => {
|
|
1305
1437
|
const root = { name: "/", children: /* @__PURE__ */ new Map(), isFile: false };
|
|
1306
1438
|
for (const entry of entries) {
|
|
@@ -1348,7 +1480,7 @@ function formatVirtualFileTree(entries, opts = {}) {
|
|
|
1348
1480
|
return "/" + printNode(root, "", sort);
|
|
1349
1481
|
}
|
|
1350
1482
|
|
|
1351
|
-
// src/
|
|
1483
|
+
// src/lib/virtual-fs/queries.ts
|
|
1352
1484
|
function hasFileWithMimeType(stateManager, pattern) {
|
|
1353
1485
|
const tree = stateManager.get("fileTree");
|
|
1354
1486
|
const matchers = (Array.isArray(pattern) ? pattern : [pattern]).map(buildMatcher);
|
|
@@ -1389,6 +1521,25 @@ function buildGlobMatcher(pattern) {
|
|
|
1389
1521
|
);
|
|
1390
1522
|
return (v) => re.test(v);
|
|
1391
1523
|
}
|
|
1524
|
+
function proxyVirtualFsOps(scope, options) {
|
|
1525
|
+
const resolvedScope = scope ?? workflowInfo().workflowType;
|
|
1526
|
+
const acts = proxyActivities(
|
|
1527
|
+
options ?? {
|
|
1528
|
+
startToCloseTimeout: "30s",
|
|
1529
|
+
retry: {
|
|
1530
|
+
maximumAttempts: 3,
|
|
1531
|
+
initialInterval: "2s",
|
|
1532
|
+
maximumInterval: "30s",
|
|
1533
|
+
backoffCoefficient: 2
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
);
|
|
1537
|
+
const prefix = resolvedScope;
|
|
1538
|
+
const p = (key) => `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;
|
|
1539
|
+
return {
|
|
1540
|
+
resolveFileTree: acts[p("resolveFileTree")]
|
|
1541
|
+
};
|
|
1542
|
+
}
|
|
1392
1543
|
|
|
1393
1544
|
// src/lib/skills/parse.ts
|
|
1394
1545
|
function parseSkillFile(raw) {
|
|
@@ -2023,12 +2174,41 @@ function withParentWorkflowState(client, handler) {
|
|
|
2023
2174
|
|
|
2024
2175
|
// src/lib/sandbox/manager.ts
|
|
2025
2176
|
var SandboxManager = class {
|
|
2026
|
-
constructor(provider) {
|
|
2177
|
+
constructor(provider, options) {
|
|
2027
2178
|
this.provider = provider;
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2179
|
+
this.hooks = options?.hooks ?? {};
|
|
2180
|
+
}
|
|
2181
|
+
hooks;
|
|
2182
|
+
async create(options, ctx) {
|
|
2183
|
+
let providerOptions = options;
|
|
2184
|
+
if (this.hooks.onPreCreate) {
|
|
2185
|
+
const hookResult = await this.hooks.onPreCreate(
|
|
2186
|
+
options ?? {},
|
|
2187
|
+
ctx ?? {}
|
|
2188
|
+
);
|
|
2189
|
+
if (hookResult?.skip) return null;
|
|
2190
|
+
if (hookResult?.modifiedOptions) {
|
|
2191
|
+
const orig = options ?? {};
|
|
2192
|
+
const mod = hookResult.modifiedOptions;
|
|
2193
|
+
providerOptions = {
|
|
2194
|
+
...mod,
|
|
2195
|
+
...orig,
|
|
2196
|
+
initialFiles: {
|
|
2197
|
+
...mod.initialFiles,
|
|
2198
|
+
...orig.initialFiles
|
|
2199
|
+
},
|
|
2200
|
+
env: {
|
|
2201
|
+
...mod.env,
|
|
2202
|
+
...orig.env
|
|
2203
|
+
}
|
|
2204
|
+
};
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
const { sandbox } = await this.provider.create(providerOptions);
|
|
2208
|
+
if (this.hooks.onPostCreate) {
|
|
2209
|
+
await this.hooks.onPostCreate(sandbox.id);
|
|
2210
|
+
}
|
|
2211
|
+
return { sandboxId: sandbox.id };
|
|
2032
2212
|
}
|
|
2033
2213
|
async getSandbox(id) {
|
|
2034
2214
|
return this.provider.get(id);
|
|
@@ -2065,16 +2245,16 @@ var SandboxManager = class {
|
|
|
2065
2245
|
* manager.createActivities("CodingAgent");
|
|
2066
2246
|
* // registers: inMemoryCodingAgentCreateSandbox, inMemoryCodingAgentDestroySandbox, …
|
|
2067
2247
|
*
|
|
2068
|
-
* const
|
|
2069
|
-
*
|
|
2070
|
-
* // registers:
|
|
2248
|
+
* const dmgr = new SandboxManager(new DaytonaSandboxProvider(config));
|
|
2249
|
+
* dmgr.createActivities("CodingAgent");
|
|
2250
|
+
* // registers: daytonaCodingAgentCreateSandbox, …
|
|
2071
2251
|
* ```
|
|
2072
2252
|
*/
|
|
2073
2253
|
createActivities(scope) {
|
|
2074
2254
|
const prefix = `${this.provider.id}${scope.charAt(0).toUpperCase()}${scope.slice(1)}`;
|
|
2075
2255
|
const ops = {
|
|
2076
|
-
createSandbox: async (options) => {
|
|
2077
|
-
return this.create(options);
|
|
2256
|
+
createSandbox: async (options, ctx) => {
|
|
2257
|
+
return this.create(options, ctx);
|
|
2078
2258
|
},
|
|
2079
2259
|
destroySandbox: async (sandboxId) => {
|
|
2080
2260
|
await this.destroy(sandboxId);
|
|
@@ -2164,6 +2344,328 @@ var NodeFsSandboxFileSystem = class {
|
|
|
2164
2344
|
return posix.resolve(base, path);
|
|
2165
2345
|
}
|
|
2166
2346
|
};
|
|
2347
|
+
function normalisePath(p, workspaceBase = "/") {
|
|
2348
|
+
return posix.resolve(workspaceBase, p);
|
|
2349
|
+
}
|
|
2350
|
+
function parentDir(p) {
|
|
2351
|
+
const idx = p.lastIndexOf("/");
|
|
2352
|
+
return idx <= 0 ? "/" : p.slice(0, idx);
|
|
2353
|
+
}
|
|
2354
|
+
function inferDirectories(entries, workspaceBase) {
|
|
2355
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
2356
|
+
dirs.add("/");
|
|
2357
|
+
for (const entry of entries) {
|
|
2358
|
+
let dir = parentDir(normalisePath(entry.path, workspaceBase));
|
|
2359
|
+
while (dir !== "/" && !dirs.has(dir)) {
|
|
2360
|
+
dirs.add(dir);
|
|
2361
|
+
dir = parentDir(dir);
|
|
2362
|
+
}
|
|
2363
|
+
dirs.add("/");
|
|
2364
|
+
}
|
|
2365
|
+
return dirs;
|
|
2366
|
+
}
|
|
2367
|
+
var VirtualFileSystem = class {
|
|
2368
|
+
constructor(tree, resolver, ctx, workspaceBase = "/") {
|
|
2369
|
+
this.resolver = resolver;
|
|
2370
|
+
this.ctx = ctx;
|
|
2371
|
+
this.workspaceBase = normalisePath(workspaceBase);
|
|
2372
|
+
this.entries = new Map(
|
|
2373
|
+
tree.map((e) => [normalisePath(e.path, this.workspaceBase), e])
|
|
2374
|
+
);
|
|
2375
|
+
this.directories = inferDirectories(tree, this.workspaceBase);
|
|
2376
|
+
}
|
|
2377
|
+
workspaceBase;
|
|
2378
|
+
entries;
|
|
2379
|
+
directories;
|
|
2380
|
+
mutations = [];
|
|
2381
|
+
/** Return all mutations accumulated during this invocation. */
|
|
2382
|
+
getMutations() {
|
|
2383
|
+
return this.mutations;
|
|
2384
|
+
}
|
|
2385
|
+
/** Look up a file entry by virtual path. */
|
|
2386
|
+
getEntry(path) {
|
|
2387
|
+
return this.entries.get(normalisePath(path, this.workspaceBase));
|
|
2388
|
+
}
|
|
2389
|
+
// --------------------------------------------------------------------------
|
|
2390
|
+
// Read operations — delegate to resolver lazily
|
|
2391
|
+
// --------------------------------------------------------------------------
|
|
2392
|
+
async readFile(path) {
|
|
2393
|
+
const norm = normalisePath(path, this.workspaceBase);
|
|
2394
|
+
const entry = this.entries.get(norm);
|
|
2395
|
+
if (!entry) throw new Error(`ENOENT: no such file: ${path}`);
|
|
2396
|
+
return this.resolver.readFile(entry.id, this.ctx, entry.metadata);
|
|
2397
|
+
}
|
|
2398
|
+
async readFileBuffer(path) {
|
|
2399
|
+
const norm = normalisePath(path, this.workspaceBase);
|
|
2400
|
+
const entry = this.entries.get(norm);
|
|
2401
|
+
if (!entry) throw new Error(`ENOENT: no such file: ${path}`);
|
|
2402
|
+
return this.resolver.readFileBuffer(entry.id, this.ctx, entry.metadata);
|
|
2403
|
+
}
|
|
2404
|
+
// --------------------------------------------------------------------------
|
|
2405
|
+
// Metadata operations — pure, resolved from the tree
|
|
2406
|
+
// --------------------------------------------------------------------------
|
|
2407
|
+
async exists(path) {
|
|
2408
|
+
const norm = normalisePath(path, this.workspaceBase);
|
|
2409
|
+
return this.entries.has(norm) || this.directories.has(norm);
|
|
2410
|
+
}
|
|
2411
|
+
async stat(path) {
|
|
2412
|
+
const norm = normalisePath(path, this.workspaceBase);
|
|
2413
|
+
const entry = this.entries.get(norm);
|
|
2414
|
+
if (entry) {
|
|
2415
|
+
return {
|
|
2416
|
+
isFile: true,
|
|
2417
|
+
isDirectory: false,
|
|
2418
|
+
isSymbolicLink: false,
|
|
2419
|
+
size: entry.size,
|
|
2420
|
+
mtime: new Date(entry.mtime)
|
|
2421
|
+
};
|
|
2422
|
+
}
|
|
2423
|
+
if (this.directories.has(norm)) {
|
|
2424
|
+
return {
|
|
2425
|
+
isFile: false,
|
|
2426
|
+
isDirectory: true,
|
|
2427
|
+
isSymbolicLink: false,
|
|
2428
|
+
size: 0,
|
|
2429
|
+
mtime: /* @__PURE__ */ new Date()
|
|
2430
|
+
};
|
|
2431
|
+
}
|
|
2432
|
+
throw new Error(`ENOENT: no such file or directory: ${path}`);
|
|
2433
|
+
}
|
|
2434
|
+
async readdir(path) {
|
|
2435
|
+
const norm = normalisePath(path, this.workspaceBase);
|
|
2436
|
+
if (!this.directories.has(norm)) {
|
|
2437
|
+
throw new Error(`ENOENT: no such directory: ${path}`);
|
|
2438
|
+
}
|
|
2439
|
+
const prefix = norm === "/" ? "/" : norm + "/";
|
|
2440
|
+
const names = /* @__PURE__ */ new Set();
|
|
2441
|
+
for (const p of this.entries.keys()) {
|
|
2442
|
+
if (p.startsWith(prefix)) {
|
|
2443
|
+
const rest = p.slice(prefix.length);
|
|
2444
|
+
const seg = rest.split("/")[0];
|
|
2445
|
+
if (seg) names.add(seg);
|
|
2446
|
+
}
|
|
2447
|
+
}
|
|
2448
|
+
for (const d of this.directories) {
|
|
2449
|
+
if (d.startsWith(prefix) && d !== norm) {
|
|
2450
|
+
const rest = d.slice(prefix.length);
|
|
2451
|
+
const seg = rest.split("/")[0];
|
|
2452
|
+
if (seg) names.add(seg);
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
return [...names].sort();
|
|
2456
|
+
}
|
|
2457
|
+
async readdirWithFileTypes(path) {
|
|
2458
|
+
const names = await this.readdir(path);
|
|
2459
|
+
const norm = normalisePath(path, this.workspaceBase);
|
|
2460
|
+
const prefix = norm === "/" ? "/" : norm + "/";
|
|
2461
|
+
return names.map((name) => {
|
|
2462
|
+
const full = prefix + name;
|
|
2463
|
+
const isFile = this.entries.has(full);
|
|
2464
|
+
const isDirectory = this.directories.has(full);
|
|
2465
|
+
return { name, isFile, isDirectory, isSymbolicLink: false };
|
|
2466
|
+
});
|
|
2467
|
+
}
|
|
2468
|
+
// --------------------------------------------------------------------------
|
|
2469
|
+
// Write operations — delegate to resolver, record mutations
|
|
2470
|
+
// --------------------------------------------------------------------------
|
|
2471
|
+
async writeFile(path, content) {
|
|
2472
|
+
const norm = normalisePath(path, this.workspaceBase);
|
|
2473
|
+
const existing = this.entries.get(norm);
|
|
2474
|
+
if (existing) {
|
|
2475
|
+
await this.resolver.writeFile(
|
|
2476
|
+
existing.id,
|
|
2477
|
+
content,
|
|
2478
|
+
this.ctx,
|
|
2479
|
+
existing.metadata
|
|
2480
|
+
);
|
|
2481
|
+
const size = typeof content === "string" ? new TextEncoder().encode(content).byteLength : content.byteLength;
|
|
2482
|
+
const updated = {
|
|
2483
|
+
...existing,
|
|
2484
|
+
size,
|
|
2485
|
+
mtime: (/* @__PURE__ */ new Date()).toISOString()
|
|
2486
|
+
};
|
|
2487
|
+
this.entries.set(norm, updated);
|
|
2488
|
+
this.mutations.push({ type: "update", path: norm, entry: updated });
|
|
2489
|
+
} else {
|
|
2490
|
+
const entry = await this.resolver.createFile(norm, content, this.ctx);
|
|
2491
|
+
const normalised = { ...entry, path: norm };
|
|
2492
|
+
this.entries.set(norm, normalised);
|
|
2493
|
+
this.addParentDirectories(norm);
|
|
2494
|
+
this.mutations.push({ type: "add", entry: normalised });
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
async appendFile(path, content) {
|
|
2498
|
+
const norm = normalisePath(path, this.workspaceBase);
|
|
2499
|
+
const existing = this.entries.get(norm);
|
|
2500
|
+
if (!existing) {
|
|
2501
|
+
return this.writeFile(path, content);
|
|
2502
|
+
}
|
|
2503
|
+
const current = await this.resolver.readFile(
|
|
2504
|
+
existing.id,
|
|
2505
|
+
this.ctx,
|
|
2506
|
+
existing.metadata
|
|
2507
|
+
);
|
|
2508
|
+
const appended = typeof content === "string" ? current + content : current + new TextDecoder().decode(content);
|
|
2509
|
+
await this.resolver.writeFile(
|
|
2510
|
+
existing.id,
|
|
2511
|
+
appended,
|
|
2512
|
+
this.ctx,
|
|
2513
|
+
existing.metadata
|
|
2514
|
+
);
|
|
2515
|
+
const size = new TextEncoder().encode(appended).byteLength;
|
|
2516
|
+
const updated = {
|
|
2517
|
+
...existing,
|
|
2518
|
+
size,
|
|
2519
|
+
mtime: (/* @__PURE__ */ new Date()).toISOString()
|
|
2520
|
+
};
|
|
2521
|
+
this.entries.set(norm, updated);
|
|
2522
|
+
this.mutations.push({ type: "update", path: norm, entry: updated });
|
|
2523
|
+
}
|
|
2524
|
+
async mkdir(_path, _options) {
|
|
2525
|
+
const norm = normalisePath(_path, this.workspaceBase);
|
|
2526
|
+
if (this.directories.has(norm)) return;
|
|
2527
|
+
if (_options?.recursive) {
|
|
2528
|
+
this.addParentDirectories(norm + "/placeholder");
|
|
2529
|
+
this.directories.add(norm);
|
|
2530
|
+
} else {
|
|
2531
|
+
const parent = parentDir(norm);
|
|
2532
|
+
if (!this.directories.has(parent)) {
|
|
2533
|
+
throw new Error(`ENOENT: no such directory: ${parent}`);
|
|
2534
|
+
}
|
|
2535
|
+
this.directories.add(norm);
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
async rm(path, options) {
|
|
2539
|
+
const norm = normalisePath(path, this.workspaceBase);
|
|
2540
|
+
const entry = this.entries.get(norm);
|
|
2541
|
+
if (entry) {
|
|
2542
|
+
await this.resolver.deleteFile(entry.id, this.ctx, entry.metadata);
|
|
2543
|
+
this.entries.delete(norm);
|
|
2544
|
+
this.mutations.push({ type: "remove", path: norm });
|
|
2545
|
+
return;
|
|
2546
|
+
}
|
|
2547
|
+
if (this.directories.has(norm)) {
|
|
2548
|
+
if (!options?.recursive) {
|
|
2549
|
+
throw new Error(`EISDIR: is a directory (use recursive): ${path}`);
|
|
2550
|
+
}
|
|
2551
|
+
const prefix = norm === "/" ? "/" : norm + "/";
|
|
2552
|
+
for (const [p, e] of this.entries) {
|
|
2553
|
+
if (p.startsWith(prefix)) {
|
|
2554
|
+
await this.resolver.deleteFile(e.id, this.ctx, e.metadata);
|
|
2555
|
+
this.entries.delete(p);
|
|
2556
|
+
this.mutations.push({ type: "remove", path: p });
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
for (const d of this.directories) {
|
|
2560
|
+
if (d.startsWith(prefix)) this.directories.delete(d);
|
|
2561
|
+
}
|
|
2562
|
+
this.directories.delete(norm);
|
|
2563
|
+
return;
|
|
2564
|
+
}
|
|
2565
|
+
if (!options?.force) {
|
|
2566
|
+
throw new Error(`ENOENT: no such file or directory: ${path}`);
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
async cp(src, dest, _options) {
|
|
2570
|
+
const normSrc = normalisePath(src, this.workspaceBase);
|
|
2571
|
+
const normDest = normalisePath(dest, this.workspaceBase);
|
|
2572
|
+
const entry = this.entries.get(normSrc);
|
|
2573
|
+
if (entry) {
|
|
2574
|
+
const content = await this.resolver.readFile(
|
|
2575
|
+
entry.id,
|
|
2576
|
+
this.ctx,
|
|
2577
|
+
entry.metadata
|
|
2578
|
+
);
|
|
2579
|
+
await this.writeFile(normDest, content);
|
|
2580
|
+
return;
|
|
2581
|
+
}
|
|
2582
|
+
if (!this.directories.has(normSrc)) {
|
|
2583
|
+
throw new Error(`ENOENT: no such file or directory: ${src}`);
|
|
2584
|
+
}
|
|
2585
|
+
if (!_options?.recursive) {
|
|
2586
|
+
throw new Error(`EISDIR: is a directory (use recursive): ${src}`);
|
|
2587
|
+
}
|
|
2588
|
+
const prefix = normSrc === "/" ? "/" : normSrc + "/";
|
|
2589
|
+
for (const [p, e] of this.entries) {
|
|
2590
|
+
if (p.startsWith(prefix)) {
|
|
2591
|
+
const relative = p.slice(normSrc.length);
|
|
2592
|
+
const content = await this.resolver.readFile(
|
|
2593
|
+
e.id,
|
|
2594
|
+
this.ctx,
|
|
2595
|
+
e.metadata
|
|
2596
|
+
);
|
|
2597
|
+
await this.writeFile(normDest + relative, content);
|
|
2598
|
+
}
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
async mv(src, dest) {
|
|
2602
|
+
await this.cp(src, dest, { recursive: true });
|
|
2603
|
+
await this.rm(src, { recursive: true });
|
|
2604
|
+
}
|
|
2605
|
+
// --------------------------------------------------------------------------
|
|
2606
|
+
// Unsupported
|
|
2607
|
+
// --------------------------------------------------------------------------
|
|
2608
|
+
async readlink(_path) {
|
|
2609
|
+
throw new SandboxNotSupportedError("readlink");
|
|
2610
|
+
}
|
|
2611
|
+
resolvePath(base, path) {
|
|
2612
|
+
return posix.resolve(normalisePath(base, this.workspaceBase), path);
|
|
2613
|
+
}
|
|
2614
|
+
// --------------------------------------------------------------------------
|
|
2615
|
+
// Helpers
|
|
2616
|
+
// --------------------------------------------------------------------------
|
|
2617
|
+
addParentDirectories(filePath) {
|
|
2618
|
+
let dir = parentDir(normalisePath(filePath, this.workspaceBase));
|
|
2619
|
+
while (!this.directories.has(dir)) {
|
|
2620
|
+
this.directories.add(dir);
|
|
2621
|
+
dir = parentDir(dir);
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2624
|
+
};
|
|
2625
|
+
|
|
2626
|
+
// src/lib/virtual-fs/with-virtual-fs.ts
|
|
2627
|
+
function withVirtualFs(client, resolver, handler) {
|
|
2628
|
+
return async (args, context) => {
|
|
2629
|
+
const state = await queryParentWorkflowState(client);
|
|
2630
|
+
const { fileTree, ctx, workspaceBase } = state;
|
|
2631
|
+
if (!fileTree) {
|
|
2632
|
+
return {
|
|
2633
|
+
toolResponse: `Error: No fileTree in agent state. The ${context.toolName} tool requires a virtual filesystem.`,
|
|
2634
|
+
data: null
|
|
2635
|
+
};
|
|
2636
|
+
}
|
|
2637
|
+
const virtualFs = new VirtualFileSystem(
|
|
2638
|
+
fileTree,
|
|
2639
|
+
resolver,
|
|
2640
|
+
ctx,
|
|
2641
|
+
workspaceBase ?? "/"
|
|
2642
|
+
);
|
|
2643
|
+
const response = await handler(args, { ...context, virtualFs });
|
|
2644
|
+
const mutations = virtualFs.getMutations();
|
|
2645
|
+
return {
|
|
2646
|
+
toolResponse: response.toolResponse,
|
|
2647
|
+
data: {
|
|
2648
|
+
...response.data ?? {},
|
|
2649
|
+
treeMutations: mutations
|
|
2650
|
+
}
|
|
2651
|
+
};
|
|
2652
|
+
};
|
|
2653
|
+
}
|
|
2654
|
+
|
|
2655
|
+
// src/lib/virtual-fs/manager.ts
|
|
2656
|
+
function createVirtualFsActivities(resolver, scope) {
|
|
2657
|
+
const ops = {
|
|
2658
|
+
resolveFileTree: async (ctx) => {
|
|
2659
|
+
const fileTree = await resolver.resolveEntries(ctx);
|
|
2660
|
+
return { fileTree };
|
|
2661
|
+
}
|
|
2662
|
+
};
|
|
2663
|
+
const prefix = scope;
|
|
2664
|
+
const cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
2665
|
+
return Object.fromEntries(
|
|
2666
|
+
Object.entries(ops).map(([k, v]) => [`${prefix}${cap(k)}`, v])
|
|
2667
|
+
);
|
|
2668
|
+
}
|
|
2167
2669
|
|
|
2168
2670
|
// src/tools/bash/handler.ts
|
|
2169
2671
|
var bashHandler = async (args, { sandbox }) => {
|
|
@@ -2419,6 +2921,6 @@ var toTree = async (fs, opts = {}) => {
|
|
|
2419
2921
|
return base + subtree;
|
|
2420
2922
|
};
|
|
2421
2923
|
|
|
2422
|
-
export { FileSystemSkillProvider, NodeFsSandboxFileSystem, SandboxManager, SandboxNotFoundError, SandboxNotSupportedError, applyVirtualTreeMutations, askUserQuestionTool, bashHandler, bashTool, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createReadSkillHandler, createReadSkillTool, createRunAgentActivity, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createThreadManager, createToolRouter, defineSubagent, defineSubagentWorkflow, defineTool, defineWorkflow, editHandler, editTool, filesWithMimeType, formatVirtualFileTree, getShortId, globHandler, globTool, grepTool, hasDirectory, hasFileWithMimeType, hasNoOtherToolCalls, isTerminalStatus, parseSkillFile, queryParentWorkflowState, readFileHandler, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, toTree, withAutoAppend, withParentWorkflowState, withSandbox, writeFileHandler, writeFileTool };
|
|
2924
|
+
export { FileSystemSkillProvider, NodeFsSandboxFileSystem, SandboxManager, SandboxNotFoundError, SandboxNotSupportedError, VirtualFileSystem, applyVirtualTreeMutations, askUserQuestionTool, bashHandler, bashTool, composeHooks, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createObservabilityHooks, createReadSkillHandler, createReadSkillTool, createRunAgentActivity, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createThreadManager, createToolRouter, createVirtualFsActivities, defineSubagent, defineSubagentWorkflow, defineTool, defineWorkflow, editHandler, editTool, filesWithMimeType, formatVirtualFileTree, getShortId, globHandler, globTool, grepTool, hasDirectory, hasFileWithMimeType, hasNoOtherToolCalls, isTerminalStatus, parseSkillFile, proxyVirtualFsOps, queryParentWorkflowState, readFileHandler, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, toTree, withAutoAppend, withParentWorkflowState, withSandbox, withVirtualFs, writeFileHandler, writeFileTool };
|
|
2423
2925
|
//# sourceMappingURL=index.js.map
|
|
2424
2926
|
//# sourceMappingURL=index.js.map
|