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 CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.281",
3
+ "version": "0.1.283",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "workspace": [
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/runtime/index.ts"],"names":[],"mappings":"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"}
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;AAoBD;;;;;;;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,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACvC,iBAAiB,CAAC,EAAE,oBAAoB,CAAC;CAC1C,GACA,OAAO,CAAC,cAAc,EAAE,CAAC,CA+E3B"}
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;AAYxD,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;AA4FD,wBAAsB,gCAAgC,CACpD,KAAK,EAAE,oBAAoB,EAC3B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,+BAA+B,GACpC,OAAO,CAAC,QAAQ,CAAC,CA8OnB"}
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":"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"}
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, waitForSandboxReady, } from "./sandbox.js";
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 fetch(`${this.requireEndpoint()}/file?path=${encodeURIComponent(path)}`, {
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 fetch(`${this.requireEndpoint()}/files`, {
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 fetch(`${endpoint}/exec/jobs`, {
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 fetch(`${endpoint}/exec/jobs/${jobId}`, {
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 fetch(`${endpoint}/exec/jobs/${jobId}/output`, {
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 fetch(`${this.requireEndpoint()}/exec/jobs`, {
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 fetch(`${endpoint}/exec/jobs/${jobId}/cancel`, {
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 fetch(`${this.apiUrl}/sandbox-sessions/${currentSessionId}/heartbeat`, {
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 fetch(`${this.apiUrl}/sandbox-sessions`, {
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 waitForSandboxReady({
345
- apiUrl: this.apiUrl,
346
- id: session.id,
347
- authToken: this.authToken,
348
- maxWaitMs: this.startupTimeoutMs,
349
- pollIntervalMs: this.pollIntervalMs,
350
- });
351
- const res = await fetch(`${this.apiUrl}/sandbox-sessions/${session.id}`, {
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
- const nextSession = await res.json();
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 fetch(`${this.apiUrl}/sandbox-sessions/${sessionId}`, {
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
- const controller = new AbortController();
470
- const timeout = dntShim.setTimeout(() => controller.abort(), this.execStartTimeoutMs);
471
- try {
472
- return await fetch(url, { ...init, signal: controller.signal });
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.281";
1
+ export declare const VERSION = "0.1.283";
2
2
  //# sourceMappingURL=version-constant.d.ts.map
@@ -1,3 +1,3 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
- export const VERSION = "0.1.281";
3
+ export const VERSION = "0.1.283";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.281",
3
+ "version": "0.1.283",
4
4
  "description": "The simplest way to build AI-powered apps",
5
5
  "keywords": [
6
6
  "react",
package/src/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.281",
3
+ "version": "0.1.283",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "workspace": [
@@ -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 fetch(`${this.requireEndpoint()}/file?path=${encodeURIComponent(path)}`, {
179
- headers: this.authHeaders(),
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 fetch(`${this.requireEndpoint()}/files`, {
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 fetch(`${endpoint}/exec/jobs`, {
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 fetch(`${endpoint}/exec/jobs/${jobId}`, {
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 fetch(`${endpoint}/exec/jobs/${jobId}/output`, {
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 fetch(`${this.requireEndpoint()}/exec/jobs`, {
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 fetch(`${endpoint}/exec/jobs/${jobId}/cancel`, {
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 fetch(`${this.apiUrl}/sandbox-sessions/${currentSessionId}/heartbeat`, {
324
- method: "POST",
325
- headers: this.authHeaders(),
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 fetch(`${this.apiUrl}/sandbox-sessions`, {
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 waitForSandboxReady({
440
- apiUrl: this.apiUrl,
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
- const res = await fetch(`${this.apiUrl}/sandbox-sessions/${session.id}`, {
448
- headers: this.authHeaders(),
449
- });
452
+ private async waitForReadySession(sessionId: string): Promise<SandboxSessionRecord> {
453
+ const start = Date.now();
450
454
 
451
- if (!res.ok) {
452
- throw REQUEST_ERROR.create({
453
- detail: `Failed to get sandbox: ${res.status} ${await res.text()}`,
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
- const nextSession = await res.json();
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 fetch(`${this.apiUrl}/sandbox-sessions/${sessionId}`, {
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
- const controller = new AbortController();
588
- const timeout = dntShim.setTimeout(() => controller.abort(), this.execStartTimeoutMs);
606
+ return fetchWithTimeout(url, this.execStartTimeoutMs, init);
607
+ }
589
608
 
590
- try {
591
- return await fetch(url, { ...init, signal: controller.signal });
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,
@@ -1,3 +1,3 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
- export const VERSION = "0.1.281";
3
+ export const VERSION = "0.1.283";