@assemblyline-agents/runtime 3.0.0 → 3.2.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.
- package/dist/agent-hook-controller-factory.d.ts +28 -0
- package/dist/agent-hook-controller-factory.d.ts.map +1 -0
- package/dist/agent-hook-controller-factory.js +83 -0
- package/dist/agent-hook-controller-factory.js.map +1 -0
- package/dist/background-subagents.d.ts +43 -0
- package/dist/background-subagents.d.ts.map +1 -0
- package/dist/background-subagents.js +304 -0
- package/dist/background-subagents.js.map +1 -0
- package/dist/builtin-tool-executors.d.ts +1 -0
- package/dist/builtin-tool-executors.d.ts.map +1 -1
- package/dist/builtin-tool-executors.js +38 -30
- package/dist/builtin-tool-executors.js.map +1 -1
- package/dist/builtin-tools.d.ts.map +1 -1
- package/dist/builtin-tools.js +5 -4
- package/dist/builtin-tools.js.map +1 -1
- package/dist/capability-catalog.d.ts +8 -5
- package/dist/capability-catalog.d.ts.map +1 -1
- package/dist/capability-catalog.js +28 -1
- package/dist/capability-catalog.js.map +1 -1
- package/dist/conversation-turn-dispatch.d.ts +1 -1
- package/dist/conversation-turn-dispatch.d.ts.map +1 -1
- package/dist/conversation-turn-dispatch.js +25 -1
- package/dist/conversation-turn-dispatch.js.map +1 -1
- package/dist/dynamic-schedule-runtime.d.ts +42 -0
- package/dist/dynamic-schedule-runtime.d.ts.map +1 -0
- package/dist/dynamic-schedule-runtime.js +57 -0
- package/dist/dynamic-schedule-runtime.js.map +1 -0
- package/dist/harness-loop.d.ts +5 -5
- package/dist/harness-loop.d.ts.map +1 -1
- package/dist/harness-loop.js +16 -14
- package/dist/harness-loop.js.map +1 -1
- package/dist/in-memory-conversation-turn-store.d.ts +1 -0
- package/dist/in-memory-conversation-turn-store.d.ts.map +1 -1
- package/dist/in-memory-conversation-turn-store.js +11 -0
- package/dist/in-memory-conversation-turn-store.js.map +1 -1
- package/dist/index.d.ts +18 -40
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +144 -164
- package/dist/index.js.map +1 -1
- package/dist/local-sandbox.d.ts.map +1 -1
- package/dist/local-sandbox.js +2 -1
- package/dist/local-sandbox.js.map +1 -1
- package/dist/public-api.d.ts +2 -2
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js.map +1 -1
- package/dist/replay-resume.d.ts.map +1 -1
- package/dist/replay-resume.js +3 -2
- package/dist/replay-resume.js.map +1 -1
- package/dist/run-heartbeat.d.ts +45 -18
- package/dist/run-heartbeat.d.ts.map +1 -1
- package/dist/run-heartbeat.js +120 -14
- package/dist/run-heartbeat.js.map +1 -1
- package/dist/run-outcome.d.ts +1 -1
- package/dist/run-outcome.d.ts.map +1 -1
- package/dist/run-outcome.js.map +1 -1
- package/dist/run-recovery.d.ts +9 -1
- package/dist/run-recovery.d.ts.map +1 -1
- package/dist/run-recovery.js +26 -1
- package/dist/run-recovery.js.map +1 -1
- package/dist/runtime-types.d.ts +15 -3
- package/dist/runtime-types.d.ts.map +1 -1
- package/dist/sandbox-session-lifecycle.d.ts +1 -0
- package/dist/sandbox-session-lifecycle.d.ts.map +1 -1
- package/dist/sandbox-session-lifecycle.js +48 -16
- package/dist/sandbox-session-lifecycle.js.map +1 -1
- package/dist/scheduled-delivery.d.ts +6 -0
- package/dist/scheduled-delivery.d.ts.map +1 -0
- package/dist/scheduled-delivery.js +117 -0
- package/dist/scheduled-delivery.js.map +1 -0
- package/dist/state-stores.js +1 -1
- package/dist/state-stores.js.map +1 -1
- package/dist/state.d.ts +2 -1
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +1 -0
- package/dist/state.js.map +1 -1
- package/dist/storage.d.ts +1 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +3 -0
- package/dist/storage.js.map +1 -1
- package/dist/subagent-execution.d.ts +8 -1
- package/dist/subagent-execution.d.ts.map +1 -1
- package/dist/subagent-execution.js +132 -6
- package/dist/subagent-execution.js.map +1 -1
- package/dist/subagent-handoff.d.ts +44 -0
- package/dist/subagent-handoff.d.ts.map +1 -0
- package/dist/subagent-handoff.js +271 -0
- package/dist/subagent-handoff.js.map +1 -0
- package/dist/tool-apis.d.ts.map +1 -1
- package/dist/tool-apis.js +7 -6
- package/dist/tool-apis.js.map +1 -1
- package/dist/tool-execution.d.ts +5 -0
- package/dist/tool-execution.d.ts.map +1 -1
- package/dist/tool-execution.js +96 -9
- package/dist/tool-execution.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -10,10 +10,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
12
|
import { AgentEventHandlerRegistry } from "./agent-event-handlers.js";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { createRuntimeAgentHookController, recoverAgentHookController, removeTerminalAgentHookState, resolvedInstructionsForRun as resolvedHookInstructionsForRun } from "./agent-hook-run-lifecycle.js";
|
|
13
|
+
import { createMainAgentHookController as createMainAgentHookControllerImpl, createSubagentHookController as createSubagentHookControllerImpl } from "./agent-hook-controller-factory.js";
|
|
14
|
+
import { durableAgentSurfaceScope, flattenSubagents, surfaceForPath, surfaceForRun } from "./agent-surface.js";
|
|
15
|
+
import { recoverAgentHookController, removeTerminalAgentHookState, resolvedInstructionsForRun as resolvedHookInstructionsForRun } from "./agent-hook-run-lifecycle.js";
|
|
17
16
|
import { compiledChannelProvider, providerIngressSecurityError, providerIngressSecurityWarnings, resolveCoreToolPolicy, trustedAttachmentProviderForTurn } from "./security.js";
|
|
18
17
|
export { constantTimeSecretEqual } from "./security.js";
|
|
19
18
|
export { RUN_STREAM_TERMINAL_EVENTS } from "./run-stream.js";
|
|
@@ -24,7 +23,7 @@ import { resolveBooleanEnv, resolveNonNegativeIntegerEnv, resolvePositiveInteger
|
|
|
24
23
|
import { humanInputModeForChannel, withHumanInputMode } from "./human-input-routing.js";
|
|
25
24
|
import { RunEventBus, withRunEventPublishing } from "./run-stream.js";
|
|
26
25
|
import { failRun as failRunImpl, handleRunExecutionError, logTerminalRunEvent, settleCompletionBoundaryControlImpl } from "./run-outcome.js";
|
|
27
|
-
import {
|
|
26
|
+
import { eventRenewsRunProgress, RunProgressSupervisor } from "./run-heartbeat.js";
|
|
28
27
|
import { redactTruncateJson } from "./content-capture.js";
|
|
29
28
|
import { isJsonObject, safeJson } from "./json-util.js";
|
|
30
29
|
import { sandboxSessionKeyForRun } from "./sandbox-session-key.js";
|
|
@@ -55,7 +54,8 @@ import { beginChannelTurnImpl, completeRunImpl, latestRunFailureMessageImpl, rec
|
|
|
55
54
|
import { backfillMemoryDocumentsFromFileIndexesImpl, hydrateLogicalPathForToolImpl, listResourcesForRunImpl, memoryScopeForRunImpl, projectLoadedSkillsIntoSandboxImpl, projectResourcesForRunImpl, projectSkillIntoSandboxImpl, readResourceForRunImpl, readSandboxTombstonesWithMissingProjectedFilesImpl, recordSandboxTombstoneImpl, runMemoryEmbeddingBackfillImpl } from "./resource-projection.js";
|
|
56
55
|
import { createSkillBundleIndex, createSkillResourceReader } from "./skill-bundles.js";
|
|
57
56
|
import { createSandboxHandleImpl } from "./sandbox-handle.js";
|
|
58
|
-
import { RuntimeWorkspaceManager
|
|
57
|
+
import { RuntimeWorkspaceManager } from "./workspace-runtime.js";
|
|
58
|
+
import { DynamicScheduleRuntimeMethods } from "./dynamic-schedule-runtime.js";
|
|
59
59
|
import { beginConnectionAuthorizationImpl, createConnectionRegistryForRunImpl, createConnectionRegistryForSessionImpl, createConnectionRegistryImpl, executeConnectionToolWithRecordImpl, skillLoadDetailsImpl } from "./builtin-tool-executors.js";
|
|
60
60
|
import { createMemoryToolApiImpl, createResourceToolApiImpl, durableStepImpl } from "./tool-apis.js";
|
|
61
61
|
import { executeToolImpl, executeToolWithRecordImpl, harnessExecuteToolImpl, modelToolsImpl, selectToolImpl, visibleToolSetImpl, wrapSandboxImpl } from "./tool-execution.js";
|
|
@@ -64,13 +64,15 @@ import { completeConnectionAuthorizationCallbackImpl, replayImpl, resumeApproval
|
|
|
64
64
|
import { recordRunReplayStarted, rerunFromSnapshot } from "./run-replay.js";
|
|
65
65
|
export { RunReplayError } from "./run-replay.js";
|
|
66
66
|
import { buildRunAgentResult } from "./run-result.js";
|
|
67
|
-
import { readSubagentImpl, runSubagentImpl, sendSubagentFollowupImpl } from "./subagent-execution.js";
|
|
67
|
+
import { createSubagentRunImpl, executeSubagentRunImpl, finalizeSubagentHandoffImpl, readSubagentImpl, runSubagentImpl, sendSubagentFollowupImpl } from "./subagent-execution.js";
|
|
68
|
+
import { acceptBackgroundSubagentHandoff } from "./subagent-handoff.js";
|
|
68
69
|
import { createHarnessContextImpl, DEFAULT_MAX_MODEL_ITERATIONS, DEFAULT_OUTPUT_VALIDATION_MAX_RETRIES, executeHarnessTurnImpl, persistHarnessContinuationImpl, resolveAgentHarnessImpl, runHarnessLoopImpl } from "./harness-loop.js";
|
|
69
70
|
import { getAgentControlImpl, requestRunControlImpl, setAgentEnabledImpl, setAgentMaintenanceImpl } from "./operator-controls.js";
|
|
70
71
|
import { acceptChannelTurnImpl, channelAttachmentResolverImpl, dispatchHttpChannelImpl, loadChannelModuleImpl, observeChannelMessageImpl, startChannelAgentTurnImpl, startChannelIngressImpl } from "./channel-ingress.js";
|
|
71
72
|
import { augmentChannelContextImpl, buildContextBundleImpl, prepareConversationImpl, recentHistoryImpl } from "./conversation-context.js";
|
|
72
73
|
import { loadResumableConversationTranscriptImpl } from "./conversation-transcript.js";
|
|
73
74
|
import { ConversationTurnDispatcher } from "./conversation-turn-dispatch.js";
|
|
75
|
+
import { BackgroundSubagentCoordinator } from "./background-subagents.js";
|
|
74
76
|
import { instructionsForRunTargetImpl } from "./target-instructions.js";
|
|
75
77
|
import { emitTelemetrySpanImpl, runSpanAttributesImpl } from "./telemetry.js";
|
|
76
78
|
import { normalizeRuntimeState } from "./state-stores.js";
|
|
@@ -92,8 +94,8 @@ import { syncMemoryFromSandbox, syncSkillsFromSandbox } from "./sandbox-state-sy
|
|
|
92
94
|
import { acquireSandboxForRun as acquireSandboxSessionForRun } from "./sandbox-session-lifecycle.js";
|
|
93
95
|
import { resolveSandboxSnapshotPolicy } from "./sandbox-snapshot-policy.js";
|
|
94
96
|
import { inferToolInput } from "./channel-http-util.js";
|
|
95
|
-
import { connectionPrincipalKeyForGrant, durableAgentScopeForManifest, isInstrumentationDefinition, normalizeCapturePolicy, randomHex,
|
|
96
|
-
export class AssemblyLineRuntime extends
|
|
97
|
+
import { connectionPrincipalKeyForGrant, durableAgentScopeForManifest, isInstrumentationDefinition, normalizeCapturePolicy, randomHex, timestamp, } from "./runtime-util.js";
|
|
98
|
+
export class AssemblyLineRuntime extends DynamicScheduleRuntimeMethods {
|
|
97
99
|
manifest;
|
|
98
100
|
state;
|
|
99
101
|
runEventBus = new RunEventBus();
|
|
@@ -103,6 +105,8 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
103
105
|
blob;
|
|
104
106
|
sandbox;
|
|
105
107
|
scheduler;
|
|
108
|
+
scheduleStore;
|
|
109
|
+
schedulesConfig;
|
|
106
110
|
mediaProcessors;
|
|
107
111
|
deliveryMode;
|
|
108
112
|
toolStubs;
|
|
@@ -130,10 +134,8 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
130
134
|
skillStore;
|
|
131
135
|
learningStore;
|
|
132
136
|
memoryStore;
|
|
133
|
-
scheduleStore;
|
|
134
137
|
connectionDefinitionStore;
|
|
135
138
|
skillsConfig;
|
|
136
|
-
schedulesConfig;
|
|
137
139
|
connectionsConfig;
|
|
138
140
|
runtimeLearning;
|
|
139
141
|
connectionScopeMigrated = false;
|
|
@@ -159,6 +161,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
159
161
|
outputValidationMaxRetries;
|
|
160
162
|
runSemaphore;
|
|
161
163
|
conversationTurnDispatcher;
|
|
164
|
+
backgroundSubagents;
|
|
162
165
|
memoryEmbeddingProvider;
|
|
163
166
|
memoryEmbeddingsEnabled;
|
|
164
167
|
resourceProjectionPolicy;
|
|
@@ -177,10 +180,8 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
177
180
|
runControlIntents = new Map();
|
|
178
181
|
/** Runs currently owned by this process, used to route immediate control signals without leaking orphan ids. */
|
|
179
182
|
activeRunExecutions = new Set();
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
runAbortControllers = new Map();
|
|
183
|
-
maxRunDurationMs;
|
|
183
|
+
runProgress;
|
|
184
|
+
runStallTimeoutMs;
|
|
184
185
|
constructor(options) {
|
|
185
186
|
super();
|
|
186
187
|
this.manifest = options.manifest;
|
|
@@ -286,7 +287,16 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
286
287
|
this.deliveryQueueMaxAttempts = options.deliveryQueueMaxAttempts ?? resolvePositiveIntegerEnv(this.env.ASSEMBLY_LINE_DELIVERY_QUEUE_MAX_ATTEMPTS, 5);
|
|
287
288
|
this.deliveryQueueIntervalMs = options.deliveryQueueIntervalMs ?? resolvePositiveIntegerEnv(this.env.ASSEMBLY_LINE_DELIVERY_QUEUE_INTERVAL_MS, 15_000);
|
|
288
289
|
this.runHeartbeatMs = options.runHeartbeatMs ?? resolvePositiveIntegerEnv(this.env.ASSEMBLY_LINE_RUN_HEARTBEAT_MS, 30_000);
|
|
289
|
-
this.
|
|
290
|
+
this.runStallTimeoutMs = options.runStallTimeoutMs ?? resolveNonNegativeIntegerEnv(this.env.ASSEMBLY_LINE_RUN_STALL_TIMEOUT_MS, 3_600_000);
|
|
291
|
+
this.runProgress = new RunProgressSupervisor({
|
|
292
|
+
state: this.state,
|
|
293
|
+
logger: this.logger,
|
|
294
|
+
runHeartbeatMs: this.runHeartbeatMs,
|
|
295
|
+
runStallTimeoutMs: this.runStallTimeoutMs,
|
|
296
|
+
runControlIntents: this.runControlIntents,
|
|
297
|
+
activeRuns: this.activeRunExecutions,
|
|
298
|
+
debugSwallow: (message, fields) => this.debugSwallow(message, fields)
|
|
299
|
+
});
|
|
290
300
|
this.runRecoveryIntervalMs = options.runRecoveryIntervalMs ?? resolvePositiveIntegerEnv(this.env.ASSEMBLY_LINE_RUN_RECOVERY_INTERVAL_MS, 60_000);
|
|
291
301
|
this.maxModelIterations = resolvePositiveIntegerEnv(this.env.ASSEMBLY_LINE_MAX_MODEL_ITERATIONS, DEFAULT_MAX_MODEL_ITERATIONS);
|
|
292
302
|
this.outputValidationMaxRetries = resolveNonNegativeIntegerEnv(this.env.ASSEMBLY_LINE_OUTPUT_VALIDATION_MAX_RETRIES, DEFAULT_OUTPUT_VALIDATION_MAX_RETRIES);
|
|
@@ -296,7 +306,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
296
306
|
});
|
|
297
307
|
this.conversationTurnDispatcher = new ConversationTurnDispatcher({
|
|
298
308
|
state: this.state, logger: this.logger,
|
|
299
|
-
agentScope: this.durableAgentScope(),
|
|
309
|
+
agentScope: this.durableAgentScope(),
|
|
300
310
|
now: () => this.now(), agentEnabled: () => this.agentEnabled(),
|
|
301
311
|
admitRunOrReject: () => this.admitRunOrReject(),
|
|
302
312
|
runTurn: (turn, admission, onRunCreated) => this.run({
|
|
@@ -318,6 +328,16 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
318
328
|
manifestRoot: this.manifest.root,
|
|
319
329
|
sourceBundle: this.sourceBundle
|
|
320
330
|
});
|
|
331
|
+
this.backgroundSubagents = new BackgroundSubagentCoordinator({
|
|
332
|
+
state: this.state,
|
|
333
|
+
logger: this.logger,
|
|
334
|
+
withRunAdmission: (work) => this.withRunAdmission(work),
|
|
335
|
+
execute: (childRunId) => executeSubagentRunImpl(this.subagentExecutionHost(), childRunId),
|
|
336
|
+
finalize: (timeline) => finalizeSubagentHandoffImpl(this.subagentExecutionHost(), timeline),
|
|
337
|
+
replay: (runId) => this.replay(runId),
|
|
338
|
+
cancel: (runId) => this.cancelRun(runId),
|
|
339
|
+
enqueueConversationTurn: (input) => this.conversationTurnDispatcher.enqueue(input)
|
|
340
|
+
});
|
|
321
341
|
}
|
|
322
342
|
boot() {
|
|
323
343
|
if (this.manifest.schemaVersion !== ASSEMBLY_LINE_MANIFEST_SCHEMA_VERSION) {
|
|
@@ -374,6 +394,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
374
394
|
async createCheckpoint(input) {
|
|
375
395
|
const storedData = await this.checkpointDataForStorage(input.runId, input.name, input.data);
|
|
376
396
|
const checkpoint = await this.state.createCheckpoint({ ...input, data: storedData });
|
|
397
|
+
await this.runProgress.renew(input.runId);
|
|
377
398
|
if (COMPACTABLE_ACTIVE_CHECKPOINT_NAMES.includes(input.name)) {
|
|
378
399
|
await this.compactCheckpoints({
|
|
379
400
|
runId: input.runId,
|
|
@@ -477,53 +498,6 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
477
498
|
startBackgroundReviewWorker(options = {}) {
|
|
478
499
|
return this.runtimeLearning.startBackgroundReviewWorker(options);
|
|
479
500
|
}
|
|
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
501
|
/** Persist a runtime-provided connection definition (gated). Credentials route to the grant store. */
|
|
528
502
|
async saveConnectionDefinition(input) {
|
|
529
503
|
if (!this.connectionsConfig.dynamic) {
|
|
@@ -624,6 +598,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
624
598
|
async acquireSandboxForRun(run) {
|
|
625
599
|
return acquireSandboxSessionForRun({
|
|
626
600
|
manifest: this.manifest,
|
|
601
|
+
env: this.env,
|
|
627
602
|
state: this.state,
|
|
628
603
|
sandbox: this.sandbox,
|
|
629
604
|
sessionKey: (candidate) => this.sandboxSessionKey(candidate),
|
|
@@ -796,6 +771,17 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
796
771
|
this.logger.warn("onRunCreated hook failed", { runId: run.id, error: error instanceof Error ? error.message : String(error) });
|
|
797
772
|
}
|
|
798
773
|
await this.state.appendEvent(run.id, "run.accepted", { agentRevision: this.manifest.agentRevision });
|
|
774
|
+
try {
|
|
775
|
+
await acceptBackgroundSubagentHandoff(this.state, run);
|
|
776
|
+
}
|
|
777
|
+
catch (error) {
|
|
778
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
779
|
+
run = await failRunImpl({ state: this.state }, run.id, {
|
|
780
|
+
reason: "subagent.handoff_failed",
|
|
781
|
+
error: message
|
|
782
|
+
});
|
|
783
|
+
return this.result(run, `Artifact handoff failed: ${message}`, false, false, false);
|
|
784
|
+
}
|
|
799
785
|
if (options.replay)
|
|
800
786
|
await recordRunReplayStarted(this.state, run.id, options.replay);
|
|
801
787
|
if (this.usesRevisionScopedDurableState() && (this.skillsConfig.enabled || this.connectionsConfig.dynamic)) {
|
|
@@ -916,8 +902,20 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
916
902
|
const channelContext = mergeJsonObjects(media.channelContext, augmentation?.channelContext);
|
|
917
903
|
if (channelContext)
|
|
918
904
|
contextInput.channelContext = channelContext;
|
|
919
|
-
|
|
920
|
-
|
|
905
|
+
const activeWork = await this.backgroundSubagents.listForRoot(run);
|
|
906
|
+
if (hydratedOptions.promptContext || activeWork.length > 0) {
|
|
907
|
+
contextInput.promptContext = {
|
|
908
|
+
...(hydratedOptions.promptContext ?? {}),
|
|
909
|
+
...(activeWork.length > 0
|
|
910
|
+
? {
|
|
911
|
+
activeWork: {
|
|
912
|
+
items: activeWork,
|
|
913
|
+
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."
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
: {})
|
|
917
|
+
};
|
|
918
|
+
}
|
|
921
919
|
if (hydratedOptions.target)
|
|
922
920
|
contextInput.target = hydratedOptions.target;
|
|
923
921
|
let bundle = options.contextSnapshot ? structuredClone(options.contextSnapshot) : await this.buildContextBundle(contextInput);
|
|
@@ -965,6 +963,13 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
965
963
|
const input = hydratedOptions.input ?? inferToolInput(tool, hydratedOptions.message);
|
|
966
964
|
const outcome = await this.executeTool(run, tool, input, sandboxHandle, hydratedOptions.approve ?? false);
|
|
967
965
|
run = outcome.run;
|
|
966
|
+
const stalled = await this.runProgress.failIfStalled(run);
|
|
967
|
+
if (stalled) {
|
|
968
|
+
run = stalled;
|
|
969
|
+
await stopChannelLifecycle();
|
|
970
|
+
await sandboxHandle.dispose();
|
|
971
|
+
return this.result(run, "Run stalled without durable progress.", false, false, false);
|
|
972
|
+
}
|
|
968
973
|
if (outcome.waitingForApproval || outcome.waitingForInput || outcome.waitingForConnection) {
|
|
969
974
|
await stopChannelLifecycle();
|
|
970
975
|
await this.emitSpan("ai.assembly-line.turn", spanStartedAt, this.runSpanAttributes(run, {
|
|
@@ -1063,24 +1068,9 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
1063
1068
|
async settleCompletionBoundaryControl(run) {
|
|
1064
1069
|
return settleCompletionBoundaryControlImpl({ state: this.state, runControlIntents: this.runControlIntents }, run);
|
|
1065
1070
|
}
|
|
1066
|
-
/** Bump `updatedAt` while a run executes
|
|
1071
|
+
/** Bump `updatedAt` while a run executes and supervise its progress lease. */
|
|
1067
1072
|
startRunHeartbeat(runId) {
|
|
1068
|
-
return
|
|
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);
|
|
1073
|
+
return this.runProgress.start(runId);
|
|
1084
1074
|
}
|
|
1085
1075
|
conversationContextHost() {
|
|
1086
1076
|
const runtime = this;
|
|
@@ -1136,10 +1126,10 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
1136
1126
|
maxModelIterations: this.maxModelIterations,
|
|
1137
1127
|
outputValidationMaxRetries: this.outputValidationMaxRetries,
|
|
1138
1128
|
now: () => this.now(),
|
|
1139
|
-
shouldStopRun: (runId) => this.
|
|
1140
|
-
|
|
1141
|
-
registerRunAbort: (runId, controller) => this.
|
|
1142
|
-
|
|
1129
|
+
shouldStopRun: (runId) => this.runProgress.shouldStop(runId),
|
|
1130
|
+
runStalled: (runId) => this.runProgress.isStalled(runId),
|
|
1131
|
+
registerRunAbort: (runId, controller) => this.runProgress.registerAbort(runId, controller),
|
|
1132
|
+
runStallTimeoutMs: this.runStallTimeoutMs,
|
|
1143
1133
|
runEventBus: this.runEventBus,
|
|
1144
1134
|
connectionAuthorizationSessionStore: this.connectionAuthorizationSessionStore,
|
|
1145
1135
|
get defaultAgentHarness() {
|
|
@@ -1411,7 +1401,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
1411
1401
|
state: this.state,
|
|
1412
1402
|
boot: () => this.boot(),
|
|
1413
1403
|
durableAgentScope: () => this.durableAgentScope(),
|
|
1414
|
-
cacheRunControl: (runId, intent) =>
|
|
1404
|
+
cacheRunControl: (runId, intent) => this.runProgress.cacheControl(runId, intent)
|
|
1415
1405
|
};
|
|
1416
1406
|
}
|
|
1417
1407
|
async resumeHarnessLoop(run, harness, restored, resume) {
|
|
@@ -1420,6 +1410,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
1420
1410
|
subagentExecutionHost() {
|
|
1421
1411
|
return {
|
|
1422
1412
|
state: this.state,
|
|
1413
|
+
blob: this.blob,
|
|
1423
1414
|
manifest: this.manifest,
|
|
1424
1415
|
sourceLoader: this.sourceLoader,
|
|
1425
1416
|
resolveAgentHarness: (modelSpec) => this.resolveAgentHarness(modelSpec),
|
|
@@ -1440,6 +1431,29 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
1440
1431
|
async runSubagent(parentRunId, subagentName, task) {
|
|
1441
1432
|
return runSubagentImpl(this.subagentExecutionHost(), parentRunId, subagentName, task);
|
|
1442
1433
|
}
|
|
1434
|
+
async queueSubagent(parentRunId, subagentName, task) {
|
|
1435
|
+
const child = await createSubagentRunImpl(this.subagentExecutionHost(), parentRunId, subagentName, task, { background: true });
|
|
1436
|
+
this.backgroundSubagents.requestDrain();
|
|
1437
|
+
return child;
|
|
1438
|
+
}
|
|
1439
|
+
async listBackgroundWork(rootRunId, includeTerminal = false) {
|
|
1440
|
+
const root = await this.state.getRun(rootRunId);
|
|
1441
|
+
if (!root)
|
|
1442
|
+
throw new Error(`Run not found: ${rootRunId}`);
|
|
1443
|
+
return this.backgroundSubagents.listForRoot(root, includeTerminal);
|
|
1444
|
+
}
|
|
1445
|
+
async getBackgroundWork(rootRunId, childRunId) {
|
|
1446
|
+
const root = await this.state.getRun(rootRunId);
|
|
1447
|
+
if (!root)
|
|
1448
|
+
throw new Error(`Run not found: ${rootRunId}`);
|
|
1449
|
+
return this.backgroundSubagents.getForRoot(root, childRunId);
|
|
1450
|
+
}
|
|
1451
|
+
async cancelBackgroundWork(rootRunId, childRunId) {
|
|
1452
|
+
const root = await this.state.getRun(rootRunId);
|
|
1453
|
+
if (!root)
|
|
1454
|
+
throw new Error(`Run not found: ${rootRunId}`);
|
|
1455
|
+
return this.backgroundSubagents.cancelForRoot(root, childRunId);
|
|
1456
|
+
}
|
|
1443
1457
|
async readSubagent(childRunId, cursor) {
|
|
1444
1458
|
return readSubagentImpl(this.subagentExecutionHost(), childRunId, cursor);
|
|
1445
1459
|
}
|
|
@@ -1580,7 +1594,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
1580
1594
|
async resumeRunFromContinuation(run, context) {
|
|
1581
1595
|
return resumeRunFromContinuationImpl(this.replayResumeHost(), run, context);
|
|
1582
1596
|
}
|
|
1583
|
-
/** Start delivery, sandbox-sync, conversation-turn, background-review, and orphan-recovery workers. */
|
|
1597
|
+
/** Start delivery, sandbox-sync, conversation-turn, subagent, background-review, and orphan-recovery workers. */
|
|
1584
1598
|
startBackgroundWorkers(options = {}) {
|
|
1585
1599
|
return startBackgroundWorkersImpl({
|
|
1586
1600
|
env: this.env,
|
|
@@ -1589,6 +1603,7 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
1589
1603
|
startDeliveryWorker: (workerOptions) => this.startDeliveryWorker(workerOptions),
|
|
1590
1604
|
startSandboxSyncWorker: (workerOptions) => this.startSandboxSyncWorker(workerOptions),
|
|
1591
1605
|
startConversationTurnWorker: (workerOptions) => this.conversationTurnDispatcher.startWorker(workerOptions?.intervalMs),
|
|
1606
|
+
startBackgroundSubagentWorker: (workerOptions) => this.backgroundSubagents.startWorker(workerOptions?.intervalMs),
|
|
1592
1607
|
startBackgroundReviewWorker: (workerOptions) => this.startBackgroundReviewWorker(workerOptions),
|
|
1593
1608
|
startConnectionEventWorker: (workerOptions) => this.startConnectionEventWorker(workerOptions),
|
|
1594
1609
|
recoverIncompleteRuns: (recoveryOptions) => this.recoverIncompleteRuns(recoveryOptions),
|
|
@@ -1870,6 +1885,9 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
1870
1885
|
connectionsConfig: this.connectionsConfig,
|
|
1871
1886
|
surfaceForRun: (run) => surfaceForRun(this.manifest, run),
|
|
1872
1887
|
agentStateForRun: (runId) => this.agentStateForRun(runId),
|
|
1888
|
+
reportRunProgress: async (runId, data = {}) => {
|
|
1889
|
+
await this.state.appendEvent(runId, "run.progress_reported", data);
|
|
1890
|
+
},
|
|
1873
1891
|
ensureSkillsSeeded: (run) => this.ensureSkillsSeeded(surfaceForRun(this.manifest, run).path),
|
|
1874
1892
|
skillScopeForRun: (run) => this.skillScopeForRun(run),
|
|
1875
1893
|
scheduleScopeForRun: (run) => this.scheduleScopeForRun(run),
|
|
@@ -1879,6 +1897,10 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
1879
1897
|
loadConnectionDefinition: (connection) => this.loadConnectionDefinition(connection),
|
|
1880
1898
|
loadTool: (tool, run) => this.loadTool(tool, run),
|
|
1881
1899
|
runSubagent: (parentRunId, subagentName, task) => this.runSubagent(parentRunId, subagentName, task),
|
|
1900
|
+
queueSubagent: (parentRunId, subagentName, task) => this.queueSubagent(parentRunId, subagentName, task),
|
|
1901
|
+
listBackgroundWork: (rootRunId, includeTerminal) => this.listBackgroundWork(rootRunId, includeTerminal),
|
|
1902
|
+
getBackgroundWork: (rootRunId, childRunId) => this.getBackgroundWork(rootRunId, childRunId),
|
|
1903
|
+
cancelBackgroundWork: (rootRunId, childRunId) => this.cancelBackgroundWork(rootRunId, childRunId),
|
|
1882
1904
|
projectSkillIntoSandbox: (run, sandbox, skillName) => this.projectSkillIntoSandbox(run, sandbox, skillName),
|
|
1883
1905
|
hydrateLogicalPathForTool: (run, sandbox, path, options) => this.hydrateLogicalPathForTool(run, sandbox, path, options),
|
|
1884
1906
|
recordSandboxTombstone: (run, sandbox, path) => this.recordSandboxTombstone(run, sandbox, path),
|
|
@@ -1908,10 +1930,24 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
1908
1930
|
return selectToolImpl(this.toolExecutionHost(), options);
|
|
1909
1931
|
}
|
|
1910
1932
|
async executeTool(run, tool, input, sandboxHandle, approved, idempotencyKey) {
|
|
1911
|
-
|
|
1933
|
+
const abortController = new AbortController();
|
|
1934
|
+
const unregisterAbort = this.runProgress.registerAbort(run.id, abortController);
|
|
1935
|
+
try {
|
|
1936
|
+
return await executeToolImpl(this.toolExecutionHost(), run, tool, input, sandboxHandle, approved, idempotencyKey, abortController.signal);
|
|
1937
|
+
}
|
|
1938
|
+
finally {
|
|
1939
|
+
unregisterAbort();
|
|
1940
|
+
}
|
|
1912
1941
|
}
|
|
1913
1942
|
async executeToolWithRecord(run, tool, toolCall, input, sandboxHandle, approvedToolCall = false) {
|
|
1914
|
-
|
|
1943
|
+
const abortController = new AbortController();
|
|
1944
|
+
const unregisterAbort = this.runProgress.registerAbort(run.id, abortController);
|
|
1945
|
+
try {
|
|
1946
|
+
return await executeToolWithRecordImpl(this.toolExecutionHost(), run, tool, toolCall, input, sandboxHandle, approvedToolCall, abortController.signal);
|
|
1947
|
+
}
|
|
1948
|
+
finally {
|
|
1949
|
+
unregisterAbort();
|
|
1950
|
+
}
|
|
1915
1951
|
}
|
|
1916
1952
|
async durableStep(runId, key, fn, options) {
|
|
1917
1953
|
return durableStepImpl(this.toolExecutionHost(), runId, key, fn, options);
|
|
@@ -1980,94 +2016,38 @@ export class AssemblyLineRuntime extends WorkspaceRuntimeMethods {
|
|
|
1980
2016
|
removeTerminalAgentHookState(runId, event, this.eventHandlers, this.agentHookControllers, this.agentStateHandles);
|
|
1981
2017
|
}
|
|
1982
2018
|
async handleRuntimeEvent(runId, event) {
|
|
2019
|
+
if (eventRenewsRunProgress(event.type))
|
|
2020
|
+
await this.runProgress.renew(runId);
|
|
1983
2021
|
await this.dispatchHookEvent(runId, event);
|
|
1984
2022
|
await this.runtimeLearning.handleRuntimeEvent(runId, event.type);
|
|
1985
2023
|
}
|
|
1986
2024
|
async createAgentHookController(run, options, channel, conversationId, attachments) {
|
|
1987
|
-
const
|
|
1988
|
-
|
|
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;
|
|
2025
|
+
const created = await createMainAgentHookControllerImpl(this.agentHookControllerFactoryHost(), run, options, channel, conversationId, attachments);
|
|
2026
|
+
return this.rememberAgentHookController(run.id, created);
|
|
2024
2027
|
}
|
|
2025
2028
|
async createSubagentHookController(run, subagent, message, conversationId) {
|
|
2026
|
-
const
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2029
|
+
const created = await createSubagentHookControllerImpl(this.agentHookControllerFactoryHost(), run, subagent, message, conversationId);
|
|
2030
|
+
return this.rememberAgentHookController(run.id, created);
|
|
2031
|
+
}
|
|
2032
|
+
agentHookControllerFactoryHost() {
|
|
2033
|
+
return {
|
|
2030
2034
|
manifest: this.manifest,
|
|
2031
2035
|
state: this.state,
|
|
2032
2036
|
blob: this.blob,
|
|
2033
2037
|
sourceLoader: this.sourceLoader,
|
|
2034
2038
|
eventHandlers: this.eventHandlers,
|
|
2035
2039
|
logger: this.logger,
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
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),
|
|
2040
|
+
durableAgentScope: () => this.durableAgentScope(),
|
|
2041
|
+
listSkillNames: async (surfacePath) => (await this.listSkills(surfacePath)).map((skill) => skill.name).sort(),
|
|
2042
|
+
disabledToolsForRun: () => new Set(Object.entries(this.coreToolPolicy).filter(([, mode]) => mode === "disabled").map(([name]) => name)),
|
|
2061
2043
|
createCheckpoint: (input) => this.createCheckpoint(input),
|
|
2062
2044
|
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;
|
|
2045
|
+
};
|
|
2067
2046
|
}
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2047
|
+
rememberAgentHookController(runId, created) {
|
|
2048
|
+
this.agentStateHandles.set(runId, created.agentState);
|
|
2049
|
+
this.agentHookControllers.set(runId, created.controller);
|
|
2050
|
+
return created.controller;
|
|
2071
2051
|
}
|
|
2072
2052
|
agentStateForRun(runId) {
|
|
2073
2053
|
const handle = this.agentStateHandles.get(runId);
|