@assemblyline-agents/runtime 3.1.0 → 3.3.0

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.
Files changed (113) hide show
  1. package/README.md +6 -0
  2. package/dist/agent-hook-controller-factory.d.ts +28 -0
  3. package/dist/agent-hook-controller-factory.d.ts.map +1 -0
  4. package/dist/agent-hook-controller-factory.js +83 -0
  5. package/dist/agent-hook-controller-factory.js.map +1 -0
  6. package/dist/background-subagents.d.ts +43 -0
  7. package/dist/background-subagents.d.ts.map +1 -0
  8. package/dist/background-subagents.js +309 -0
  9. package/dist/background-subagents.js.map +1 -0
  10. package/dist/builtin-tool-executors.d.ts +1 -0
  11. package/dist/builtin-tool-executors.d.ts.map +1 -1
  12. package/dist/builtin-tool-executors.js +38 -30
  13. package/dist/builtin-tool-executors.js.map +1 -1
  14. package/dist/builtin-tools.d.ts.map +1 -1
  15. package/dist/builtin-tools.js +5 -4
  16. package/dist/builtin-tools.js.map +1 -1
  17. package/dist/capability-catalog.d.ts +8 -5
  18. package/dist/capability-catalog.d.ts.map +1 -1
  19. package/dist/capability-catalog.js +28 -1
  20. package/dist/capability-catalog.js.map +1 -1
  21. package/dist/conversation-turn-dispatch.d.ts +1 -1
  22. package/dist/conversation-turn-dispatch.d.ts.map +1 -1
  23. package/dist/conversation-turn-dispatch.js +25 -1
  24. package/dist/conversation-turn-dispatch.js.map +1 -1
  25. package/dist/dynamic-schedule-runtime.d.ts +42 -0
  26. package/dist/dynamic-schedule-runtime.d.ts.map +1 -0
  27. package/dist/dynamic-schedule-runtime.js +57 -0
  28. package/dist/dynamic-schedule-runtime.js.map +1 -0
  29. package/dist/harness-loop.d.ts +6 -6
  30. package/dist/harness-loop.d.ts.map +1 -1
  31. package/dist/harness-loop.js +26 -15
  32. package/dist/harness-loop.js.map +1 -1
  33. package/dist/in-memory-conversation-turn-store.d.ts +1 -0
  34. package/dist/in-memory-conversation-turn-store.d.ts.map +1 -1
  35. package/dist/in-memory-conversation-turn-store.js +11 -0
  36. package/dist/in-memory-conversation-turn-store.js.map +1 -1
  37. package/dist/index.d.ts +23 -41
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +172 -169
  40. package/dist/index.js.map +1 -1
  41. package/dist/local-sandbox.d.ts.map +1 -1
  42. package/dist/local-sandbox.js +2 -1
  43. package/dist/local-sandbox.js.map +1 -1
  44. package/dist/public-api.d.ts +2 -2
  45. package/dist/public-api.d.ts.map +1 -1
  46. package/dist/public-api.js.map +1 -1
  47. package/dist/replay-resume.d.ts.map +1 -1
  48. package/dist/replay-resume.js +3 -2
  49. package/dist/replay-resume.js.map +1 -1
  50. package/dist/run-heartbeat.d.ts +45 -18
  51. package/dist/run-heartbeat.d.ts.map +1 -1
  52. package/dist/run-heartbeat.js +120 -14
  53. package/dist/run-heartbeat.js.map +1 -1
  54. package/dist/run-outcome.d.ts +1 -1
  55. package/dist/run-outcome.d.ts.map +1 -1
  56. package/dist/run-outcome.js.map +1 -1
  57. package/dist/run-recovery.d.ts +9 -1
  58. package/dist/run-recovery.d.ts.map +1 -1
  59. package/dist/run-recovery.js +26 -1
  60. package/dist/run-recovery.js.map +1 -1
  61. package/dist/runtime-types.d.ts +23 -3
  62. package/dist/runtime-types.d.ts.map +1 -1
  63. package/dist/sandbox-authored-tool-child.d.ts +7 -0
  64. package/dist/sandbox-authored-tool-child.d.ts.map +1 -0
  65. package/dist/sandbox-authored-tool-child.js +217 -0
  66. package/dist/sandbox-authored-tool-child.js.map +1 -0
  67. package/dist/sandbox-authored-tool-executor.d.ts +23 -0
  68. package/dist/sandbox-authored-tool-executor.d.ts.map +1 -0
  69. package/dist/sandbox-authored-tool-executor.js +290 -0
  70. package/dist/sandbox-authored-tool-executor.js.map +1 -0
  71. package/dist/sandbox-session-lifecycle.d.ts +1 -0
  72. package/dist/sandbox-session-lifecycle.d.ts.map +1 -1
  73. package/dist/sandbox-session-lifecycle.js +48 -16
  74. package/dist/sandbox-session-lifecycle.js.map +1 -1
  75. package/dist/sandbox-tool-bridge.d.ts +19 -0
  76. package/dist/sandbox-tool-bridge.d.ts.map +1 -0
  77. package/dist/sandbox-tool-bridge.js +227 -0
  78. package/dist/sandbox-tool-bridge.js.map +1 -0
  79. package/dist/scheduled-delivery.d.ts +6 -0
  80. package/dist/scheduled-delivery.d.ts.map +1 -0
  81. package/dist/scheduled-delivery.js +117 -0
  82. package/dist/scheduled-delivery.js.map +1 -0
  83. package/dist/source-loader.d.ts +10 -0
  84. package/dist/source-loader.d.ts.map +1 -1
  85. package/dist/source-loader.js +64 -3
  86. package/dist/source-loader.js.map +1 -1
  87. package/dist/state-stores.js +1 -1
  88. package/dist/state-stores.js.map +1 -1
  89. package/dist/state.d.ts +2 -1
  90. package/dist/state.d.ts.map +1 -1
  91. package/dist/state.js +1 -0
  92. package/dist/state.js.map +1 -1
  93. package/dist/storage.d.ts +1 -0
  94. package/dist/storage.d.ts.map +1 -1
  95. package/dist/storage.js +3 -0
  96. package/dist/storage.js.map +1 -1
  97. package/dist/subagent-execution.d.ts +17 -1
  98. package/dist/subagent-execution.d.ts.map +1 -1
  99. package/dist/subagent-execution.js +217 -6
  100. package/dist/subagent-execution.js.map +1 -1
  101. package/dist/subagent-handoff.d.ts +44 -0
  102. package/dist/subagent-handoff.d.ts.map +1 -0
  103. package/dist/subagent-handoff.js +271 -0
  104. package/dist/subagent-handoff.js.map +1 -0
  105. package/dist/tool-apis.d.ts +1 -1
  106. package/dist/tool-apis.d.ts.map +1 -1
  107. package/dist/tool-apis.js +17 -10
  108. package/dist/tool-apis.js.map +1 -1
  109. package/dist/tool-execution.d.ts +17 -3
  110. package/dist/tool-execution.d.ts.map +1 -1
  111. package/dist/tool-execution.js +147 -20
  112. package/dist/tool-execution.js.map +1 -1
  113. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -5,15 +5,15 @@ export * from "./public-api.js";
5
5
  export { builtInToolDefaults, FILES_MOUNT_TOOL_NAME, FILES_SEARCH_TOOL_NAME, HISTORY_SEARCH_TOOL_NAME, PAIR_TOOL_NAME } from "./builtin-tools.js";
6
6
  export { inspectAgentCapabilities } from "./capability-inspection.js";
7
7
  export { CONNECTION_PAIRING_UNAVAILABLE_EVENT, executePairTool } from "./builtin-tool-executors.js";
8
- import { resolveEvalToolStub, validateEvalRunOptions } from "./eval-run-options.js";
8
+ import { evalRunOptionsForRun, resolveEvalToolStub, validateEvalRunOptions } from "./eval-run-options.js";
9
9
  import { rememberDefaultOutboundRoute } from "./default-outbound-route.js";
10
10
  import { audienceFromRun, audienceUserKey, normalizeAgentAudience } from "./audience.js";
11
11
  import { AgentSourceModuleLoader } from "./source-loader.js";
12
+ import { SandboxAuthoredToolExecutor, resolveAuthoredToolExecutionPolicy } from "./sandbox-authored-tool-executor.js";
12
13
  import { AgentEventHandlerRegistry } from "./agent-event-handlers.js";
13
- import { immutableAgentRunContext } from "./agent-hook-evaluation.js";
14
- import { hookCapabilityCatalog } from "./agent-hook-context.js";
15
- import { flattenSubagents, rootAgentSurface, subagentSurface, surfaceForPath, surfaceForRun, durableAgentSurfaceScope } from "./agent-surface.js";
16
- import { createRuntimeAgentHookController, recoverAgentHookController, removeTerminalAgentHookState, resolvedInstructionsForRun as resolvedHookInstructionsForRun } from "./agent-hook-run-lifecycle.js";
14
+ import { createMainAgentHookController as createMainAgentHookControllerImpl, createSubagentHookController as createSubagentHookControllerImpl } from "./agent-hook-controller-factory.js";
15
+ import { durableAgentSurfaceScope, flattenSubagents, surfaceForPath, surfaceForRun } from "./agent-surface.js";
16
+ import { recoverAgentHookController, removeTerminalAgentHookState, resolvedInstructionsForRun as resolvedHookInstructionsForRun } from "./agent-hook-run-lifecycle.js";
17
17
  import { compiledChannelProvider, providerIngressSecurityError, providerIngressSecurityWarnings, resolveCoreToolPolicy, trustedAttachmentProviderForTurn } from "./security.js";
18
18
  export { constantTimeSecretEqual } from "./security.js";
19
19
  export { RUN_STREAM_TERMINAL_EVENTS } from "./run-stream.js";
@@ -24,7 +24,7 @@ import { resolveBooleanEnv, resolveNonNegativeIntegerEnv, resolvePositiveInteger
24
24
  import { humanInputModeForChannel, withHumanInputMode } from "./human-input-routing.js";
25
25
  import { RunEventBus, withRunEventPublishing } from "./run-stream.js";
26
26
  import { failRun as failRunImpl, handleRunExecutionError, logTerminalRunEvent, settleCompletionBoundaryControlImpl } from "./run-outcome.js";
27
- import { cacheRunControlSignal, registerRunAbortController, startRunHeartbeatImpl, trackActiveRunHeartbeat } from "./run-heartbeat.js";
27
+ import { eventRenewsRunProgress, RunProgressSupervisor } from "./run-heartbeat.js";
28
28
  import { redactTruncateJson } from "./content-capture.js";
29
29
  import { isJsonObject, safeJson } from "./json-util.js";
30
30
  import { sandboxSessionKeyForRun } from "./sandbox-session-key.js";
@@ -55,7 +55,8 @@ import { beginChannelTurnImpl, completeRunImpl, latestRunFailureMessageImpl, rec
55
55
  import { backfillMemoryDocumentsFromFileIndexesImpl, hydrateLogicalPathForToolImpl, listResourcesForRunImpl, memoryScopeForRunImpl, projectLoadedSkillsIntoSandboxImpl, projectResourcesForRunImpl, projectSkillIntoSandboxImpl, readResourceForRunImpl, readSandboxTombstonesWithMissingProjectedFilesImpl, recordSandboxTombstoneImpl, runMemoryEmbeddingBackfillImpl } from "./resource-projection.js";
56
56
  import { createSkillBundleIndex, createSkillResourceReader } from "./skill-bundles.js";
57
57
  import { createSandboxHandleImpl } from "./sandbox-handle.js";
58
- import { RuntimeWorkspaceManager, WorkspaceRuntimeMethods } from "./workspace-runtime.js";
58
+ import { RuntimeWorkspaceManager } from "./workspace-runtime.js";
59
+ import { DynamicScheduleRuntimeMethods } from "./dynamic-schedule-runtime.js";
59
60
  import { beginConnectionAuthorizationImpl, createConnectionRegistryForRunImpl, createConnectionRegistryForSessionImpl, createConnectionRegistryImpl, executeConnectionToolWithRecordImpl, skillLoadDetailsImpl } from "./builtin-tool-executors.js";
60
61
  import { createMemoryToolApiImpl, createResourceToolApiImpl, durableStepImpl } from "./tool-apis.js";
61
62
  import { executeToolImpl, executeToolWithRecordImpl, harnessExecuteToolImpl, modelToolsImpl, selectToolImpl, visibleToolSetImpl, wrapSandboxImpl } from "./tool-execution.js";
@@ -64,13 +65,15 @@ import { completeConnectionAuthorizationCallbackImpl, replayImpl, resumeApproval
64
65
  import { recordRunReplayStarted, rerunFromSnapshot } from "./run-replay.js";
65
66
  export { RunReplayError } from "./run-replay.js";
66
67
  import { buildRunAgentResult } from "./run-result.js";
67
- import { readSubagentImpl, runSubagentImpl, sendSubagentFollowupImpl } from "./subagent-execution.js";
68
+ import { createSubagentRunImpl, executeSubagentRunImpl, finalizeSubagentHandoffImpl, readSubagentImpl, resumeSubagentImpl, runSubagentImpl, sendSubagentFollowupImpl } from "./subagent-execution.js";
69
+ import { acceptBackgroundSubagentHandoff } from "./subagent-handoff.js";
68
70
  import { createHarnessContextImpl, DEFAULT_MAX_MODEL_ITERATIONS, DEFAULT_OUTPUT_VALIDATION_MAX_RETRIES, executeHarnessTurnImpl, persistHarnessContinuationImpl, resolveAgentHarnessImpl, runHarnessLoopImpl } from "./harness-loop.js";
69
71
  import { getAgentControlImpl, requestRunControlImpl, setAgentEnabledImpl, setAgentMaintenanceImpl } from "./operator-controls.js";
70
72
  import { acceptChannelTurnImpl, channelAttachmentResolverImpl, dispatchHttpChannelImpl, loadChannelModuleImpl, observeChannelMessageImpl, startChannelAgentTurnImpl, startChannelIngressImpl } from "./channel-ingress.js";
71
73
  import { augmentChannelContextImpl, buildContextBundleImpl, prepareConversationImpl, recentHistoryImpl } from "./conversation-context.js";
72
74
  import { loadResumableConversationTranscriptImpl } from "./conversation-transcript.js";
73
75
  import { ConversationTurnDispatcher } from "./conversation-turn-dispatch.js";
76
+ import { BackgroundSubagentCoordinator } from "./background-subagents.js";
74
77
  import { instructionsForRunTargetImpl } from "./target-instructions.js";
75
78
  import { emitTelemetrySpanImpl, runSpanAttributesImpl } from "./telemetry.js";
76
79
  import { normalizeRuntimeState } from "./state-stores.js";
@@ -92,9 +95,10 @@ import { syncMemoryFromSandbox, syncSkillsFromSandbox } from "./sandbox-state-sy
92
95
  import { acquireSandboxForRun as acquireSandboxSessionForRun } from "./sandbox-session-lifecycle.js";
93
96
  import { resolveSandboxSnapshotPolicy } from "./sandbox-snapshot-policy.js";
94
97
  import { inferToolInput } from "./channel-http-util.js";
95
- import { connectionPrincipalKeyForGrant, durableAgentScopeForManifest, isInstrumentationDefinition, normalizeCapturePolicy, randomHex, stringValue, timestamp, } from "./runtime-util.js";
96
- export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
98
+ import { connectionPrincipalKeyForGrant, durableAgentScopeForManifest, isInstrumentationDefinition, normalizeCapturePolicy, randomHex, timestamp, } from "./runtime-util.js";
99
+ export class AssemblyLineRuntime extends DynamicScheduleRuntimeMethods {
97
100
  manifest;
101
+ authoredToolExecution;
98
102
  state;
99
103
  runEventBus = new RunEventBus();
100
104
  eventHandlers;
@@ -103,6 +107,8 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
103
107
  blob;
104
108
  sandbox;
105
109
  scheduler;
110
+ scheduleStore;
111
+ schedulesConfig;
106
112
  mediaProcessors;
107
113
  deliveryMode;
108
114
  toolStubs;
@@ -130,10 +136,8 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
130
136
  skillStore;
131
137
  learningStore;
132
138
  memoryStore;
133
- scheduleStore;
134
139
  connectionDefinitionStore;
135
140
  skillsConfig;
136
- schedulesConfig;
137
141
  connectionsConfig;
138
142
  runtimeLearning;
139
143
  connectionScopeMigrated = false;
@@ -159,6 +163,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
159
163
  outputValidationMaxRetries;
160
164
  runSemaphore;
161
165
  conversationTurnDispatcher;
166
+ backgroundSubagents;
162
167
  memoryEmbeddingProvider;
163
168
  memoryEmbeddingsEnabled;
164
169
  resourceProjectionPolicy;
@@ -170,6 +175,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
170
175
  hostInstrumentationProvided;
171
176
  instrumentationConfig;
172
177
  sourceLoader;
178
+ sandboxAuthoredToolExecutor;
173
179
  skillBundleIndex;
174
180
  skillResourceReader;
175
181
  contextPolicyPromise;
@@ -177,13 +183,12 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
177
183
  runControlIntents = new Map();
178
184
  /** Runs currently owned by this process, used to route immediate control signals without leaking orphan ids. */
179
185
  activeRunExecutions = new Set();
180
- /** Deadline-fired runs (read by shouldStopRun) + their in-flight abort controllers. */
181
- runDeadlines = new Set();
182
- runAbortControllers = new Map();
183
- maxRunDurationMs;
186
+ runProgress;
187
+ runStallTimeoutMs;
184
188
  constructor(options) {
185
189
  super();
186
190
  this.manifest = options.manifest;
191
+ this.authoredToolExecution = resolveAuthoredToolExecutionPolicy(options.authoredToolExecution);
187
192
  const normalizedState = normalizeRuntimeState(options.state ?? new InMemoryStateAdapter());
188
193
  // Events fan out to live streams; terminal outcomes become log lines at
189
194
  // this one choke point (logger read lazily — assigned below).
@@ -286,7 +291,16 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
286
291
  this.deliveryQueueMaxAttempts = options.deliveryQueueMaxAttempts ?? resolvePositiveIntegerEnv(this.env.ASSEMBLY_LINE_DELIVERY_QUEUE_MAX_ATTEMPTS, 5);
287
292
  this.deliveryQueueIntervalMs = options.deliveryQueueIntervalMs ?? resolvePositiveIntegerEnv(this.env.ASSEMBLY_LINE_DELIVERY_QUEUE_INTERVAL_MS, 15_000);
288
293
  this.runHeartbeatMs = options.runHeartbeatMs ?? resolvePositiveIntegerEnv(this.env.ASSEMBLY_LINE_RUN_HEARTBEAT_MS, 30_000);
289
- this.maxRunDurationMs = options.maxRunDurationMs ?? resolveNonNegativeIntegerEnv(this.env.ASSEMBLY_LINE_MAX_RUN_DURATION_MS, 3_600_000);
294
+ this.runStallTimeoutMs = options.runStallTimeoutMs ?? resolveNonNegativeIntegerEnv(this.env.ASSEMBLY_LINE_RUN_STALL_TIMEOUT_MS, 3_600_000);
295
+ this.runProgress = new RunProgressSupervisor({
296
+ state: this.state,
297
+ logger: this.logger,
298
+ runHeartbeatMs: this.runHeartbeatMs,
299
+ runStallTimeoutMs: this.runStallTimeoutMs,
300
+ runControlIntents: this.runControlIntents,
301
+ activeRuns: this.activeRunExecutions,
302
+ debugSwallow: (message, fields) => this.debugSwallow(message, fields)
303
+ });
290
304
  this.runRecoveryIntervalMs = options.runRecoveryIntervalMs ?? resolvePositiveIntegerEnv(this.env.ASSEMBLY_LINE_RUN_RECOVERY_INTERVAL_MS, 60_000);
291
305
  this.maxModelIterations = resolvePositiveIntegerEnv(this.env.ASSEMBLY_LINE_MAX_MODEL_ITERATIONS, DEFAULT_MAX_MODEL_ITERATIONS);
292
306
  this.outputValidationMaxRetries = resolveNonNegativeIntegerEnv(this.env.ASSEMBLY_LINE_OUTPUT_VALIDATION_MAX_RETRIES, DEFAULT_OUTPUT_VALIDATION_MAX_RETRIES);
@@ -296,7 +310,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
296
310
  });
297
311
  this.conversationTurnDispatcher = new ConversationTurnDispatcher({
298
312
  state: this.state, logger: this.logger,
299
- agentScope: this.durableAgentScope(), maxRunDurationMs: this.maxRunDurationMs,
313
+ agentScope: this.durableAgentScope(),
300
314
  now: () => this.now(), agentEnabled: () => this.agentEnabled(),
301
315
  admitRunOrReject: () => this.admitRunOrReject(),
302
316
  runTurn: (turn, admission, onRunCreated) => this.run({
@@ -309,8 +323,12 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
309
323
  this.sourceLoader = new AgentSourceModuleLoader({
310
324
  manifest: this.manifest,
311
325
  sourceBundle: this.sourceBundle,
312
- ...(options.artifactRoot ? { cacheRoot: join(resolve(options.artifactRoot), ARTIFACT_DIR_NAME, "module-cache") } : {})
326
+ ...(options.artifactRoot ? {
327
+ cacheRoot: join(resolve(options.artifactRoot), ARTIFACT_DIR_NAME, "module-cache"),
328
+ packageRoot: resolve(options.artifactRoot)
329
+ } : {})
313
330
  });
331
+ this.sandboxAuthoredToolExecutor = new SandboxAuthoredToolExecutor(this.sourceLoader);
314
332
  this.skillBundleIndex = createSkillBundleIndex(this.manifest);
315
333
  this.skillResourceReader = createSkillResourceReader({
316
334
  manifest: this.manifest,
@@ -318,6 +336,16 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
318
336
  manifestRoot: this.manifest.root,
319
337
  sourceBundle: this.sourceBundle
320
338
  });
339
+ this.backgroundSubagents = new BackgroundSubagentCoordinator({
340
+ state: this.state,
341
+ logger: this.logger,
342
+ withRunAdmission: (work) => this.withRunAdmission(work),
343
+ execute: (childRunId) => executeSubagentRunImpl(this.subagentExecutionHost(), childRunId),
344
+ finalize: (timeline) => finalizeSubagentHandoffImpl(this.subagentExecutionHost(), timeline),
345
+ replay: (runId) => this.replay(runId),
346
+ cancel: (runId) => this.cancelRun(runId),
347
+ enqueueConversationTurn: (input) => this.conversationTurnDispatcher.enqueue(input)
348
+ });
321
349
  }
322
350
  boot() {
323
351
  if (this.manifest.schemaVersion !== ASSEMBLY_LINE_MANIFEST_SCHEMA_VERSION) {
@@ -374,6 +402,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
374
402
  async createCheckpoint(input) {
375
403
  const storedData = await this.checkpointDataForStorage(input.runId, input.name, input.data);
376
404
  const checkpoint = await this.state.createCheckpoint({ ...input, data: storedData });
405
+ await this.runProgress.renew(input.runId);
377
406
  if (COMPACTABLE_ACTIVE_CHECKPOINT_NAMES.includes(input.name)) {
378
407
  await this.compactCheckpoints({
379
408
  runId: input.runId,
@@ -477,53 +506,6 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
477
506
  startBackgroundReviewWorker(options = {}) {
478
507
  return this.runtimeLearning.startBackgroundReviewWorker(options);
479
508
  }
480
- async createDynamicSchedule(input) {
481
- if (!this.schedulesConfig.dynamic) {
482
- throw new Error("Dynamic automations are disabled (dynamicAutomations.dynamic is false).");
483
- }
484
- const trigger = input.trigger ? this.normalizeScheduleTriggerDefinition(input.trigger) : undefined;
485
- const prompt = stringValue(input.prompt) || stringValue(input.message) || (trigger ? `Run scheduled trigger ${trigger.handler}.` : "");
486
- if (!prompt)
487
- throw new Error("Dynamic schedules require prompt or message.");
488
- const createInput = {
489
- ...input,
490
- prompt
491
- };
492
- if (input.message)
493
- createInput.message = input.message;
494
- if (trigger)
495
- createInput.trigger = trigger;
496
- return this.scheduleStore.create(createInput);
497
- }
498
- async createDynamicAutomation(input) {
499
- return this.createDynamicSchedule(input);
500
- }
501
- async listDynamicSchedules(scope) {
502
- return this.scheduleStore.list(scope);
503
- }
504
- async listDynamicAutomations(scope) {
505
- return this.listDynamicSchedules(scope);
506
- }
507
- async updateDynamicSchedule(scope, id, patch) {
508
- if (!this.schedulesConfig.dynamic) {
509
- throw new Error("Dynamic automations are disabled (dynamicAutomations.dynamic is false).");
510
- }
511
- const normalized = { ...patch };
512
- if (Object.prototype.hasOwnProperty.call(patch, "trigger")) {
513
- const rawTrigger = patch.trigger;
514
- normalized.trigger = rawTrigger === null ? null : this.normalizeScheduleTriggerDefinition(rawTrigger);
515
- }
516
- return this.scheduleStore.update(scope, id, normalized);
517
- }
518
- async updateDynamicAutomation(scope, id, patch) {
519
- return this.updateDynamicSchedule(scope, id, patch);
520
- }
521
- async deleteDynamicSchedule(scope, id) {
522
- return this.scheduleStore.delete(scope, id);
523
- }
524
- async deleteDynamicAutomation(scope, id) {
525
- return this.deleteDynamicSchedule(scope, id);
526
- }
527
509
  /** Persist a runtime-provided connection definition (gated). Credentials route to the grant store. */
528
510
  async saveConnectionDefinition(input) {
529
511
  if (!this.connectionsConfig.dynamic) {
@@ -624,6 +606,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
624
606
  async acquireSandboxForRun(run) {
625
607
  return acquireSandboxSessionForRun({
626
608
  manifest: this.manifest,
609
+ env: this.env,
627
610
  state: this.state,
628
611
  sandbox: this.sandbox,
629
612
  sessionKey: (candidate) => this.sandboxSessionKey(candidate),
@@ -796,6 +779,17 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
796
779
  this.logger.warn("onRunCreated hook failed", { runId: run.id, error: error instanceof Error ? error.message : String(error) });
797
780
  }
798
781
  await this.state.appendEvent(run.id, "run.accepted", { agentRevision: this.manifest.agentRevision });
782
+ try {
783
+ await acceptBackgroundSubagentHandoff(this.state, run);
784
+ }
785
+ catch (error) {
786
+ const message = error instanceof Error ? error.message : String(error);
787
+ run = await failRunImpl({ state: this.state }, run.id, {
788
+ reason: "subagent.handoff_failed",
789
+ error: message
790
+ });
791
+ return this.result(run, `Artifact handoff failed: ${message}`, false, false, false);
792
+ }
799
793
  if (options.replay)
800
794
  await recordRunReplayStarted(this.state, run.id, options.replay);
801
795
  if (this.usesRevisionScopedDurableState() && (this.skillsConfig.enabled || this.connectionsConfig.dynamic)) {
@@ -916,8 +910,20 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
916
910
  const channelContext = mergeJsonObjects(media.channelContext, augmentation?.channelContext);
917
911
  if (channelContext)
918
912
  contextInput.channelContext = channelContext;
919
- if (hydratedOptions.promptContext)
920
- contextInput.promptContext = hydratedOptions.promptContext;
913
+ const activeWork = await this.backgroundSubagents.listForRoot(run);
914
+ if (hydratedOptions.promptContext || activeWork.length > 0) {
915
+ contextInput.promptContext = {
916
+ ...(hydratedOptions.promptContext ?? {}),
917
+ ...(activeWork.length > 0
918
+ ? {
919
+ activeWork: {
920
+ items: activeWork,
921
+ guidance: "These background tasks are still active. You may answer new messages while they run. Do not claim they are complete. Use manage_work to inspect or cancel them."
922
+ }
923
+ }
924
+ : {})
925
+ };
926
+ }
921
927
  if (hydratedOptions.target)
922
928
  contextInput.target = hydratedOptions.target;
923
929
  let bundle = options.contextSnapshot ? structuredClone(options.contextSnapshot) : await this.buildContextBundle(contextInput);
@@ -965,6 +971,13 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
965
971
  const input = hydratedOptions.input ?? inferToolInput(tool, hydratedOptions.message);
966
972
  const outcome = await this.executeTool(run, tool, input, sandboxHandle, hydratedOptions.approve ?? false);
967
973
  run = outcome.run;
974
+ const stalled = await this.runProgress.failIfStalled(run);
975
+ if (stalled) {
976
+ run = stalled;
977
+ await stopChannelLifecycle();
978
+ await sandboxHandle.dispose();
979
+ return this.result(run, "Run stalled without durable progress.", false, false, false);
980
+ }
968
981
  if (outcome.waitingForApproval || outcome.waitingForInput || outcome.waitingForConnection) {
969
982
  await stopChannelLifecycle();
970
983
  await this.emitSpan("ai.assembly-line.turn", spanStartedAt, this.runSpanAttributes(run, {
@@ -1063,24 +1076,9 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
1063
1076
  async settleCompletionBoundaryControl(run) {
1064
1077
  return settleCompletionBoundaryControlImpl({ state: this.state, runControlIntents: this.runControlIntents }, run);
1065
1078
  }
1066
- /** Bump `updatedAt` while a run executes; enforces the wall-clock deadline (run-heartbeat.ts). */
1079
+ /** Bump `updatedAt` while a run executes and supervise its progress lease. */
1067
1080
  startRunHeartbeat(runId) {
1068
- return trackActiveRunHeartbeat(this.activeRunExecutions, runId, startRunHeartbeatImpl({
1069
- state: this.state,
1070
- logger: this.logger,
1071
- runHeartbeatMs: this.runHeartbeatMs,
1072
- maxRunDurationMs: this.maxRunDurationMs,
1073
- runControlIntents: this.runControlIntents,
1074
- runDeadlines: this.runDeadlines,
1075
- abortRunControllers: (id) => {
1076
- for (const controller of this.runAbortControllers.get(id) ?? [])
1077
- controller.abort();
1078
- },
1079
- debugSwallow: (message, fields) => this.debugSwallow(message, fields)
1080
- }, runId));
1081
- }
1082
- registerRunAbort(runId, controller) {
1083
- return registerRunAbortController(this.runAbortControllers, this.runDeadlines, runId, controller, this.runControlIntents);
1081
+ return this.runProgress.start(runId);
1084
1082
  }
1085
1083
  conversationContextHost() {
1086
1084
  const runtime = this;
@@ -1136,10 +1134,10 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
1136
1134
  maxModelIterations: this.maxModelIterations,
1137
1135
  outputValidationMaxRetries: this.outputValidationMaxRetries,
1138
1136
  now: () => this.now(),
1139
- shouldStopRun: (runId) => this.runControlIntents.has(runId) || this.runDeadlines.has(runId),
1140
- runDeadlineExceeded: (runId) => this.runDeadlines.has(runId),
1141
- registerRunAbort: (runId, controller) => this.registerRunAbort(runId, controller),
1142
- maxRunDurationMs: this.maxRunDurationMs,
1137
+ shouldStopRun: (runId) => this.runProgress.shouldStop(runId),
1138
+ runStalled: (runId) => this.runProgress.isStalled(runId),
1139
+ registerRunAbort: (runId, controller) => this.runProgress.registerAbort(runId, controller),
1140
+ runStallTimeoutMs: this.runStallTimeoutMs,
1143
1141
  runEventBus: this.runEventBus,
1144
1142
  connectionAuthorizationSessionStore: this.connectionAuthorizationSessionStore,
1145
1143
  get defaultAgentHarness() {
@@ -1155,7 +1153,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
1155
1153
  createConnectionRegistryForRun: (run, fallbackChannel, sandboxHandle, selectedConnections) => this.createConnectionRegistryForRun(run, fallbackChannel, sandboxHandle, selectedConnections),
1156
1154
  missingRequiredConnections: (selected) => this.missingRequiredConnections(selected),
1157
1155
  visibleToolSet: (defaultToolNames, activeSkills) => this.visibleToolSet(defaultToolNames, activeSkills),
1158
- modelTools: (run, activeToolNames, connectionRegistry, discoveredConnectionTools, options) => this.modelTools(run, activeToolNames, connectionRegistry, discoveredConnectionTools, options),
1156
+ modelTools: (run, activeToolNames, sandboxHandle, connectionRegistry, discoveredConnectionTools, options) => this.modelTools(run, activeToolNames, sandboxHandle, connectionRegistry, discoveredConnectionTools, options),
1159
1157
  harnessExecuteTool: (call, state) => this.harnessExecuteTool(call, state),
1160
1158
  createCheckpoint: (input) => this.createCheckpoint(input),
1161
1159
  hydrateCheckpointData: (data) => this.hydrateCheckpointData(data),
@@ -1411,7 +1409,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
1411
1409
  state: this.state,
1412
1410
  boot: () => this.boot(),
1413
1411
  durableAgentScope: () => this.durableAgentScope(),
1414
- cacheRunControl: (runId, intent) => cacheRunControlSignal(this.runControlIntents, this.activeRunExecutions, this.runAbortControllers, runId, intent)
1412
+ cacheRunControl: (runId, intent) => this.runProgress.cacheControl(runId, intent)
1415
1413
  };
1416
1414
  }
1417
1415
  async resumeHarnessLoop(run, harness, restored, resume) {
@@ -1420,6 +1418,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
1420
1418
  subagentExecutionHost() {
1421
1419
  return {
1422
1420
  state: this.state,
1421
+ blob: this.blob,
1423
1422
  manifest: this.manifest,
1424
1423
  sourceLoader: this.sourceLoader,
1425
1424
  resolveAgentHarness: (modelSpec) => this.resolveAgentHarness(modelSpec),
@@ -1440,6 +1439,32 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
1440
1439
  async runSubagent(parentRunId, subagentName, task) {
1441
1440
  return runSubagentImpl(this.subagentExecutionHost(), parentRunId, subagentName, task);
1442
1441
  }
1442
+ async resumeSubagent(parentRunId, childRunId, subagentName, message) {
1443
+ return resumeSubagentImpl(this.subagentExecutionHost(), parentRunId, childRunId, subagentName, message);
1444
+ }
1445
+ async queueSubagent(parentRunId, subagentName, task) {
1446
+ const child = await createSubagentRunImpl(this.subagentExecutionHost(), parentRunId, subagentName, task, { background: true });
1447
+ this.backgroundSubagents.requestDrain();
1448
+ return child;
1449
+ }
1450
+ async listBackgroundWork(rootRunId, includeTerminal = false) {
1451
+ const root = await this.state.getRun(rootRunId);
1452
+ if (!root)
1453
+ throw new Error(`Run not found: ${rootRunId}`);
1454
+ return this.backgroundSubagents.listForRoot(root, includeTerminal);
1455
+ }
1456
+ async getBackgroundWork(rootRunId, childRunId) {
1457
+ const root = await this.state.getRun(rootRunId);
1458
+ if (!root)
1459
+ throw new Error(`Run not found: ${rootRunId}`);
1460
+ return this.backgroundSubagents.getForRoot(root, childRunId);
1461
+ }
1462
+ async cancelBackgroundWork(rootRunId, childRunId) {
1463
+ const root = await this.state.getRun(rootRunId);
1464
+ if (!root)
1465
+ throw new Error(`Run not found: ${rootRunId}`);
1466
+ return this.backgroundSubagents.cancelForRoot(root, childRunId);
1467
+ }
1443
1468
  async readSubagent(childRunId, cursor) {
1444
1469
  return readSubagentImpl(this.subagentExecutionHost(), childRunId, cursor);
1445
1470
  }
@@ -1580,7 +1605,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
1580
1605
  async resumeRunFromContinuation(run, context) {
1581
1606
  return resumeRunFromContinuationImpl(this.replayResumeHost(), run, context);
1582
1607
  }
1583
- /** Start delivery, sandbox-sync, conversation-turn, background-review, and orphan-recovery workers. */
1608
+ /** Start delivery, sandbox-sync, conversation-turn, subagent, background-review, and orphan-recovery workers. */
1584
1609
  startBackgroundWorkers(options = {}) {
1585
1610
  return startBackgroundWorkersImpl({
1586
1611
  env: this.env,
@@ -1589,6 +1614,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
1589
1614
  startDeliveryWorker: (workerOptions) => this.startDeliveryWorker(workerOptions),
1590
1615
  startSandboxSyncWorker: (workerOptions) => this.startSandboxSyncWorker(workerOptions),
1591
1616
  startConversationTurnWorker: (workerOptions) => this.conversationTurnDispatcher.startWorker(workerOptions?.intervalMs),
1617
+ startBackgroundSubagentWorker: (workerOptions) => this.backgroundSubagents.startWorker(workerOptions?.intervalMs),
1592
1618
  startBackgroundReviewWorker: (workerOptions) => this.startBackgroundReviewWorker(workerOptions),
1593
1619
  startConnectionEventWorker: (workerOptions) => this.startConnectionEventWorker(workerOptions),
1594
1620
  recoverIncompleteRuns: (recoveryOptions) => this.recoverIncompleteRuns(recoveryOptions),
@@ -1725,8 +1751,8 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
1725
1751
  async instructionsForRunTarget(run, target, baseInstructions) {
1726
1752
  return instructionsForRunTargetImpl({ appendEvent: (runId, type, data) => this.state.appendEvent(runId, type, data), skillLoadDetails: (skillName) => this.skillLoadDetails(run, skillName) }, run, target, baseInstructions);
1727
1753
  }
1728
- async modelTools(run, activeToolNames, connectionRegistry, discoveredConnectionTools = new Map(), options) {
1729
- return modelToolsImpl(this.toolExecutionHost(), run, activeToolNames, connectionRegistry, discoveredConnectionTools, options);
1754
+ async modelTools(run, activeToolNames, sandboxHandle, connectionRegistry, discoveredConnectionTools = new Map(), options) {
1755
+ return modelToolsImpl(this.toolExecutionHost(), run, activeToolNames, sandboxHandle, connectionRegistry, discoveredConnectionTools, options);
1730
1756
  }
1731
1757
  async harnessExecuteTool(call, state) {
1732
1758
  return harnessExecuteToolImpl(this.toolExecutionHost(), call, state);
@@ -1863,6 +1889,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
1863
1889
  connectionAuthorizationSessionStore: this.connectionAuthorizationSessionStore,
1864
1890
  connectionCallbackBaseUrl: this.connectionCallbackBaseUrl,
1865
1891
  toolOutputMaxChars: this.toolOutputMaxChars,
1892
+ authoredToolExecution: this.authoredToolExecution,
1866
1893
  toolTimeoutMs: this.toolTimeoutMs,
1867
1894
  sandboxSyncMaxAttempts: this.sandboxSyncMaxAttempts,
1868
1895
  skillsConfigForRun: (run) => this.skillsConfigForRun(run),
@@ -1870,6 +1897,9 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
1870
1897
  connectionsConfig: this.connectionsConfig,
1871
1898
  surfaceForRun: (run) => surfaceForRun(this.manifest, run),
1872
1899
  agentStateForRun: (runId) => this.agentStateForRun(runId),
1900
+ reportRunProgress: async (runId, data = {}) => {
1901
+ await this.state.appendEvent(runId, "run.progress_reported", data);
1902
+ },
1873
1903
  ensureSkillsSeeded: (run) => this.ensureSkillsSeeded(surfaceForRun(this.manifest, run).path),
1874
1904
  skillScopeForRun: (run) => this.skillScopeForRun(run),
1875
1905
  scheduleScopeForRun: (run) => this.scheduleScopeForRun(run),
@@ -1878,7 +1908,15 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
1878
1908
  mergedConnections: () => this.mergedConnections(),
1879
1909
  loadConnectionDefinition: (connection) => this.loadConnectionDefinition(connection),
1880
1910
  loadTool: (tool, run) => this.loadTool(tool, run),
1911
+ shouldSandboxAuthoredTool: (tool, run) => this.shouldSandboxAuthoredTool(tool, run),
1912
+ describeSandboxedTool: (tool, sandboxHandle) => this.sandboxAuthoredToolExecutor.describe(tool, sandboxHandle),
1913
+ executeSandboxedTool: (tool, input, context, sandboxHandle, signal) => this.sandboxAuthoredToolExecutor.execute(tool, input, context, sandboxHandle, signal),
1881
1914
  runSubagent: (parentRunId, subagentName, task) => this.runSubagent(parentRunId, subagentName, task),
1915
+ queueSubagent: (parentRunId, subagentName, task) => this.queueSubagent(parentRunId, subagentName, task),
1916
+ resumeSubagent: (parentRunId, childRunId, subagentName, message) => this.resumeSubagent(parentRunId, childRunId, subagentName, message),
1917
+ listBackgroundWork: (rootRunId, includeTerminal) => this.listBackgroundWork(rootRunId, includeTerminal),
1918
+ getBackgroundWork: (rootRunId, childRunId) => this.getBackgroundWork(rootRunId, childRunId),
1919
+ cancelBackgroundWork: (rootRunId, childRunId) => this.cancelBackgroundWork(rootRunId, childRunId),
1882
1920
  projectSkillIntoSandbox: (run, sandbox, skillName) => this.projectSkillIntoSandbox(run, sandbox, skillName),
1883
1921
  hydrateLogicalPathForTool: (run, sandbox, path, options) => this.hydrateLogicalPathForTool(run, sandbox, path, options),
1884
1922
  recordSandboxTombstone: (run, sandbox, path) => this.recordSandboxTombstone(run, sandbox, path),
@@ -1908,10 +1946,24 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
1908
1946
  return selectToolImpl(this.toolExecutionHost(), options);
1909
1947
  }
1910
1948
  async executeTool(run, tool, input, sandboxHandle, approved, idempotencyKey) {
1911
- return executeToolImpl(this.toolExecutionHost(), run, tool, input, sandboxHandle, approved, idempotencyKey);
1949
+ const abortController = new AbortController();
1950
+ const unregisterAbort = this.runProgress.registerAbort(run.id, abortController);
1951
+ try {
1952
+ return await executeToolImpl(this.toolExecutionHost(), run, tool, input, sandboxHandle, approved, idempotencyKey, abortController.signal);
1953
+ }
1954
+ finally {
1955
+ unregisterAbort();
1956
+ }
1912
1957
  }
1913
1958
  async executeToolWithRecord(run, tool, toolCall, input, sandboxHandle, approvedToolCall = false) {
1914
- return executeToolWithRecordImpl(this.toolExecutionHost(), run, tool, toolCall, input, sandboxHandle, approvedToolCall);
1959
+ const abortController = new AbortController();
1960
+ const unregisterAbort = this.runProgress.registerAbort(run.id, abortController);
1961
+ try {
1962
+ return await executeToolWithRecordImpl(this.toolExecutionHost(), run, tool, toolCall, input, sandboxHandle, approvedToolCall, abortController.signal);
1963
+ }
1964
+ finally {
1965
+ unregisterAbort();
1966
+ }
1915
1967
  }
1916
1968
  async durableStep(runId, key, fn, options) {
1917
1969
  return durableStepImpl(this.toolExecutionHost(), runId, key, fn, options);
@@ -1980,94 +2032,38 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
1980
2032
  removeTerminalAgentHookState(runId, event, this.eventHandlers, this.agentHookControllers, this.agentStateHandles);
1981
2033
  }
1982
2034
  async handleRuntimeEvent(runId, event) {
2035
+ if (eventRenewsRunProgress(event.type))
2036
+ await this.runProgress.renew(runId);
1983
2037
  await this.dispatchHookEvent(runId, event);
1984
2038
  await this.runtimeLearning.handleRuntimeEvent(runId, event.type);
1985
2039
  }
1986
2040
  async createAgentHookController(run, options, channel, conversationId, attachments) {
1987
- const disabledTools = this.disabledToolsForRun(run);
1988
- const surface = rootAgentSurface(this.manifest);
1989
- const liveSkills = (await this.listSkills(surface.path)).map((skill) => skill.name).sort();
1990
- const baseCatalog = hookCapabilityCatalog(this.manifest, surface);
1991
- const created = await createRuntimeAgentHookController({
1992
- manifest: this.manifest,
1993
- state: this.state,
1994
- blob: this.blob,
1995
- sourceLoader: this.sourceLoader,
1996
- eventHandlers: this.eventHandlers,
1997
- logger: this.logger,
1998
- agentScope: this.durableAgentScope(),
1999
- conversationId,
2000
- run: immutableAgentRunContext({
2001
- id: run.id,
2002
- message: options.message,
2003
- channel,
2004
- conversationId,
2005
- ...(typeof run.input.userId === "string" ? { userId: run.input.userId } : {}),
2006
- ...(principalFromRun(run) ? { principal: principalFromRun(run) } : {}),
2007
- ...(initiatorFromRun(run) ? { initiator: initiatorFromRun(run) } : {}),
2008
- audience: audienceFromRun(run),
2009
- ...((options.metadata ?? options.turn?.metadata) ? {
2010
- metadata: (options.metadata ?? options.turn?.metadata)
2011
- } : {}),
2012
- attachments
2013
- }),
2014
- surface,
2015
- catalog: { ...baseCatalog, skills: new Set(liveSkills) },
2016
- defaultSkills: liveSkills,
2017
- disabledTools,
2018
- createCheckpoint: (input) => this.createCheckpoint(input),
2019
- listCheckpoints: (runId) => this.listHydratedCheckpoints(runId)
2020
- });
2021
- this.agentStateHandles.set(run.id, created.agentState);
2022
- this.agentHookControllers.set(run.id, created.controller);
2023
- return created.controller;
2041
+ const created = await createMainAgentHookControllerImpl(this.agentHookControllerFactoryHost(), run, options, channel, conversationId, attachments);
2042
+ return this.rememberAgentHookController(run.id, created);
2024
2043
  }
2025
2044
  async createSubagentHookController(run, subagent, message, conversationId) {
2026
- const surface = subagentSurface(subagent);
2027
- const liveSkills = (await this.listSkills(surface.path)).map((skill) => skill.name).sort();
2028
- const baseCatalog = hookCapabilityCatalog(this.manifest, surface);
2029
- const created = await createRuntimeAgentHookController({
2045
+ const created = await createSubagentHookControllerImpl(this.agentHookControllerFactoryHost(), run, subagent, message, conversationId);
2046
+ return this.rememberAgentHookController(run.id, created);
2047
+ }
2048
+ agentHookControllerFactoryHost() {
2049
+ return {
2030
2050
  manifest: this.manifest,
2031
2051
  state: this.state,
2032
2052
  blob: this.blob,
2033
2053
  sourceLoader: this.sourceLoader,
2034
2054
  eventHandlers: this.eventHandlers,
2035
2055
  logger: this.logger,
2036
- agentScope: `${this.durableAgentScope()}:subagent:${subagent.path}`,
2037
- conversationId,
2038
- agentSource: subagent.agentSource,
2039
- surface,
2040
- catalog: {
2041
- ...baseCatalog,
2042
- skills: new Set(liveSkills),
2043
- models: new Set(subagent.possibleModels),
2044
- connections: new Set(subagent.connections),
2045
- ...(subagent.maxReasoning !== undefined ? { maxReasoning: subagent.maxReasoning } : {})
2046
- },
2047
- defaultSkills: liveSkills,
2048
- run: immutableAgentRunContext({
2049
- id: run.id,
2050
- message,
2051
- channel: "subagent",
2052
- conversationId,
2053
- ...(typeof run.input.userId === "string" ? { userId: run.input.userId } : {}),
2054
- ...(principalFromRun(run) ? { principal: principalFromRun(run) } : {}),
2055
- ...(initiatorFromRun(run) ? { initiator: initiatorFromRun(run) } : {}),
2056
- audience: audienceFromRun(run),
2057
- ...(isJsonObject(run.input.metadata) ? { metadata: run.input.metadata } : {}),
2058
- attachments: []
2059
- }),
2060
- disabledTools: this.disabledToolsForRun(run),
2056
+ durableAgentScope: () => this.durableAgentScope(),
2057
+ listSkillNames: async (surfacePath) => (await this.listSkills(surfacePath)).map((skill) => skill.name).sort(),
2058
+ disabledToolsForRun: () => new Set(Object.entries(this.coreToolPolicy).filter(([, mode]) => mode === "disabled").map(([name]) => name)),
2061
2059
  createCheckpoint: (input) => this.createCheckpoint(input),
2062
2060
  listCheckpoints: (runId) => this.listHydratedCheckpoints(runId)
2063
- });
2064
- this.agentStateHandles.set(run.id, created.agentState);
2065
- this.agentHookControllers.set(run.id, created.controller);
2066
- return created.controller;
2061
+ };
2067
2062
  }
2068
- disabledToolsForRun(run) {
2069
- const disabledTools = new Set(Object.entries(this.coreToolPolicy).filter(([, mode]) => mode === "disabled").map(([name]) => name));
2070
- return disabledTools;
2063
+ rememberAgentHookController(runId, created) {
2064
+ this.agentStateHandles.set(runId, created.agentState);
2065
+ this.agentHookControllers.set(runId, created.controller);
2066
+ return created.controller;
2071
2067
  }
2072
2068
  agentStateForRun(runId) {
2073
2069
  const handle = this.agentStateHandles.get(runId);
@@ -2103,6 +2099,13 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
2103
2099
  const module = await this.sourceLoader.load(tool.source);
2104
2100
  return module.default;
2105
2101
  }
2102
+ shouldSandboxAuthoredTool(tool, run) {
2103
+ if (tool.source.path.startsWith("__builtin__"))
2104
+ return false;
2105
+ if (this.toolStubs[tool.name] || evalRunOptionsForRun(run)?.toolStubs?.[tool.name])
2106
+ return false;
2107
+ return this.authoredToolExecution === "sandbox" || tool.execution === "sandbox";
2108
+ }
2106
2109
  async result(run, response, waitingForApproval, waitingForInput, waitingForConnection) {
2107
2110
  return buildRunAgentResult(this.state, run, response, waitingForApproval, waitingForInput, waitingForConnection);
2108
2111
  }