veryfront 0.1.281 → 0.1.283
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/esm/deno.js +1 -1
- package/esm/src/agent/runtime/index.d.ts.map +1 -1
- package/esm/src/agent/runtime/index.js +23 -0
- package/esm/src/agent/runtime/tool-helpers.d.ts +1 -0
- package/esm/src/agent/runtime/tool-helpers.d.ts.map +1 -1
- package/esm/src/agent/runtime/tool-helpers.js +21 -0
- package/esm/src/internal-agents/run-stream.d.ts.map +1 -1
- package/esm/src/internal-agents/run-stream.js +22 -0
- package/esm/src/sandbox/lazy-sandbox.d.ts +4 -0
- package/esm/src/sandbox/lazy-sandbox.d.ts.map +1 -1
- package/esm/src/sandbox/lazy-sandbox.js +53 -34
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
- package/src/deno.js +1 -1
- package/src/src/agent/runtime/index.ts +32 -1
- package/src/src/agent/runtime/tool-helpers.ts +32 -0
- package/src/src/internal-agents/run-stream.ts +34 -0
- package/src/src/sandbox/lazy-sandbox.ts +73 -38
- package/src/src/utils/version-constant.ts +1 -1
package/esm/deno.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/runtime/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,aAAa,EAGlB,KAAK,OAAO,EACZ,KAAK,WAAW,EAEhB,KAAK,QAAQ,EACb,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AAIrB,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAU/D,OAAO,EACL,KAAK,eAAe,EAGpB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACzB,MAAM,0BAA0B,CAAC;AAUlC,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,8BAA8B,EAC9B,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,aAAa,GACd,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC5E,YAAY,EACV,mBAAmB,EACnB,eAAe,EACf,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAiBxB,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/runtime/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -249,6 +249,25 @@ function getRuntimeAllowedRemoteTools(config) {
|
|
|
249
249
|
}
|
|
250
250
|
return raw.every((toolName) => typeof toolName === "string") ? raw : [];
|
|
251
251
|
}
|
|
252
|
+
function getRuntimeForwardedIntegrationToolDefs(config) {
|
|
253
|
+
const configWithFilters = config;
|
|
254
|
+
const raw = configWithFilters.__vfForwardedIntegrationToolDefs;
|
|
255
|
+
if (!Array.isArray(raw) || raw.length === 0)
|
|
256
|
+
return undefined;
|
|
257
|
+
return raw
|
|
258
|
+
.filter((def) => typeof def === "object" &&
|
|
259
|
+
def !== null &&
|
|
260
|
+
typeof def.name === "string" &&
|
|
261
|
+
typeof def.description === "string")
|
|
262
|
+
.map((def) => ({
|
|
263
|
+
name: def.name,
|
|
264
|
+
description: def.description,
|
|
265
|
+
parameters: typeof def.parameters === "object" && def.parameters !== null &&
|
|
266
|
+
!Array.isArray(def.parameters)
|
|
267
|
+
? def.parameters
|
|
268
|
+
: { type: "object", properties: {} },
|
|
269
|
+
}));
|
|
270
|
+
}
|
|
252
271
|
export class AgentRuntime {
|
|
253
272
|
id;
|
|
254
273
|
config;
|
|
@@ -446,6 +465,7 @@ export class AgentRuntime {
|
|
|
446
465
|
// Request-scoped skill policy (not class-level mutable state)
|
|
447
466
|
let activeSkillPolicy;
|
|
448
467
|
const allowedRemoteToolNames = getRuntimeAllowedRemoteTools(this.config);
|
|
468
|
+
const forwardedRemoteToolDefinitions = getRuntimeForwardedIntegrationToolDefs(this.config);
|
|
449
469
|
let currentSystemPrompt = systemPrompt;
|
|
450
470
|
let currentRuntimeContext = runtimeContext;
|
|
451
471
|
for (let step = 0; step < maxSteps; step++) {
|
|
@@ -458,6 +478,7 @@ export class AgentRuntime {
|
|
|
458
478
|
let tools = isLocal ? [] : await getAvailableTools(this.config.tools, {
|
|
459
479
|
includeSkillTools: Boolean(this.config.skills),
|
|
460
480
|
allowedRemoteToolNames,
|
|
481
|
+
forwardedRemoteToolDefinitions,
|
|
461
482
|
remoteToolSources: this.config.remoteTools,
|
|
462
483
|
remoteToolContext: toolContext,
|
|
463
484
|
});
|
|
@@ -650,6 +671,7 @@ export class AgentRuntime {
|
|
|
650
671
|
let finalFinishReason;
|
|
651
672
|
let latestAssistantText = "";
|
|
652
673
|
const allowedRemoteToolNames = getRuntimeAllowedRemoteTools(this.config);
|
|
674
|
+
const forwardedRemoteToolDefinitions = getRuntimeForwardedIntegrationToolDefs(this.config);
|
|
653
675
|
let currentSystemPrompt = systemPrompt;
|
|
654
676
|
let currentRuntimeContext = runtimeContext;
|
|
655
677
|
for (let step = 0; step < maxSteps; step++) {
|
|
@@ -663,6 +685,7 @@ export class AgentRuntime {
|
|
|
663
685
|
let tools = isLocalStreaming ? [] : await getAvailableTools(this.config.tools, {
|
|
664
686
|
includeSkillTools: Boolean(this.config.skills),
|
|
665
687
|
allowedRemoteToolNames,
|
|
688
|
+
forwardedRemoteToolDefinitions,
|
|
666
689
|
remoteToolSources: this.config.remoteTools,
|
|
667
690
|
remoteToolContext: toolContext,
|
|
668
691
|
});
|
|
@@ -41,6 +41,7 @@ export declare function getAvailableTools(toolsConfig: true | Record<string, Too
|
|
|
41
41
|
includeSkillTools?: boolean;
|
|
42
42
|
includeIntegrationTools?: boolean;
|
|
43
43
|
allowedRemoteToolNames?: string[];
|
|
44
|
+
forwardedRemoteToolDefinitions?: ToolDefinition[];
|
|
44
45
|
remoteToolSources?: RemoteToolSource[];
|
|
45
46
|
remoteToolContext?: ToolExecutionContext;
|
|
46
47
|
}): Promise<ToolDefinition[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-helpers.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/runtime/tool-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAaxG;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAuBD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACxC,cAAc,CAyBhB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;;GAGG;AAEH,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC;AAqHvD,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,SAAS,EAC/D,QAAQ,EAAE,MAAM,GACf,IAAI,GAAG,IAAI,CAmBb;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,WAAW,EAAE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,SAAS,EAC/D,OAAO,CAAC,EAAE,oBAAoB,EAC9B,sBAAsB,CAAC,EAAE,MAAM,EAAE,EACjC,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,GACrC,OAAO,CAAC,OAAO,CAAC,CAoClB;
|
|
1
|
+
{"version":3,"file":"tool-helpers.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/runtime/tool-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAaxG;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAuBD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACxC,cAAc,CAyBhB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;;GAGG;AAEH,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC;AAqHvD,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,SAAS,EAC/D,QAAQ,EAAE,MAAM,GACf,IAAI,GAAG,IAAI,CAmBb;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,WAAW,EAAE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,SAAS,EAC/D,OAAO,CAAC,EAAE,oBAAoB,EAC9B,sBAAsB,CAAC,EAAE,MAAM,EAAE,EACjC,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,GACrC,OAAO,CAAC,OAAO,CAAC,CAoClB;AAyCD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,SAAS,EAC/D,OAAO,CAAC,EAAE;IACR,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC,8BAA8B,CAAC,EAAE,cAAc,EAAE,CAAC;IAClD,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACvC,iBAAiB,CAAC,EAAE,oBAAoB,CAAC;CAC1C,GACA,OAAO,CAAC,cAAc,EAAE,CAAC,CAyF3B"}
|
|
@@ -187,6 +187,25 @@ tool) {
|
|
|
187
187
|
logToolDefinition(name, def);
|
|
188
188
|
tools.push(def);
|
|
189
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Merge forwarded integration tool definitions into the remote defs array.
|
|
192
|
+
* Forwarded definitions are provided by the API when the runtime cannot
|
|
193
|
+
* fetch them directly (e.g., the runtime token lacks user auth).
|
|
194
|
+
* Only appends definitions not already present in the array.
|
|
195
|
+
*/
|
|
196
|
+
function appendForwardedToolDefinitions(remoteDefs, forwarded, allowedNames) {
|
|
197
|
+
if (!forwarded?.length)
|
|
198
|
+
return;
|
|
199
|
+
const existing = new Set(remoteDefs.map((def) => def.name));
|
|
200
|
+
for (const def of forwarded) {
|
|
201
|
+
if (existing.has(def.name))
|
|
202
|
+
continue;
|
|
203
|
+
if (allowedNames && !allowedNames.includes(def.name))
|
|
204
|
+
continue;
|
|
205
|
+
remoteDefs.push(def);
|
|
206
|
+
existing.add(def.name);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
190
209
|
/**
|
|
191
210
|
* Get available tools based on agent configuration.
|
|
192
211
|
* When tools === true, loads all tools from registry.
|
|
@@ -213,6 +232,7 @@ export async function getAvailableTools(toolsConfig, options) {
|
|
|
213
232
|
});
|
|
214
233
|
// Append remote integration tools (per-request, project-scoped)
|
|
215
234
|
const remoteDefs = await getRemoteToolDefinitions(options);
|
|
235
|
+
appendForwardedToolDefinitions(remoteDefs, options?.forwardedRemoteToolDefinitions, options?.allowedRemoteToolNames);
|
|
216
236
|
for (const def of remoteDefs) {
|
|
217
237
|
logToolDefinition(def.name, def);
|
|
218
238
|
}
|
|
@@ -221,6 +241,7 @@ export async function getAvailableTools(toolsConfig, options) {
|
|
|
221
241
|
}
|
|
222
242
|
const tools = [];
|
|
223
243
|
const remoteDefs = await getRemoteToolDefinitions(options);
|
|
244
|
+
appendForwardedToolDefinitions(remoteDefs, options?.forwardedRemoteToolDefinitions, options?.allowedRemoteToolNames);
|
|
224
245
|
const remoteToolNames = new Set(remoteDefs.map((def) => def.name));
|
|
225
246
|
const explicitlyRequestedRemoteToolNames = new Set();
|
|
226
247
|
const unresolvedConfiguredToolNames = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-stream.d.ts","sourceRoot":"","sources":["../../../src/src/internal-agents/run-stream.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,KAAK,EACV,KAAK,YAAY,IAAI,OAAO,EAC5B,KAAK,aAAa,EAEnB,MAAM,mBAAmB,CAAC;AAY3B,OAAO,EAA0B,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"run-stream.d.ts","sourceRoot":"","sources":["../../../src/src/internal-agents/run-stream.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,KAAK,EACV,KAAK,YAAY,IAAI,OAAO,EAC5B,KAAK,aAAa,EAEnB,MAAM,mBAAmB,CAAC;AAY3B,OAAO,EAA0B,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAaxD,MAAM,WAAW,+BAA+B;IAC9C,cAAc,EAAE,sBAAsB,CAAC;IACvC,aAAa,CAAC,EAAE,CACd,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAClC;QACH,MAAM,EAAE,CACN,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,SAAS,CAAC,EAAE;YACV,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;SAC9C,EACD,aAAa,CAAC,EAAE,MAAM,EACtB,uBAAuB,CAAC,EAAE,MAAM,EAChC,WAAW,CAAC,EAAE,WAAW,KACtB,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;KAC1C,CAAC;CACH;AAyHD,wBAAsB,gCAAgC,CACpD,KAAK,EAAE,oBAAoB,EAC3B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,+BAA+B,GACpC,OAAO,CAAC,QAAQ,CAAC,CAkPnB"}
|
|
@@ -68,6 +68,24 @@ function getAllowedRemoteToolNames(forwardedProps) {
|
|
|
68
68
|
}
|
|
69
69
|
return allowedTools.every((toolName) => typeof toolName === "string") ? allowedTools : [];
|
|
70
70
|
}
|
|
71
|
+
function getForwardedIntegrationToolDefinitions(forwardedProps) {
|
|
72
|
+
const runtimeOverrides = isRecord(forwardedProps?.runtimeOverrides)
|
|
73
|
+
? forwardedProps.runtimeOverrides
|
|
74
|
+
: null;
|
|
75
|
+
if (!runtimeOverrides)
|
|
76
|
+
return undefined;
|
|
77
|
+
const defs = runtimeOverrides.integrationToolDefinitions;
|
|
78
|
+
if (!Array.isArray(defs) || defs.length === 0)
|
|
79
|
+
return undefined;
|
|
80
|
+
return defs.filter((def) => typeof def === "object" &&
|
|
81
|
+
def !== null &&
|
|
82
|
+
typeof def.name === "string" &&
|
|
83
|
+
typeof def.description === "string").map((def) => ({
|
|
84
|
+
name: def.name,
|
|
85
|
+
description: def.description,
|
|
86
|
+
parameters: def.inputSchema ?? def.parameters ?? { type: "object", properties: {} },
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
71
89
|
export async function createRuntimeAgentStreamResponse(input, agent, deps) {
|
|
72
90
|
logger.info("Starting internal agent runtime stream", {
|
|
73
91
|
runId: input.runId,
|
|
@@ -83,6 +101,7 @@ export async function createRuntimeAgentStreamResponse(input, agent, deps) {
|
|
|
83
101
|
});
|
|
84
102
|
const mergedTools = buildMergedTools(agent, input, deps.sessionManager);
|
|
85
103
|
const allowedRemoteToolNames = getAllowedRemoteToolNames(input.forwardedProps);
|
|
104
|
+
const forwardedIntegrationToolDefs = getForwardedIntegrationToolDefinitions(input.forwardedProps);
|
|
86
105
|
const runtimeAgent = {
|
|
87
106
|
...agent,
|
|
88
107
|
config: {
|
|
@@ -91,6 +110,9 @@ export async function createRuntimeAgentStreamResponse(input, agent, deps) {
|
|
|
91
110
|
...(allowedRemoteToolNames !== undefined
|
|
92
111
|
? { __vfAllowedRemoteTools: allowedRemoteToolNames }
|
|
93
112
|
: {}),
|
|
113
|
+
...(forwardedIntegrationToolDefs !== undefined
|
|
114
|
+
? { __vfForwardedIntegrationToolDefs: forwardedIntegrationToolDefs }
|
|
115
|
+
: {}),
|
|
94
116
|
},
|
|
95
117
|
};
|
|
96
118
|
const runtime = deps.createRuntime?.(runtimeAgent, mergedTools) ??
|
|
@@ -5,6 +5,7 @@ export interface LazySandboxOptions extends SandboxOptions {
|
|
|
5
5
|
pollIntervalMs?: number;
|
|
6
6
|
heartbeatIntervalMs?: number;
|
|
7
7
|
heartbeatGraceMs?: number;
|
|
8
|
+
controlRequestTimeoutMs?: number;
|
|
8
9
|
execStartTimeoutMs?: number;
|
|
9
10
|
execStartMaxAttempts?: number;
|
|
10
11
|
execStartRetryDelayMs?: number;
|
|
@@ -22,6 +23,7 @@ export declare class LazySandbox {
|
|
|
22
23
|
private readonly pollIntervalMs;
|
|
23
24
|
private readonly heartbeatIntervalMs;
|
|
24
25
|
private readonly heartbeatGraceMs;
|
|
26
|
+
private readonly controlRequestTimeoutMs;
|
|
25
27
|
private readonly execStartTimeoutMs;
|
|
26
28
|
private readonly execStartMaxAttempts;
|
|
27
29
|
private readonly execStartRetryDelayMs;
|
|
@@ -56,6 +58,7 @@ export declare class LazySandbox {
|
|
|
56
58
|
get isActive(): boolean;
|
|
57
59
|
private bootstrapSession;
|
|
58
60
|
private resolveReadyEndpoint;
|
|
61
|
+
private waitForReadySession;
|
|
59
62
|
private touchSession;
|
|
60
63
|
private startHeartbeatLoop;
|
|
61
64
|
private stopHeartbeatLoop;
|
|
@@ -68,6 +71,7 @@ export declare class LazySandbox {
|
|
|
68
71
|
private updateTrackedCommandJob;
|
|
69
72
|
private startExec;
|
|
70
73
|
private fetchExecStart;
|
|
74
|
+
private fetchControl;
|
|
71
75
|
private waitForExecStartRetry;
|
|
72
76
|
private reprovisionAfterExecStartFailure;
|
|
73
77
|
private resolveRuntimeEndpoint;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lazy-sandbox.d.ts","sourceRoot":"","sources":["../../../src/src/sandbox/lazy-sandbox.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,gBAAgB,EAErB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,eAAe,EAGpB,KAAK,cAAc,
|
|
1
|
+
{"version":3,"file":"lazy-sandbox.d.ts","sourceRoot":"","sources":["../../../src/src/sandbox/lazy-sandbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as dntShim from "../../_dnt.shims.js";
|
|
2
2
|
import { REQUEST_ERROR } from "../errors/index.js";
|
|
3
|
-
import { resolveSandboxApiUrl, resolveSandboxAuthToken,
|
|
3
|
+
import { resolveSandboxApiUrl, resolveSandboxAuthToken, } from "./sandbox.js";
|
|
4
4
|
const DEFAULT_STARTUP_TIMEOUT_MS = 180_000;
|
|
5
5
|
const DEFAULT_POLL_INTERVAL_MS = 2_000;
|
|
6
6
|
const DEFAULT_HEARTBEAT_INTERVAL_MS = 30_000;
|
|
7
7
|
const DEFAULT_HEARTBEAT_GRACE_MS = 5_000;
|
|
8
|
+
const DEFAULT_CONTROL_REQUEST_TIMEOUT_MS = 15_000;
|
|
8
9
|
const DEFAULT_EXEC_START_TIMEOUT_MS = 30_000;
|
|
9
10
|
const DEFAULT_EXEC_START_MAX_ATTEMPTS = 3;
|
|
10
11
|
const DEFAULT_EXEC_START_RETRY_DELAY_MS = 1_000;
|
|
@@ -23,6 +24,7 @@ export class LazySandbox {
|
|
|
23
24
|
pollIntervalMs;
|
|
24
25
|
heartbeatIntervalMs;
|
|
25
26
|
heartbeatGraceMs;
|
|
27
|
+
controlRequestTimeoutMs;
|
|
26
28
|
execStartTimeoutMs;
|
|
27
29
|
execStartMaxAttempts;
|
|
28
30
|
execStartRetryDelayMs;
|
|
@@ -44,6 +46,8 @@ export class LazySandbox {
|
|
|
44
46
|
this.pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
45
47
|
this.heartbeatIntervalMs = options.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_INTERVAL_MS;
|
|
46
48
|
this.heartbeatGraceMs = options.heartbeatGraceMs ?? DEFAULT_HEARTBEAT_GRACE_MS;
|
|
49
|
+
this.controlRequestTimeoutMs = options.controlRequestTimeoutMs ??
|
|
50
|
+
DEFAULT_CONTROL_REQUEST_TIMEOUT_MS;
|
|
47
51
|
this.execStartTimeoutMs = options.execStartTimeoutMs ?? DEFAULT_EXEC_START_TIMEOUT_MS;
|
|
48
52
|
this.execStartMaxAttempts = options.execStartMaxAttempts ?? DEFAULT_EXEC_START_MAX_ATTEMPTS;
|
|
49
53
|
this.execStartRetryDelayMs = options.execStartRetryDelayMs ??
|
|
@@ -126,7 +130,7 @@ export class LazySandbox {
|
|
|
126
130
|
}
|
|
127
131
|
async readFile(path) {
|
|
128
132
|
await this.touchSession();
|
|
129
|
-
const res = await
|
|
133
|
+
const res = await this.fetchControl(`${this.requireEndpoint()}/file?path=${encodeURIComponent(path)}`, {
|
|
130
134
|
headers: this.authHeaders(),
|
|
131
135
|
});
|
|
132
136
|
if (!res.ok) {
|
|
@@ -136,7 +140,7 @@ export class LazySandbox {
|
|
|
136
140
|
}
|
|
137
141
|
async writeFiles(files) {
|
|
138
142
|
await this.touchSession();
|
|
139
|
-
const res = await
|
|
143
|
+
const res = await this.fetchControl(`${this.requireEndpoint()}/files`, {
|
|
140
144
|
method: "POST",
|
|
141
145
|
headers: this.jsonHeaders(),
|
|
142
146
|
body: JSON.stringify({ files }),
|
|
@@ -150,7 +154,7 @@ export class LazySandbox {
|
|
|
150
154
|
async startCommandJob(command, options) {
|
|
151
155
|
await this.touchSession();
|
|
152
156
|
const endpoint = this.resolveRuntimeEndpoint();
|
|
153
|
-
const res = await
|
|
157
|
+
const res = await this.fetchControl(`${endpoint}/exec/jobs`, {
|
|
154
158
|
method: "POST",
|
|
155
159
|
headers: this.jsonHeaders(),
|
|
156
160
|
body: JSON.stringify({ command, ...this.resolveExecOptions(options) }),
|
|
@@ -166,7 +170,7 @@ export class LazySandbox {
|
|
|
166
170
|
}
|
|
167
171
|
async getCommandJob(jobId) {
|
|
168
172
|
const endpoint = await this.resolveCommandJobEndpoint(jobId);
|
|
169
|
-
const res = await
|
|
173
|
+
const res = await this.fetchControl(`${endpoint}/exec/jobs/${jobId}`, {
|
|
170
174
|
headers: this.authHeaders(),
|
|
171
175
|
});
|
|
172
176
|
if (!res.ok) {
|
|
@@ -180,7 +184,7 @@ export class LazySandbox {
|
|
|
180
184
|
}
|
|
181
185
|
async getCommandJobOutput(jobId) {
|
|
182
186
|
const endpoint = await this.resolveCommandJobEndpoint(jobId);
|
|
183
|
-
const res = await
|
|
187
|
+
const res = await this.fetchControl(`${endpoint}/exec/jobs/${jobId}/output`, {
|
|
184
188
|
headers: this.authHeaders(),
|
|
185
189
|
});
|
|
186
190
|
if (!res.ok) {
|
|
@@ -201,7 +205,7 @@ export class LazySandbox {
|
|
|
201
205
|
}
|
|
202
206
|
async listCommandJobs() {
|
|
203
207
|
await this.ensure();
|
|
204
|
-
const res = await
|
|
208
|
+
const res = await this.fetchControl(`${this.requireEndpoint()}/exec/jobs`, {
|
|
205
209
|
headers: this.authHeaders(),
|
|
206
210
|
});
|
|
207
211
|
if (!res.ok) {
|
|
@@ -215,7 +219,7 @@ export class LazySandbox {
|
|
|
215
219
|
}
|
|
216
220
|
async cancelCommandJob(jobId) {
|
|
217
221
|
const endpoint = await this.resolveCommandJobEndpoint(jobId);
|
|
218
|
-
const res = await
|
|
222
|
+
const res = await this.fetchControl(`${endpoint}/exec/jobs/${jobId}/cancel`, {
|
|
219
223
|
method: "POST",
|
|
220
224
|
headers: this.authHeaders(),
|
|
221
225
|
});
|
|
@@ -241,7 +245,7 @@ export class LazySandbox {
|
|
|
241
245
|
return;
|
|
242
246
|
}
|
|
243
247
|
const promise = (async () => {
|
|
244
|
-
const res = await
|
|
248
|
+
const res = await this.fetchControl(`${this.apiUrl}/sandbox-sessions/${currentSessionId}/heartbeat`, {
|
|
245
249
|
method: "POST",
|
|
246
250
|
headers: this.authHeaders(),
|
|
247
251
|
});
|
|
@@ -309,7 +313,7 @@ export class LazySandbox {
|
|
|
309
313
|
}
|
|
310
314
|
async bootstrapSession() {
|
|
311
315
|
const projectId = this.resolveProjectId();
|
|
312
|
-
const res = await
|
|
316
|
+
const res = await this.fetchControl(`${this.apiUrl}/sandbox-sessions`, {
|
|
313
317
|
method: "POST",
|
|
314
318
|
headers: this.jsonHeaders(),
|
|
315
319
|
body: JSON.stringify(projectId ? { project_id: projectId } : {}),
|
|
@@ -341,23 +345,29 @@ export class LazySandbox {
|
|
|
341
345
|
if (session.status === "running") {
|
|
342
346
|
return session.endpoint;
|
|
343
347
|
}
|
|
344
|
-
await
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
headers: this.authHeaders(),
|
|
353
|
-
});
|
|
354
|
-
if (!res.ok) {
|
|
355
|
-
throw REQUEST_ERROR.create({
|
|
356
|
-
detail: `Failed to get sandbox: ${res.status} ${await res.text()}`,
|
|
348
|
+
return (await this.waitForReadySession(session.id)).endpoint;
|
|
349
|
+
}
|
|
350
|
+
async waitForReadySession(sessionId) {
|
|
351
|
+
const start = Date.now();
|
|
352
|
+
while (Date.now() - start < this.startupTimeoutMs) {
|
|
353
|
+
await new Promise((resolve) => dntShim.setTimeout(resolve, this.pollIntervalMs));
|
|
354
|
+
const res = await this.fetchControl(`${this.apiUrl}/sandbox-sessions/${sessionId}`, {
|
|
355
|
+
headers: this.authHeaders(),
|
|
357
356
|
});
|
|
357
|
+
if (!res.ok) {
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
const session = await res.json();
|
|
361
|
+
if (session.status === "running") {
|
|
362
|
+
return session;
|
|
363
|
+
}
|
|
364
|
+
if (session.status === "error" || session.status === "deleting") {
|
|
365
|
+
throw REQUEST_ERROR.create({
|
|
366
|
+
detail: `Sandbox failed to start: status=${session.status}`,
|
|
367
|
+
});
|
|
368
|
+
}
|
|
358
369
|
}
|
|
359
|
-
|
|
360
|
-
return nextSession.endpoint;
|
|
370
|
+
throw REQUEST_ERROR.create({ detail: "Sandbox did not become ready within timeout" });
|
|
361
371
|
}
|
|
362
372
|
async touchSession() {
|
|
363
373
|
const projectId = this.resolveProjectId();
|
|
@@ -387,7 +397,7 @@ export class LazySandbox {
|
|
|
387
397
|
this.heartbeatTimer = null;
|
|
388
398
|
}
|
|
389
399
|
async deleteSession(sessionId) {
|
|
390
|
-
await
|
|
400
|
+
await this.fetchControl(`${this.apiUrl}/sandbox-sessions/${sessionId}`, {
|
|
391
401
|
method: "DELETE",
|
|
392
402
|
headers: this.authHeaders(),
|
|
393
403
|
});
|
|
@@ -466,14 +476,10 @@ export class LazySandbox {
|
|
|
466
476
|
throw new Error("Sandbox exec failed before a request was made");
|
|
467
477
|
}
|
|
468
478
|
async fetchExecStart(url, init) {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
}
|
|
474
|
-
finally {
|
|
475
|
-
clearTimeout(timeout);
|
|
476
|
-
}
|
|
479
|
+
return fetchWithTimeout(url, this.execStartTimeoutMs, init);
|
|
480
|
+
}
|
|
481
|
+
async fetchControl(url, init = {}) {
|
|
482
|
+
return fetchWithTimeout(url, this.controlRequestTimeoutMs, init);
|
|
477
483
|
}
|
|
478
484
|
waitForExecStartRetry() {
|
|
479
485
|
return new Promise((resolve) => dntShim.setTimeout(resolve, this.execStartRetryDelayMs));
|
|
@@ -523,6 +529,19 @@ function shouldReprovisionAfterExecStartFailure(error) {
|
|
|
523
529
|
return typeof cause.code === "string" &&
|
|
524
530
|
REPROVISIONABLE_EXEC_START_ERROR_CODES.has(cause.code);
|
|
525
531
|
}
|
|
532
|
+
async function fetchWithTimeout(url, timeoutMs, init = {}) {
|
|
533
|
+
if (timeoutMs <= 0) {
|
|
534
|
+
return await fetch(url, init);
|
|
535
|
+
}
|
|
536
|
+
const controller = new AbortController();
|
|
537
|
+
const timeout = dntShim.setTimeout(() => controller.abort(), timeoutMs);
|
|
538
|
+
try {
|
|
539
|
+
return await fetch(url, { ...init, signal: controller.signal });
|
|
540
|
+
}
|
|
541
|
+
finally {
|
|
542
|
+
clearTimeout(timeout);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
526
545
|
function mapCommandJob(json) {
|
|
527
546
|
return {
|
|
528
547
|
id: json.id,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.1.
|
|
1
|
+
export declare const VERSION = "0.1.283";
|
|
2
2
|
//# sourceMappingURL=version-constant.d.ts.map
|
package/package.json
CHANGED
package/src/deno.js
CHANGED
|
@@ -47,7 +47,7 @@ import { repairToolCall } from "./repair-tool-call.js";
|
|
|
47
47
|
import { MiddlewareChain } from "../middleware/chain.js";
|
|
48
48
|
import { AGENT_DEFAULTS } from "../defaults.js";
|
|
49
49
|
import { tryGetCacheKeyContext } from "../../cache/cache-key-builder.js";
|
|
50
|
-
import type { ToolExecutionContext } from "../../tool/index.js";
|
|
50
|
+
import type { ToolDefinition, ToolExecutionContext } from "../../tool/index.js";
|
|
51
51
|
import { isLocalModelRuntime } from "../../provider/runtime-inspection.js";
|
|
52
52
|
import { generateText, streamText } from "../../runtime/runtime-bridge.js";
|
|
53
53
|
|
|
@@ -110,6 +110,9 @@ const LOAD_SKILL_TOOL_ID = "load-skill";
|
|
|
110
110
|
|
|
111
111
|
type RuntimeToolFilterConfig = AgentConfig & {
|
|
112
112
|
__vfAllowedRemoteTools?: string[];
|
|
113
|
+
__vfForwardedIntegrationToolDefs?: Array<
|
|
114
|
+
{ name: string; description: string; parameters: Record<string, unknown> }
|
|
115
|
+
>;
|
|
113
116
|
};
|
|
114
117
|
|
|
115
118
|
function isAbortError(error: unknown, abortSignal?: AbortSignal): boolean {
|
|
@@ -418,6 +421,30 @@ function getRuntimeAllowedRemoteTools(config: AgentConfig): string[] | undefined
|
|
|
418
421
|
return raw.every((toolName) => typeof toolName === "string") ? raw : [];
|
|
419
422
|
}
|
|
420
423
|
|
|
424
|
+
function getRuntimeForwardedIntegrationToolDefs(
|
|
425
|
+
config: AgentConfig,
|
|
426
|
+
): ToolDefinition[] | undefined {
|
|
427
|
+
const configWithFilters = config as RuntimeToolFilterConfig;
|
|
428
|
+
const raw = configWithFilters.__vfForwardedIntegrationToolDefs;
|
|
429
|
+
if (!Array.isArray(raw) || raw.length === 0) return undefined;
|
|
430
|
+
return raw
|
|
431
|
+
.filter(
|
|
432
|
+
(def): def is { name: string; description: string; parameters: Record<string, unknown> } =>
|
|
433
|
+
typeof def === "object" &&
|
|
434
|
+
def !== null &&
|
|
435
|
+
typeof def.name === "string" &&
|
|
436
|
+
typeof def.description === "string",
|
|
437
|
+
)
|
|
438
|
+
.map((def) => ({
|
|
439
|
+
name: def.name,
|
|
440
|
+
description: def.description,
|
|
441
|
+
parameters: typeof def.parameters === "object" && def.parameters !== null &&
|
|
442
|
+
!Array.isArray(def.parameters)
|
|
443
|
+
? def.parameters
|
|
444
|
+
: { type: "object", properties: {} },
|
|
445
|
+
}));
|
|
446
|
+
}
|
|
447
|
+
|
|
421
448
|
type ResolvedModelTransport = {
|
|
422
449
|
requestedModel: string;
|
|
423
450
|
resolvedModelString: string;
|
|
@@ -722,6 +749,7 @@ export class AgentRuntime {
|
|
|
722
749
|
// Request-scoped skill policy (not class-level mutable state)
|
|
723
750
|
let activeSkillPolicy: string[] | undefined;
|
|
724
751
|
const allowedRemoteToolNames = getRuntimeAllowedRemoteTools(this.config);
|
|
752
|
+
const forwardedRemoteToolDefinitions = getRuntimeForwardedIntegrationToolDefs(this.config);
|
|
725
753
|
let currentSystemPrompt = systemPrompt;
|
|
726
754
|
let currentRuntimeContext = runtimeContext;
|
|
727
755
|
|
|
@@ -743,6 +771,7 @@ export class AgentRuntime {
|
|
|
743
771
|
let tools = isLocal ? [] : await getAvailableTools(this.config.tools, {
|
|
744
772
|
includeSkillTools: Boolean(this.config.skills),
|
|
745
773
|
allowedRemoteToolNames,
|
|
774
|
+
forwardedRemoteToolDefinitions,
|
|
746
775
|
remoteToolSources: this.config.remoteTools,
|
|
747
776
|
remoteToolContext: toolContext,
|
|
748
777
|
});
|
|
@@ -1004,6 +1033,7 @@ export class AgentRuntime {
|
|
|
1004
1033
|
let finalFinishReason: string | undefined;
|
|
1005
1034
|
let latestAssistantText = "";
|
|
1006
1035
|
const allowedRemoteToolNames = getRuntimeAllowedRemoteTools(this.config);
|
|
1036
|
+
const forwardedRemoteToolDefinitions = getRuntimeForwardedIntegrationToolDefs(this.config);
|
|
1007
1037
|
let currentSystemPrompt = systemPrompt;
|
|
1008
1038
|
let currentRuntimeContext = runtimeContext;
|
|
1009
1039
|
|
|
@@ -1026,6 +1056,7 @@ export class AgentRuntime {
|
|
|
1026
1056
|
let tools = isLocalStreaming ? [] : await getAvailableTools(this.config.tools, {
|
|
1027
1057
|
includeSkillTools: Boolean(this.config.skills),
|
|
1028
1058
|
allowedRemoteToolNames,
|
|
1059
|
+
forwardedRemoteToolDefinitions,
|
|
1029
1060
|
remoteToolSources: this.config.remoteTools,
|
|
1030
1061
|
remoteToolContext: toolContext,
|
|
1031
1062
|
});
|
|
@@ -297,6 +297,27 @@ function addToolDefinition(
|
|
|
297
297
|
tools.push(def);
|
|
298
298
|
}
|
|
299
299
|
|
|
300
|
+
/**
|
|
301
|
+
* Merge forwarded integration tool definitions into the remote defs array.
|
|
302
|
+
* Forwarded definitions are provided by the API when the runtime cannot
|
|
303
|
+
* fetch them directly (e.g., the runtime token lacks user auth).
|
|
304
|
+
* Only appends definitions not already present in the array.
|
|
305
|
+
*/
|
|
306
|
+
function appendForwardedToolDefinitions(
|
|
307
|
+
remoteDefs: ToolDefinition[],
|
|
308
|
+
forwarded: ToolDefinition[] | undefined,
|
|
309
|
+
allowedNames: string[] | undefined,
|
|
310
|
+
): void {
|
|
311
|
+
if (!forwarded?.length) return;
|
|
312
|
+
const existing = new Set(remoteDefs.map((def) => def.name));
|
|
313
|
+
for (const def of forwarded) {
|
|
314
|
+
if (existing.has(def.name)) continue;
|
|
315
|
+
if (allowedNames && !allowedNames.includes(def.name)) continue;
|
|
316
|
+
remoteDefs.push(def);
|
|
317
|
+
existing.add(def.name);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
300
321
|
/**
|
|
301
322
|
* Get available tools based on agent configuration.
|
|
302
323
|
* When tools === true, loads all tools from registry.
|
|
@@ -311,6 +332,7 @@ export async function getAvailableTools(
|
|
|
311
332
|
includeSkillTools?: boolean;
|
|
312
333
|
includeIntegrationTools?: boolean;
|
|
313
334
|
allowedRemoteToolNames?: string[];
|
|
335
|
+
forwardedRemoteToolDefinitions?: ToolDefinition[];
|
|
314
336
|
remoteToolSources?: RemoteToolSource[];
|
|
315
337
|
remoteToolContext?: ToolExecutionContext;
|
|
316
338
|
},
|
|
@@ -333,6 +355,11 @@ export async function getAvailableTools(
|
|
|
333
355
|
|
|
334
356
|
// Append remote integration tools (per-request, project-scoped)
|
|
335
357
|
const remoteDefs = await getRemoteToolDefinitions(options);
|
|
358
|
+
appendForwardedToolDefinitions(
|
|
359
|
+
remoteDefs,
|
|
360
|
+
options?.forwardedRemoteToolDefinitions,
|
|
361
|
+
options?.allowedRemoteToolNames,
|
|
362
|
+
);
|
|
336
363
|
for (const def of remoteDefs) {
|
|
337
364
|
logToolDefinition(def.name, def);
|
|
338
365
|
}
|
|
@@ -343,6 +370,11 @@ export async function getAvailableTools(
|
|
|
343
370
|
|
|
344
371
|
const tools: ToolDefinition[] = [];
|
|
345
372
|
const remoteDefs = await getRemoteToolDefinitions(options);
|
|
373
|
+
appendForwardedToolDefinitions(
|
|
374
|
+
remoteDefs,
|
|
375
|
+
options?.forwardedRemoteToolDefinitions,
|
|
376
|
+
options?.allowedRemoteToolNames,
|
|
377
|
+
);
|
|
346
378
|
const remoteToolNames = new Set(remoteDefs.map((def) => def.name));
|
|
347
379
|
const explicitlyRequestedRemoteToolNames = new Set<string>();
|
|
348
380
|
const unresolvedConfiguredToolNames: string[] = [];
|
|
@@ -25,6 +25,7 @@ const logger = serverLogger.component("internal-agent-run-stream");
|
|
|
25
25
|
type RuntimeFilteredAgent = Agent & {
|
|
26
26
|
config: Agent["config"] & {
|
|
27
27
|
__vfAllowedRemoteTools?: string[];
|
|
28
|
+
__vfForwardedIntegrationToolDefs?: ForwardedToolDef[];
|
|
28
29
|
};
|
|
29
30
|
};
|
|
30
31
|
|
|
@@ -137,6 +138,35 @@ function getAllowedRemoteToolNames(
|
|
|
137
138
|
return allowedTools.every((toolName) => typeof toolName === "string") ? allowedTools : [];
|
|
138
139
|
}
|
|
139
140
|
|
|
141
|
+
interface ForwardedToolDef {
|
|
142
|
+
name: string;
|
|
143
|
+
description: string;
|
|
144
|
+
inputSchema?: Record<string, unknown>;
|
|
145
|
+
parameters?: Record<string, unknown>;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function getForwardedIntegrationToolDefinitions(
|
|
149
|
+
forwardedProps: RuntimeRunAgentInput["forwardedProps"],
|
|
150
|
+
): ForwardedToolDef[] | undefined {
|
|
151
|
+
const runtimeOverrides = isRecord(forwardedProps?.runtimeOverrides)
|
|
152
|
+
? forwardedProps.runtimeOverrides
|
|
153
|
+
: null;
|
|
154
|
+
if (!runtimeOverrides) return undefined;
|
|
155
|
+
const defs = runtimeOverrides.integrationToolDefinitions;
|
|
156
|
+
if (!Array.isArray(defs) || defs.length === 0) return undefined;
|
|
157
|
+
return defs.filter(
|
|
158
|
+
(def): def is ForwardedToolDef =>
|
|
159
|
+
typeof def === "object" &&
|
|
160
|
+
def !== null &&
|
|
161
|
+
typeof def.name === "string" &&
|
|
162
|
+
typeof def.description === "string",
|
|
163
|
+
).map((def) => ({
|
|
164
|
+
name: def.name,
|
|
165
|
+
description: def.description,
|
|
166
|
+
parameters: def.inputSchema ?? def.parameters ?? { type: "object", properties: {} },
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
|
|
140
170
|
export async function createRuntimeAgentStreamResponse(
|
|
141
171
|
input: RuntimeRunAgentInput,
|
|
142
172
|
agent: Agent,
|
|
@@ -157,6 +187,7 @@ export async function createRuntimeAgentStreamResponse(
|
|
|
157
187
|
|
|
158
188
|
const mergedTools = buildMergedTools(agent, input, deps.sessionManager);
|
|
159
189
|
const allowedRemoteToolNames = getAllowedRemoteToolNames(input.forwardedProps);
|
|
190
|
+
const forwardedIntegrationToolDefs = getForwardedIntegrationToolDefinitions(input.forwardedProps);
|
|
160
191
|
const runtimeAgent: RuntimeFilteredAgent = {
|
|
161
192
|
...agent,
|
|
162
193
|
config: {
|
|
@@ -165,6 +196,9 @@ export async function createRuntimeAgentStreamResponse(
|
|
|
165
196
|
...(allowedRemoteToolNames !== undefined
|
|
166
197
|
? { __vfAllowedRemoteTools: allowedRemoteToolNames }
|
|
167
198
|
: {}),
|
|
199
|
+
...(forwardedIntegrationToolDefs !== undefined
|
|
200
|
+
? { __vfForwardedIntegrationToolDefs: forwardedIntegrationToolDefs }
|
|
201
|
+
: {}),
|
|
168
202
|
},
|
|
169
203
|
};
|
|
170
204
|
const runtime = deps.createRuntime?.(runtimeAgent, mergedTools) ??
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
resolveSandboxApiUrl,
|
|
11
11
|
resolveSandboxAuthToken,
|
|
12
12
|
type SandboxOptions,
|
|
13
|
-
waitForSandboxReady,
|
|
14
13
|
} from "./sandbox.js";
|
|
15
14
|
|
|
16
15
|
export interface LazySandboxOptions extends SandboxOptions {
|
|
@@ -19,6 +18,7 @@ export interface LazySandboxOptions extends SandboxOptions {
|
|
|
19
18
|
pollIntervalMs?: number;
|
|
20
19
|
heartbeatIntervalMs?: number;
|
|
21
20
|
heartbeatGraceMs?: number;
|
|
21
|
+
controlRequestTimeoutMs?: number;
|
|
22
22
|
execStartTimeoutMs?: number;
|
|
23
23
|
execStartMaxAttempts?: number;
|
|
24
24
|
execStartRetryDelayMs?: number;
|
|
@@ -35,6 +35,7 @@ const DEFAULT_STARTUP_TIMEOUT_MS = 180_000;
|
|
|
35
35
|
const DEFAULT_POLL_INTERVAL_MS = 2_000;
|
|
36
36
|
const DEFAULT_HEARTBEAT_INTERVAL_MS = 30_000;
|
|
37
37
|
const DEFAULT_HEARTBEAT_GRACE_MS = 5_000;
|
|
38
|
+
const DEFAULT_CONTROL_REQUEST_TIMEOUT_MS = 15_000;
|
|
38
39
|
const DEFAULT_EXEC_START_TIMEOUT_MS = 30_000;
|
|
39
40
|
const DEFAULT_EXEC_START_MAX_ATTEMPTS = 3;
|
|
40
41
|
const DEFAULT_EXEC_START_RETRY_DELAY_MS = 1_000;
|
|
@@ -54,6 +55,7 @@ export class LazySandbox {
|
|
|
54
55
|
private readonly pollIntervalMs: number;
|
|
55
56
|
private readonly heartbeatIntervalMs: number;
|
|
56
57
|
private readonly heartbeatGraceMs: number;
|
|
58
|
+
private readonly controlRequestTimeoutMs: number;
|
|
57
59
|
private readonly execStartTimeoutMs: number;
|
|
58
60
|
private readonly execStartMaxAttempts: number;
|
|
59
61
|
private readonly execStartRetryDelayMs: number;
|
|
@@ -82,6 +84,8 @@ export class LazySandbox {
|
|
|
82
84
|
this.pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
83
85
|
this.heartbeatIntervalMs = options.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_INTERVAL_MS;
|
|
84
86
|
this.heartbeatGraceMs = options.heartbeatGraceMs ?? DEFAULT_HEARTBEAT_GRACE_MS;
|
|
87
|
+
this.controlRequestTimeoutMs = options.controlRequestTimeoutMs ??
|
|
88
|
+
DEFAULT_CONTROL_REQUEST_TIMEOUT_MS;
|
|
85
89
|
this.execStartTimeoutMs = options.execStartTimeoutMs ?? DEFAULT_EXEC_START_TIMEOUT_MS;
|
|
86
90
|
this.execStartMaxAttempts = options.execStartMaxAttempts ?? DEFAULT_EXEC_START_MAX_ATTEMPTS;
|
|
87
91
|
this.execStartRetryDelayMs = options.execStartRetryDelayMs ??
|
|
@@ -175,9 +179,12 @@ export class LazySandbox {
|
|
|
175
179
|
async readFile(path: string): Promise<string> {
|
|
176
180
|
await this.touchSession();
|
|
177
181
|
|
|
178
|
-
const res = await
|
|
179
|
-
|
|
180
|
-
|
|
182
|
+
const res = await this.fetchControl(
|
|
183
|
+
`${this.requireEndpoint()}/file?path=${encodeURIComponent(path)}`,
|
|
184
|
+
{
|
|
185
|
+
headers: this.authHeaders(),
|
|
186
|
+
},
|
|
187
|
+
);
|
|
181
188
|
|
|
182
189
|
if (!res.ok) {
|
|
183
190
|
throw REQUEST_ERROR.create({ detail: `Read file failed: ${res.status} ${await res.text()}` });
|
|
@@ -189,7 +196,7 @@ export class LazySandbox {
|
|
|
189
196
|
async writeFiles(files: Array<{ path: string; content: string }>): Promise<void> {
|
|
190
197
|
await this.touchSession();
|
|
191
198
|
|
|
192
|
-
const res = await
|
|
199
|
+
const res = await this.fetchControl(`${this.requireEndpoint()}/files`, {
|
|
193
200
|
method: "POST",
|
|
194
201
|
headers: this.jsonHeaders(),
|
|
195
202
|
body: JSON.stringify({ files }),
|
|
@@ -206,7 +213,7 @@ export class LazySandbox {
|
|
|
206
213
|
await this.touchSession();
|
|
207
214
|
const endpoint = this.resolveRuntimeEndpoint();
|
|
208
215
|
|
|
209
|
-
const res = await
|
|
216
|
+
const res = await this.fetchControl(`${endpoint}/exec/jobs`, {
|
|
210
217
|
method: "POST",
|
|
211
218
|
headers: this.jsonHeaders(),
|
|
212
219
|
body: JSON.stringify({ command, ...this.resolveExecOptions(options) }),
|
|
@@ -226,7 +233,7 @@ export class LazySandbox {
|
|
|
226
233
|
async getCommandJob(jobId: string): Promise<CommandJob> {
|
|
227
234
|
const endpoint = await this.resolveCommandJobEndpoint(jobId);
|
|
228
235
|
|
|
229
|
-
const res = await
|
|
236
|
+
const res = await this.fetchControl(`${endpoint}/exec/jobs/${jobId}`, {
|
|
230
237
|
headers: this.authHeaders(),
|
|
231
238
|
});
|
|
232
239
|
|
|
@@ -244,7 +251,7 @@ export class LazySandbox {
|
|
|
244
251
|
async getCommandJobOutput(jobId: string): Promise<CommandJobOutput> {
|
|
245
252
|
const endpoint = await this.resolveCommandJobEndpoint(jobId);
|
|
246
253
|
|
|
247
|
-
const res = await
|
|
254
|
+
const res = await this.fetchControl(`${endpoint}/exec/jobs/${jobId}/output`, {
|
|
248
255
|
headers: this.authHeaders(),
|
|
249
256
|
});
|
|
250
257
|
|
|
@@ -269,7 +276,7 @@ export class LazySandbox {
|
|
|
269
276
|
async listCommandJobs(): Promise<CommandJob[]> {
|
|
270
277
|
await this.ensure();
|
|
271
278
|
|
|
272
|
-
const res = await
|
|
279
|
+
const res = await this.fetchControl(`${this.requireEndpoint()}/exec/jobs`, {
|
|
273
280
|
headers: this.authHeaders(),
|
|
274
281
|
});
|
|
275
282
|
|
|
@@ -287,7 +294,7 @@ export class LazySandbox {
|
|
|
287
294
|
async cancelCommandJob(jobId: string): Promise<CommandJob> {
|
|
288
295
|
const endpoint = await this.resolveCommandJobEndpoint(jobId);
|
|
289
296
|
|
|
290
|
-
const res = await
|
|
297
|
+
const res = await this.fetchControl(`${endpoint}/exec/jobs/${jobId}/cancel`, {
|
|
291
298
|
method: "POST",
|
|
292
299
|
headers: this.authHeaders(),
|
|
293
300
|
});
|
|
@@ -320,10 +327,13 @@ export class LazySandbox {
|
|
|
320
327
|
}
|
|
321
328
|
|
|
322
329
|
const promise = (async () => {
|
|
323
|
-
const res = await
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
330
|
+
const res = await this.fetchControl(
|
|
331
|
+
`${this.apiUrl}/sandbox-sessions/${currentSessionId}/heartbeat`,
|
|
332
|
+
{
|
|
333
|
+
method: "POST",
|
|
334
|
+
headers: this.authHeaders(),
|
|
335
|
+
},
|
|
336
|
+
);
|
|
327
337
|
|
|
328
338
|
if (!res.ok) {
|
|
329
339
|
if (this.sessionId === currentSessionId) {
|
|
@@ -400,7 +410,7 @@ export class LazySandbox {
|
|
|
400
410
|
|
|
401
411
|
private async bootstrapSession(): Promise<void> {
|
|
402
412
|
const projectId = this.resolveProjectId();
|
|
403
|
-
const res = await
|
|
413
|
+
const res = await this.fetchControl(`${this.apiUrl}/sandbox-sessions`, {
|
|
404
414
|
method: "POST",
|
|
405
415
|
headers: this.jsonHeaders(),
|
|
406
416
|
body: JSON.stringify(projectId ? { project_id: projectId } : {}),
|
|
@@ -436,26 +446,35 @@ export class LazySandbox {
|
|
|
436
446
|
return session.endpoint;
|
|
437
447
|
}
|
|
438
448
|
|
|
439
|
-
await
|
|
440
|
-
|
|
441
|
-
id: session.id,
|
|
442
|
-
authToken: this.authToken,
|
|
443
|
-
maxWaitMs: this.startupTimeoutMs,
|
|
444
|
-
pollIntervalMs: this.pollIntervalMs,
|
|
445
|
-
});
|
|
449
|
+
return (await this.waitForReadySession(session.id)).endpoint;
|
|
450
|
+
}
|
|
446
451
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
});
|
|
452
|
+
private async waitForReadySession(sessionId: string): Promise<SandboxSessionRecord> {
|
|
453
|
+
const start = Date.now();
|
|
450
454
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
455
|
+
while (Date.now() - start < this.startupTimeoutMs) {
|
|
456
|
+
await new Promise((resolve) => dntShim.setTimeout(resolve, this.pollIntervalMs));
|
|
457
|
+
|
|
458
|
+
const res = await this.fetchControl(`${this.apiUrl}/sandbox-sessions/${sessionId}`, {
|
|
459
|
+
headers: this.authHeaders(),
|
|
454
460
|
});
|
|
461
|
+
|
|
462
|
+
if (!res.ok) {
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
const session = await res.json() as SandboxSessionRecord;
|
|
467
|
+
if (session.status === "running") {
|
|
468
|
+
return session;
|
|
469
|
+
}
|
|
470
|
+
if (session.status === "error" || session.status === "deleting") {
|
|
471
|
+
throw REQUEST_ERROR.create({
|
|
472
|
+
detail: `Sandbox failed to start: status=${session.status}`,
|
|
473
|
+
});
|
|
474
|
+
}
|
|
455
475
|
}
|
|
456
476
|
|
|
457
|
-
|
|
458
|
-
return nextSession.endpoint;
|
|
477
|
+
throw REQUEST_ERROR.create({ detail: "Sandbox did not become ready within timeout" });
|
|
459
478
|
}
|
|
460
479
|
|
|
461
480
|
private async touchSession(): Promise<void> {
|
|
@@ -489,7 +508,7 @@ export class LazySandbox {
|
|
|
489
508
|
}
|
|
490
509
|
|
|
491
510
|
private async deleteSession(sessionId: string): Promise<void> {
|
|
492
|
-
await
|
|
511
|
+
await this.fetchControl(`${this.apiUrl}/sandbox-sessions/${sessionId}`, {
|
|
493
512
|
method: "DELETE",
|
|
494
513
|
headers: this.authHeaders(),
|
|
495
514
|
});
|
|
@@ -584,14 +603,11 @@ export class LazySandbox {
|
|
|
584
603
|
}
|
|
585
604
|
|
|
586
605
|
private async fetchExecStart(url: string, init: RequestInit): Promise<Response> {
|
|
587
|
-
|
|
588
|
-
|
|
606
|
+
return fetchWithTimeout(url, this.execStartTimeoutMs, init);
|
|
607
|
+
}
|
|
589
608
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
} finally {
|
|
593
|
-
clearTimeout(timeout);
|
|
594
|
-
}
|
|
609
|
+
private async fetchControl(url: string, init: RequestInit = {}): Promise<Response> {
|
|
610
|
+
return fetchWithTimeout(url, this.controlRequestTimeoutMs, init);
|
|
595
611
|
}
|
|
596
612
|
|
|
597
613
|
private waitForExecStartRetry(): Promise<void> {
|
|
@@ -654,6 +670,25 @@ function shouldReprovisionAfterExecStartFailure(error: unknown): boolean {
|
|
|
654
670
|
REPROVISIONABLE_EXEC_START_ERROR_CODES.has(cause.code);
|
|
655
671
|
}
|
|
656
672
|
|
|
673
|
+
async function fetchWithTimeout(
|
|
674
|
+
url: string,
|
|
675
|
+
timeoutMs: number,
|
|
676
|
+
init: RequestInit = {},
|
|
677
|
+
): Promise<Response> {
|
|
678
|
+
if (timeoutMs <= 0) {
|
|
679
|
+
return await fetch(url, init);
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
const controller = new AbortController();
|
|
683
|
+
const timeout = dntShim.setTimeout(() => controller.abort(), timeoutMs);
|
|
684
|
+
|
|
685
|
+
try {
|
|
686
|
+
return await fetch(url, { ...init, signal: controller.signal });
|
|
687
|
+
} finally {
|
|
688
|
+
clearTimeout(timeout);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
657
692
|
function mapCommandJob(json: Record<string, unknown>): CommandJob {
|
|
658
693
|
return {
|
|
659
694
|
id: json.id as string,
|