@namzu/sdk 36.0.0 → 37.0.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/CHANGELOG.md +180 -0
- package/README.md +68 -41
- package/dist/bridge/a2a/mapper.d.ts.map +1 -1
- package/dist/bridge/a2a/mapper.js +2 -0
- package/dist/bridge/a2a/mapper.js.map +1 -1
- package/dist/bridge/sse/mapper.d.ts.map +1 -1
- package/dist/bridge/sse/mapper.js +2 -0
- package/dist/bridge/sse/mapper.js.map +1 -1
- package/dist/compaction/extractor.d.ts +1 -1
- package/dist/compaction/extractor.d.ts.map +1 -1
- package/dist/compaction/extractor.js +15 -7
- package/dist/compaction/extractor.js.map +1 -1
- package/dist/compaction/manager.d.ts +2 -0
- package/dist/compaction/manager.d.ts.map +1 -1
- package/dist/compaction/manager.js +12 -1
- package/dist/compaction/manager.js.map +1 -1
- package/dist/compaction/verifier.d.ts.map +1 -1
- package/dist/compaction/verifier.js +82 -15
- package/dist/compaction/verifier.js.map +1 -1
- package/dist/contracts/schemas.d.ts +10 -10
- package/dist/eval/harness-verification.d.ts +63 -0
- package/dist/eval/harness-verification.d.ts.map +1 -0
- package/dist/eval/harness-verification.js +165 -0
- package/dist/eval/harness-verification.js.map +1 -0
- package/dist/eval/index.d.ts +2 -0
- package/dist/eval/index.d.ts.map +1 -1
- package/dist/eval/index.js +1 -0
- package/dist/eval/index.js.map +1 -1
- package/dist/execution/code-runtime/json-value.d.ts +10 -0
- package/dist/execution/code-runtime/json-value.d.ts.map +1 -0
- package/dist/execution/code-runtime/json-value.js +89 -0
- package/dist/execution/code-runtime/json-value.js.map +1 -0
- package/dist/execution/code-runtime/worker-program.d.ts +8 -0
- package/dist/execution/code-runtime/worker-program.d.ts.map +1 -0
- package/dist/execution/code-runtime/worker-program.js +240 -0
- package/dist/execution/code-runtime/worker-program.js.map +1 -0
- package/dist/execution/code-runtime/worker.d.ts +22 -0
- package/dist/execution/code-runtime/worker.d.ts.map +1 -1
- package/dist/execution/code-runtime/worker.js +148 -111
- package/dist/execution/code-runtime/worker.js.map +1 -1
- package/dist/manager/agent/lifecycle.d.ts +12 -0
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +306 -37
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/manager/run/persistence.d.ts +2 -0
- package/dist/manager/run/persistence.d.ts.map +1 -1
- package/dist/manager/run/persistence.js +6 -0
- package/dist/manager/run/persistence.js.map +1 -1
- package/dist/provider/capabilities.d.ts +3 -1
- package/dist/provider/capabilities.d.ts.map +1 -1
- package/dist/provider/capabilities.js +13 -0
- package/dist/provider/capabilities.js.map +1 -1
- package/dist/provider/fallback.d.ts.map +1 -1
- package/dist/provider/fallback.js +2 -0
- package/dist/provider/fallback.js.map +1 -1
- package/dist/public-runtime.d.ts +3 -1
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +2 -1
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-tools.d.ts +1 -1
- package/dist/public-tools.d.ts.map +1 -1
- package/dist/public-tools.js +1 -1
- package/dist/public-tools.js.map +1 -1
- package/dist/public-types.d.ts +1 -0
- package/dist/public-types.d.ts.map +1 -1
- package/dist/registry/tool/execute.d.ts +3 -0
- package/dist/registry/tool/execute.d.ts.map +1 -1
- package/dist/registry/tool/execute.js +11 -80
- package/dist/registry/tool/execute.js.map +1 -1
- package/dist/run/command-gate.d.ts.map +1 -1
- package/dist/run/command-gate.js +65 -12
- package/dist/run/command-gate.js.map +1 -1
- package/dist/run/index.d.ts +2 -0
- package/dist/run/index.d.ts.map +1 -1
- package/dist/run/index.js +1 -0
- package/dist/run/index.js.map +1 -1
- package/dist/run/memory-promoter.d.ts +3 -35
- package/dist/run/memory-promoter.d.ts.map +1 -1
- package/dist/run/memory-promoter.js +32 -40
- package/dist/run/memory-promoter.js.map +1 -1
- package/dist/run/memory-recall.d.ts +25 -0
- package/dist/run/memory-recall.d.ts.map +1 -0
- package/dist/run/memory-recall.js +228 -0
- package/dist/run/memory-recall.js.map +1 -0
- package/dist/run/reporter.d.ts.map +1 -1
- package/dist/run/reporter.js +1 -0
- package/dist/run/reporter.js.map +1 -1
- package/dist/run/token-budget.d.ts +2 -0
- package/dist/run/token-budget.d.ts.map +1 -1
- package/dist/run/token-budget.js +4 -0
- package/dist/run/token-budget.js.map +1 -1
- package/dist/run/workspace-fingerprint.d.ts +10 -3
- package/dist/run/workspace-fingerprint.d.ts.map +1 -1
- package/dist/run/workspace-fingerprint.js +17 -8
- package/dist/run/workspace-fingerprint.js.map +1 -1
- package/dist/runtime/query/checkpoint.d.ts +14 -0
- package/dist/runtime/query/checkpoint.d.ts.map +1 -1
- package/dist/runtime/query/checkpoint.js +82 -1
- package/dist/runtime/query/checkpoint.js.map +1 -1
- package/dist/runtime/query/executor.d.ts +5 -0
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +70 -14
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/index.d.ts +5 -8
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +54 -7
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts +10 -0
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +325 -36
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/native-output.d.ts +10 -0
- package/dist/runtime/query/iteration/native-output.d.ts.map +1 -0
- package/dist/runtime/query/iteration/native-output.js +32 -0
- package/dist/runtime/query/iteration/native-output.js.map +1 -0
- package/dist/runtime/query/iteration/phases/advisory.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/advisory.js +18 -13
- package/dist/runtime/query/iteration/phases/advisory.js.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.d.ts +2 -0
- package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.js +32 -11
- package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +9 -0
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/iteration/phases/working-memory.d.ts +1 -1
- package/dist/runtime/query/iteration/phases/working-memory.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/working-memory.js +23 -6
- package/dist/runtime/query/iteration/phases/working-memory.js.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.js +2 -0
- package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
- package/dist/runtime/query/steering.d.ts +6 -2
- package/dist/runtime/query/steering.d.ts.map +1 -1
- package/dist/runtime/query/steering.js +17 -2
- package/dist/runtime/query/steering.js.map +1 -1
- package/dist/runtime/query/tool-call-budget.d.ts +19 -0
- package/dist/runtime/query/tool-call-budget.d.ts.map +1 -0
- package/dist/runtime/query/tool-call-budget.js +110 -0
- package/dist/runtime/query/tool-call-budget.js.map +1 -0
- package/dist/runtime/query/tooling.d.ts +2 -0
- package/dist/runtime/query/tooling.d.ts.map +1 -1
- package/dist/runtime/query/tooling.js +4 -0
- package/dist/runtime/query/tooling.js.map +1 -1
- package/dist/scheduler/local.d.ts.map +1 -1
- package/dist/scheduler/local.js +1 -0
- package/dist/scheduler/local.js.map +1 -1
- package/dist/session/handoff/capacity.d.ts +2 -2
- package/dist/session/handoff/capacity.d.ts.map +1 -1
- package/dist/session/handoff/capacity.js +3 -2
- package/dist/session/handoff/capacity.js.map +1 -1
- package/dist/store/memory/disk.d.ts +6 -2
- package/dist/store/memory/disk.d.ts.map +1 -1
- package/dist/store/memory/disk.js +42 -25
- package/dist/store/memory/disk.js.map +1 -1
- package/dist/store/memory/index.d.ts +4 -0
- package/dist/store/memory/index.d.ts.map +1 -1
- package/dist/store/memory/index.js +55 -19
- package/dist/store/memory/index.js.map +1 -1
- package/dist/store/memory/memory.d.ts +3 -2
- package/dist/store/memory/memory.d.ts.map +1 -1
- package/dist/store/memory/memory.js +11 -2
- package/dist/store/memory/memory.js.map +1 -1
- package/dist/store/memory/operation-lock.d.ts +11 -0
- package/dist/store/memory/operation-lock.d.ts.map +1 -0
- package/dist/store/memory/operation-lock.js +94 -0
- package/dist/store/memory/operation-lock.js.map +1 -0
- package/dist/tools/builtins/computer-use.d.ts.map +1 -1
- package/dist/tools/builtins/computer-use.js +60 -10
- package/dist/tools/builtins/computer-use.js.map +1 -1
- package/dist/tools/builtins/run-code.d.ts +6 -0
- package/dist/tools/builtins/run-code.d.ts.map +1 -1
- package/dist/tools/builtins/run-code.js +15 -4
- package/dist/tools/builtins/run-code.js.map +1 -1
- package/dist/tools/builtins/search-tools.d.ts.map +1 -1
- package/dist/tools/builtins/search-tools.js +14 -2
- package/dist/tools/builtins/search-tools.js.map +1 -1
- package/dist/tools/defineTool.d.ts +2 -0
- package/dist/tools/defineTool.d.ts.map +1 -1
- package/dist/tools/defineTool.js +3 -0
- package/dist/tools/defineTool.js.map +1 -1
- package/dist/tools/memory/delete.d.ts +4 -0
- package/dist/tools/memory/delete.d.ts.map +1 -0
- package/dist/tools/memory/delete.js +26 -0
- package/dist/tools/memory/delete.js.map +1 -0
- package/dist/tools/memory/index.d.ts +2 -0
- package/dist/tools/memory/index.d.ts.map +1 -1
- package/dist/tools/memory/index.js +6 -0
- package/dist/tools/memory/index.js.map +1 -1
- package/dist/tools/memory/save.d.ts.map +1 -1
- package/dist/tools/memory/save.js +3 -2
- package/dist/tools/memory/save.js.map +1 -1
- package/dist/tools/memory/search.d.ts.map +1 -1
- package/dist/tools/memory/search.js +12 -5
- package/dist/tools/memory/search.js.map +1 -1
- package/dist/tools/memory/update.d.ts +4 -0
- package/dist/tools/memory/update.d.ts.map +1 -0
- package/dist/tools/memory/update.js +47 -0
- package/dist/tools/memory/update.js.map +1 -0
- package/dist/types/agent/scheduler.d.ts +5 -0
- package/dist/types/agent/scheduler.d.ts.map +1 -1
- package/dist/types/agent/task.d.ts +10 -0
- package/dist/types/agent/task.d.ts.map +1 -1
- package/dist/types/computer-use/index.d.ts +6 -0
- package/dist/types/computer-use/index.d.ts.map +1 -1
- package/dist/types/computer-use/index.js.map +1 -1
- package/dist/types/errors/catalog.js +1 -1
- package/dist/types/errors/catalog.js.map +1 -1
- package/dist/types/hitl/index.d.ts +11 -1
- package/dist/types/hitl/index.d.ts.map +1 -1
- package/dist/types/hitl/index.js.map +1 -1
- package/dist/types/memory/index.d.ts +14 -1
- package/dist/types/memory/index.d.ts.map +1 -1
- package/dist/types/project/entity.d.ts +1 -0
- package/dist/types/project/entity.d.ts.map +1 -1
- package/dist/types/provider/config.d.ts +2 -0
- package/dist/types/provider/config.d.ts.map +1 -1
- package/dist/types/provider/model.d.ts +4 -0
- package/dist/types/provider/model.d.ts.map +1 -1
- package/dist/types/run/answer-review.d.ts +2 -0
- package/dist/types/run/answer-review.d.ts.map +1 -1
- package/dist/types/run/events.d.ts +9 -0
- package/dist/types/run/events.d.ts.map +1 -1
- package/dist/types/run/events.js.map +1 -1
- package/dist/types/run/prepare-step.d.ts +19 -1
- package/dist/types/run/prepare-step.d.ts.map +1 -1
- package/dist/types/structured-output/index.d.ts +8 -2
- package/dist/types/structured-output/index.d.ts.map +1 -1
- package/dist/types/tool/index.d.ts +15 -0
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/dist/utils/json-snapshot.d.ts +3 -0
- package/dist/utils/json-snapshot.d.ts.map +1 -0
- package/dist/utils/json-snapshot.js +79 -0
- package/dist/utils/json-snapshot.js.map +1 -0
- package/package.json +4 -2
- package/src/bridge/a2a/mapper.ts +2 -0
- package/src/bridge/sse/mapper.ts +2 -0
- package/src/compaction/extractor.ts +21 -8
- package/src/compaction/manager.ts +11 -1
- package/src/compaction/verifier.ts +80 -18
- package/src/eval/harness-verification.ts +270 -0
- package/src/eval/index.ts +10 -0
- package/src/execution/code-runtime/json-value.ts +82 -0
- package/src/execution/code-runtime/worker-program.ts +239 -0
- package/src/execution/code-runtime/worker.ts +164 -111
- package/src/manager/agent/lifecycle.ts +340 -45
- package/src/manager/run/persistence.ts +7 -0
- package/src/provider/capabilities.ts +25 -1
- package/src/provider/fallback.ts +2 -0
- package/src/public-runtime.ts +4 -0
- package/src/public-tools.ts +5 -1
- package/src/public-types.ts +1 -0
- package/src/registry/tool/execute.ts +17 -79
- package/src/run/command-gate.ts +61 -13
- package/src/run/index.ts +2 -0
- package/src/run/memory-promoter.ts +32 -40
- package/src/run/memory-recall.ts +254 -0
- package/src/run/reporter.ts +1 -0
- package/src/run/token-budget.ts +4 -0
- package/src/run/workspace-fingerprint.ts +17 -8
- package/src/runtime/query/checkpoint.ts +96 -2
- package/src/runtime/query/executor.ts +77 -14
- package/src/runtime/query/index.ts +73 -16
- package/src/runtime/query/iteration/index.ts +377 -44
- package/src/runtime/query/iteration/native-output.ts +35 -0
- package/src/runtime/query/iteration/phases/advisory.ts +21 -11
- package/src/runtime/query/iteration/phases/compaction.ts +36 -14
- package/src/runtime/query/iteration/phases/context.ts +9 -0
- package/src/runtime/query/iteration/phases/tool-review.ts +5 -1
- package/src/runtime/query/iteration/phases/working-memory.ts +23 -5
- package/src/runtime/query/iteration/stream-turn.ts +2 -0
- package/src/runtime/query/steering.ts +19 -2
- package/src/runtime/query/tool-call-budget.ts +115 -0
- package/src/runtime/query/tooling.ts +6 -0
- package/src/scheduler/local.ts +1 -0
- package/src/session/handoff/capacity.ts +7 -3
- package/src/store/memory/disk.ts +52 -30
- package/src/store/memory/index.ts +75 -27
- package/src/store/memory/memory.ts +18 -6
- package/src/store/memory/operation-lock.ts +99 -0
- package/src/tools/builtins/computer-use.ts +61 -7
- package/src/tools/builtins/run-code.ts +24 -5
- package/src/tools/builtins/search-tools.ts +18 -3
- package/src/tools/defineTool.ts +5 -0
- package/src/tools/memory/delete.ts +29 -0
- package/src/tools/memory/index.ts +6 -0
- package/src/tools/memory/save.ts +4 -2
- package/src/tools/memory/search.ts +12 -5
- package/src/tools/memory/update.ts +50 -0
- package/src/types/agent/scheduler.ts +6 -0
- package/src/types/agent/task.ts +13 -0
- package/src/types/computer-use/index.ts +6 -0
- package/src/types/errors/catalog.ts +1 -1
- package/src/types/hitl/index.ts +11 -1
- package/src/types/memory/index.ts +16 -1
- package/src/types/project/entity.ts +1 -0
- package/src/types/provider/config.ts +2 -0
- package/src/types/provider/model.ts +4 -0
- package/src/types/run/answer-review.ts +2 -0
- package/src/types/run/events.ts +10 -0
- package/src/types/run/prepare-step.ts +19 -1
- package/src/types/structured-output/index.ts +15 -2
- package/src/types/tool/index.ts +16 -0
- package/src/utils/json-snapshot.ts +76 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AGENT_MANAGER_DEFAULTS } from '../../constants/agent/index.js';
|
|
2
|
+
import { EMPTY_TOKEN_USAGE } from '../../constants/limits.js';
|
|
2
3
|
import { GENAI } from '../../constants/telemetry/index.js';
|
|
3
4
|
import { DelegationCapacityExceeded, } from '../../session/handoff/capacity.js';
|
|
4
5
|
import { isTerminalAgentTaskState } from '../../types/agent/task.js';
|
|
@@ -13,6 +14,9 @@ import { SCOPE_ATTRIBUTE } from '../../utils/log/types.js';
|
|
|
13
14
|
import { resolveLogger } from '../../utils/logger.js';
|
|
14
15
|
import { requireOpenProject } from '../project/lifecycle.js';
|
|
15
16
|
import { resolveTopicManager } from '../topic/dependency.js';
|
|
17
|
+
/** Internal backpressure: the parent's unmeasured request owns its budget until its receipt. */
|
|
18
|
+
class ParentBudgetRequestPending extends Error {
|
|
19
|
+
}
|
|
16
20
|
/**
|
|
17
21
|
* Combine a child's own environment with what its parent passed down.
|
|
18
22
|
*
|
|
@@ -42,9 +46,18 @@ export class AgentManager {
|
|
|
42
46
|
spawnLocks = new Map();
|
|
43
47
|
deps;
|
|
44
48
|
topicManager;
|
|
49
|
+
pendingSpawns = new Map();
|
|
50
|
+
drainingParents = new Set();
|
|
51
|
+
executingTasks = new Set();
|
|
52
|
+
cancelingTasks = new Set();
|
|
53
|
+
admissionTimer;
|
|
54
|
+
disposed = false;
|
|
45
55
|
constructor(registry, config, deps) {
|
|
46
56
|
this.registry = registry;
|
|
47
57
|
this.config = { ...AGENT_MANAGER_DEFAULTS, ...config };
|
|
58
|
+
const maxPending = this.config.maxPendingTasks ?? 128;
|
|
59
|
+
if (!Number.isSafeInteger(maxPending) || maxPending < 1)
|
|
60
|
+
throw new Error('maxPendingTasks must be a positive safe integer');
|
|
48
61
|
this.log = resolveLogger(deps.log).child({
|
|
49
62
|
[SCOPE_ATTRIBUTE]: 'manager/agent/lifecycle',
|
|
50
63
|
});
|
|
@@ -52,6 +65,170 @@ export class AgentManager {
|
|
|
52
65
|
this.topicManager = resolveTopicManager(deps);
|
|
53
66
|
}
|
|
54
67
|
async sendMessage(options, context, listener) {
|
|
68
|
+
if (this.disposed)
|
|
69
|
+
throw new Error('Agent manager is disposed');
|
|
70
|
+
if (this.config.capacityBehavior === 'queue')
|
|
71
|
+
return this.enqueueMessage(options, context, listener);
|
|
72
|
+
return this.startMessage(options, context, listener);
|
|
73
|
+
}
|
|
74
|
+
async enqueueMessage(options, context, listener) {
|
|
75
|
+
context.parentAbortController.signal.throwIfAborted();
|
|
76
|
+
if (context.depth >= this.config.maxDepth)
|
|
77
|
+
throw new Error(`Max task depth ${this.config.maxDepth} exceeded`);
|
|
78
|
+
if (options.tenantId !== context.tenantId)
|
|
79
|
+
throw new Error('Tenant mismatch: cross-tenant spawn rejected');
|
|
80
|
+
const definition = this.registry.getOrThrow(options.agentId);
|
|
81
|
+
const count = [...this.pendingSpawns.values()].reduce((sum, queue) => sum + queue.length, 0);
|
|
82
|
+
if (count >= (this.config.maxPendingTasks ?? 128))
|
|
83
|
+
throw new Error(`Delegation queue is full (${this.config.maxPendingTasks ?? 128} pending tasks). Wait for existing tasks before submitting more work.`);
|
|
84
|
+
const task = {
|
|
85
|
+
taskId: generateTaskId(),
|
|
86
|
+
agentId: options.agentId,
|
|
87
|
+
agent: definition.typedAgent,
|
|
88
|
+
childAbortController: createChildAbortController(context.parentAbortController),
|
|
89
|
+
context,
|
|
90
|
+
state: 'pending',
|
|
91
|
+
pendingMessages: [],
|
|
92
|
+
createdAt: Date.now(),
|
|
93
|
+
runEventListener: listener,
|
|
94
|
+
};
|
|
95
|
+
this.instances.set(task.taskId, task);
|
|
96
|
+
const onAbort = () => {
|
|
97
|
+
// Before admission this observer owns cancellation. Once child scope
|
|
98
|
+
// exists, startup rollback may abort its controller for a configuration
|
|
99
|
+
// error; that is a failure, not a user cancellation.
|
|
100
|
+
if (task.context === context || context.parentAbortController.signal.aborted)
|
|
101
|
+
this.cancel(task.taskId, 'parent');
|
|
102
|
+
};
|
|
103
|
+
task.childAbortController.signal.addEventListener('abort', onAbort, { once: true });
|
|
104
|
+
const entry = {
|
|
105
|
+
ready: false,
|
|
106
|
+
task,
|
|
107
|
+
options,
|
|
108
|
+
context,
|
|
109
|
+
listener,
|
|
110
|
+
removeAbortListener: () => task.childAbortController.signal.removeEventListener('abort', onAbort),
|
|
111
|
+
};
|
|
112
|
+
const queue = this.pendingSpawns.get(options.parentSessionId) ?? [];
|
|
113
|
+
queue.push(entry);
|
|
114
|
+
this.pendingSpawns.set(options.parentSessionId, queue);
|
|
115
|
+
this.emit({
|
|
116
|
+
type: 'pending',
|
|
117
|
+
taskId: task.taskId,
|
|
118
|
+
agentId: options.agentId,
|
|
119
|
+
parentAgentId: context.parentAgentId,
|
|
120
|
+
depth: context.depth,
|
|
121
|
+
});
|
|
122
|
+
try {
|
|
123
|
+
await listener?.({
|
|
124
|
+
type: 'agent_pending',
|
|
125
|
+
runId: context.parentRunId,
|
|
126
|
+
taskId: task.taskId,
|
|
127
|
+
parentAgentId: context.parentAgentId,
|
|
128
|
+
childAgentId: options.agentId,
|
|
129
|
+
depth: context.depth,
|
|
130
|
+
});
|
|
131
|
+
entry.ready = true;
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
this.failAdmission(entry, error);
|
|
135
|
+
}
|
|
136
|
+
this.pumpAdmissions(options.parentSessionId);
|
|
137
|
+
return task;
|
|
138
|
+
}
|
|
139
|
+
pumpAdmissions(parentSessionId) {
|
|
140
|
+
if (this.disposed || this.drainingParents.has(parentSessionId))
|
|
141
|
+
return;
|
|
142
|
+
this.drainingParents.add(parentSessionId);
|
|
143
|
+
void this.drainAdmissions(parentSessionId)
|
|
144
|
+
.finally(() => {
|
|
145
|
+
this.drainingParents.delete(parentSessionId);
|
|
146
|
+
// External handoffs and metadata changes have no manager event. A
|
|
147
|
+
// single slow, unref'ed timer observes those without spinning or
|
|
148
|
+
// keeping a host alive. Actual completions wake admission directly.
|
|
149
|
+
if (!this.disposed && this.pendingSpawns.size > 0 && !this.admissionTimer) {
|
|
150
|
+
this.admissionTimer = setTimeout(() => {
|
|
151
|
+
this.admissionTimer = undefined;
|
|
152
|
+
for (const parent of this.pendingSpawns.keys())
|
|
153
|
+
this.pumpAdmissions(parent);
|
|
154
|
+
}, 250);
|
|
155
|
+
this.admissionTimer.unref?.();
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
.catch((error) => this.log.error('Delegation admission failed', {
|
|
159
|
+
'exception.message': toErrorMessage(error),
|
|
160
|
+
}));
|
|
161
|
+
}
|
|
162
|
+
async drainAdmissions(parentSessionId) {
|
|
163
|
+
const queue = this.pendingSpawns.get(parentSessionId);
|
|
164
|
+
if (!queue)
|
|
165
|
+
return;
|
|
166
|
+
while (!this.disposed && queue.length > 0) {
|
|
167
|
+
const entry = queue[0];
|
|
168
|
+
if (!entry)
|
|
169
|
+
break;
|
|
170
|
+
if (isTerminalAgentTaskState(entry.task.state)) {
|
|
171
|
+
entry.removeAbortListener();
|
|
172
|
+
queue.shift();
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
// A concurrent enqueue can pump this same FIFO while the head's
|
|
176
|
+
// pending listener still owns its acknowledgement. Do not provision
|
|
177
|
+
// or spend until that acknowledgement succeeds.
|
|
178
|
+
if (!entry.ready)
|
|
179
|
+
return;
|
|
180
|
+
try {
|
|
181
|
+
await entry.options.beforeStart?.();
|
|
182
|
+
entry.task.childAbortController.signal.throwIfAborted();
|
|
183
|
+
await this.validateSpawn(entry.options, entry.context);
|
|
184
|
+
entry.task.childAbortController.signal.throwIfAborted();
|
|
185
|
+
await this.startMessage(entry.options, entry.context, entry.listener, entry.task);
|
|
186
|
+
entry.removeAbortListener();
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
if ((error instanceof ParentBudgetRequestPending ||
|
|
190
|
+
(error instanceof DelegationCapacityExceeded && error.details.dimension === 'width')) &&
|
|
191
|
+
!isTerminalAgentTaskState(entry.task.state))
|
|
192
|
+
return;
|
|
193
|
+
this.failAdmission(entry, error);
|
|
194
|
+
}
|
|
195
|
+
queue.shift();
|
|
196
|
+
}
|
|
197
|
+
if (queue.length === 0 && this.pendingSpawns.get(parentSessionId) === queue)
|
|
198
|
+
this.pendingSpawns.delete(parentSessionId);
|
|
199
|
+
}
|
|
200
|
+
failAdmission(entry, reason) {
|
|
201
|
+
entry.removeAbortListener();
|
|
202
|
+
const task = entry.task;
|
|
203
|
+
if (isTerminalAgentTaskState(task.state))
|
|
204
|
+
return;
|
|
205
|
+
task.childAbortController.abort(reason);
|
|
206
|
+
const error = toErrorMessage(reason);
|
|
207
|
+
task.result = {
|
|
208
|
+
runId: entry.context.parentRunId,
|
|
209
|
+
status: 'failed',
|
|
210
|
+
usage: { ...EMPTY_TOKEN_USAGE },
|
|
211
|
+
cost: { ...ZERO_COST },
|
|
212
|
+
iterations: 0,
|
|
213
|
+
durationMs: Date.now() - task.createdAt,
|
|
214
|
+
messages: [],
|
|
215
|
+
lastError: error,
|
|
216
|
+
};
|
|
217
|
+
task.state = 'failed';
|
|
218
|
+
task.completedAt = Date.now();
|
|
219
|
+
this.emit({ type: 'failed', taskId: task.taskId, error });
|
|
220
|
+
this.emitRunEvent(task, {
|
|
221
|
+
type: 'agent_failed',
|
|
222
|
+
runId: entry.context.parentRunId,
|
|
223
|
+
taskId: task.taskId,
|
|
224
|
+
error,
|
|
225
|
+
});
|
|
226
|
+
this.scheduleEviction(task.taskId);
|
|
227
|
+
this.resolveCompletionCallbacks(task.taskId);
|
|
228
|
+
}
|
|
229
|
+
async startMessage(options, context, listener, queuedTask) {
|
|
230
|
+
await options.beforeStart?.();
|
|
231
|
+
queuedTask?.childAbortController.signal.throwIfAborted();
|
|
55
232
|
if (context.depth >= this.config.maxDepth) {
|
|
56
233
|
throw new Error(`Max task depth ${this.config.maxDepth} exceeded (current: ${context.depth}). Recursive agent delegation is limited to prevent resource exhaustion.`);
|
|
57
234
|
}
|
|
@@ -83,9 +260,21 @@ export class AgentManager {
|
|
|
83
260
|
// Reserve synchronously before provisioning yields. The authority is shared
|
|
84
261
|
// across managers and nested sessions, while the session lock below only
|
|
85
262
|
// serializes filesystem capacity checks.
|
|
263
|
+
// Queued siblings share the available budget with the parent. The first
|
|
264
|
+
// of eight children receives at most one ninth; later siblings receive
|
|
265
|
+
// comparable grants instead of a geometric 1/2, 1/4, ... starvation tail.
|
|
266
|
+
let budgetShares = 1;
|
|
267
|
+
if (queuedTask) {
|
|
268
|
+
const project = await requireOpenProject(this.deps.sessionStore, context.projectId, context.tenantId, 'spawn');
|
|
269
|
+
const children = await this.deps.sessionStore.getChildren(options.parentSessionId, context.tenantId);
|
|
270
|
+
const active = children.filter((child) => child.status !== 'idle' && child.status !== 'failed' && child.status !== 'archived').length;
|
|
271
|
+
budgetShares = Math.max(2, project.config.maxDelegationWidth - active + 1);
|
|
272
|
+
}
|
|
273
|
+
context.parentAbortController.signal.throwIfAborted();
|
|
274
|
+
queuedTask?.childAbortController.signal.throwIfAborted();
|
|
86
275
|
const remaining = context.budget.remaining;
|
|
87
276
|
const maxAllocation = Number.isFinite(remaining)
|
|
88
|
-
? Math.floor(remaining * this.config.maxBudgetFraction)
|
|
277
|
+
? Math.floor(Math.min(remaining * this.config.maxBudgetFraction, remaining / budgetShares))
|
|
89
278
|
: (options.budgetAllocation?.tokenBudget ??
|
|
90
279
|
(options.configOverrides?.tokenBudget === 0
|
|
91
280
|
? 200_000
|
|
@@ -97,6 +286,12 @@ export class AgentManager {
|
|
|
97
286
|
message: `Cannot spawn "${options.agentId}": the parent has ${remaining} tokens remaining; a child allocation must be a finite positive integer.`,
|
|
98
287
|
});
|
|
99
288
|
}
|
|
289
|
+
// No await between this check and reserve: a parent's response may start
|
|
290
|
+
// during the scope reads above. Its own in-flight request is temporary
|
|
291
|
+
// backpressure; descendant requests are expected during a fan-out.
|
|
292
|
+
// Invalid/zero allocations above still fail rather than waiting forever.
|
|
293
|
+
if (queuedTask && context.budget.hasInFlightRequest)
|
|
294
|
+
throw new ParentBudgetRequestPending('The parent provider request is still in flight');
|
|
100
295
|
const childBudget = context.budget.reserve(allocatedTokens);
|
|
101
296
|
let spawnRecord;
|
|
102
297
|
try {
|
|
@@ -111,8 +306,11 @@ export class AgentManager {
|
|
|
111
306
|
let childAbortController;
|
|
112
307
|
let agentTask;
|
|
113
308
|
try {
|
|
114
|
-
childAbortController =
|
|
115
|
-
|
|
309
|
+
childAbortController =
|
|
310
|
+
queuedTask?.childAbortController ??
|
|
311
|
+
createChildAbortController(context.parentAbortController);
|
|
312
|
+
childAbortController.signal.throwIfAborted();
|
|
313
|
+
const taskId = queuedTask?.taskId ?? generateTaskId();
|
|
116
314
|
const childParentActor = {
|
|
117
315
|
kind: 'agent',
|
|
118
316
|
agentId: context.parentAgentId,
|
|
@@ -155,38 +353,40 @@ export class AgentManager {
|
|
|
155
353
|
parentActor: childParentActor,
|
|
156
354
|
...(resolvedDenies.length > 0 ? { toolDenies: resolvedDenies } : {}),
|
|
157
355
|
};
|
|
158
|
-
agentTask = {
|
|
356
|
+
agentTask = Object.assign(queuedTask ?? {}, {
|
|
159
357
|
taskId,
|
|
160
358
|
agentId: options.agentId,
|
|
161
359
|
agent,
|
|
162
360
|
childAbortController,
|
|
163
361
|
context: childContext,
|
|
164
362
|
state: 'pending',
|
|
165
|
-
pendingMessages: [],
|
|
166
|
-
createdAt: Date.now(),
|
|
363
|
+
pendingMessages: queuedTask?.pendingMessages ?? [],
|
|
364
|
+
createdAt: queuedTask?.createdAt ?? Date.now(),
|
|
167
365
|
runEventListener: listener,
|
|
168
|
-
};
|
|
366
|
+
});
|
|
169
367
|
childAbortController.signal.throwIfAborted();
|
|
170
368
|
this.instances.set(taskId, agentTask);
|
|
171
369
|
if (resolvedDenies.length > 0)
|
|
172
370
|
spawnRecord.resolvedToolDenies = resolvedDenies;
|
|
173
371
|
this.spawnRecords.set(taskId, spawnRecord);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
agentId: options.agentId,
|
|
178
|
-
parentAgentId: context.parentAgentId,
|
|
179
|
-
depth: context.depth,
|
|
180
|
-
});
|
|
181
|
-
if (listener) {
|
|
182
|
-
await listener({
|
|
183
|
-
type: 'agent_pending',
|
|
184
|
-
runId: context.parentRunId,
|
|
372
|
+
if (!queuedTask)
|
|
373
|
+
this.emit({
|
|
374
|
+
type: 'pending',
|
|
185
375
|
taskId,
|
|
376
|
+
agentId: options.agentId,
|
|
186
377
|
parentAgentId: context.parentAgentId,
|
|
187
|
-
childAgentId: options.agentId,
|
|
188
378
|
depth: context.depth,
|
|
189
379
|
});
|
|
380
|
+
if (listener) {
|
|
381
|
+
if (!queuedTask)
|
|
382
|
+
await listener({
|
|
383
|
+
type: 'agent_pending',
|
|
384
|
+
runId: context.parentRunId,
|
|
385
|
+
taskId,
|
|
386
|
+
parentAgentId: context.parentAgentId,
|
|
387
|
+
childAgentId: options.agentId,
|
|
388
|
+
depth: context.depth,
|
|
389
|
+
});
|
|
190
390
|
const lineage = {
|
|
191
391
|
parentSessionId: spawnRecord.parentSessionId,
|
|
192
392
|
rootSessionId: spawnRecord.rootSessionId,
|
|
@@ -373,7 +573,10 @@ export class AgentManager {
|
|
|
373
573
|
childAbortController.signal.throwIfAborted();
|
|
374
574
|
await childBudget.flush();
|
|
375
575
|
childAbortController.signal.throwIfAborted();
|
|
376
|
-
this.
|
|
576
|
+
this.executingTasks.add(taskId);
|
|
577
|
+
const runningTask = agentTask;
|
|
578
|
+
this.runChild(runningTask, options, childConfig, listener)
|
|
579
|
+
.catch(async (err) => {
|
|
377
580
|
// A thrown invocation supplied no final usage receipt. Keep its
|
|
378
581
|
// reservation, including when its task handle was canceled or evicted.
|
|
379
582
|
let failure = err;
|
|
@@ -383,8 +586,24 @@ export class AgentManager {
|
|
|
383
586
|
catch (writeError) {
|
|
384
587
|
failure = writeError;
|
|
385
588
|
}
|
|
386
|
-
|
|
387
|
-
|
|
589
|
+
// Cancellation may already have published a terminal handle. Its
|
|
590
|
+
// invocation has only NOW stopped; release the persisted edge here.
|
|
591
|
+
if (!this.instances.has(taskId) || isTerminalAgentTaskState(runningTask.state)) {
|
|
592
|
+
await this.failSubSession(spawnRecord);
|
|
593
|
+
}
|
|
594
|
+
else
|
|
595
|
+
this.markFailed(taskId, toErrorMessage(failure));
|
|
596
|
+
})
|
|
597
|
+
.finally(() => {
|
|
598
|
+
this.executingTasks.delete(taskId);
|
|
599
|
+
if (!this.instances.has(taskId))
|
|
600
|
+
this.spawnRecords.delete(taskId);
|
|
601
|
+
this.pumpAdmissions(options.parentSessionId);
|
|
602
|
+
})
|
|
603
|
+
.catch((error) => this.log.warn('Child cleanup failed', {
|
|
604
|
+
'namzu.task.id': taskId,
|
|
605
|
+
'exception.message': toErrorMessage(error),
|
|
606
|
+
}));
|
|
388
607
|
return agentTask;
|
|
389
608
|
}
|
|
390
609
|
catch (err) {
|
|
@@ -392,7 +611,7 @@ export class AgentManager {
|
|
|
392
611
|
// provisioned resources are still ours to return. A builder/listener
|
|
393
612
|
// failure must not strand a pending task the caller never received.
|
|
394
613
|
if (agentTask) {
|
|
395
|
-
await this.rollbackUnstartedSpawn(agentTask, spawnRecord, err);
|
|
614
|
+
await this.rollbackUnstartedSpawn(agentTask, spawnRecord, err, queuedTask !== undefined);
|
|
396
615
|
}
|
|
397
616
|
else {
|
|
398
617
|
childAbortController?.abort();
|
|
@@ -403,7 +622,7 @@ export class AgentManager {
|
|
|
403
622
|
throw err;
|
|
404
623
|
}
|
|
405
624
|
}
|
|
406
|
-
async rollbackUnstartedSpawn(agentTask, spawnRecord, reason) {
|
|
625
|
+
async rollbackUnstartedSpawn(agentTask, spawnRecord, reason, retainHandle = false) {
|
|
407
626
|
agentTask.childAbortController.abort();
|
|
408
627
|
agentTask.context.budget.settle(0);
|
|
409
628
|
await agentTask.context.budget.flush();
|
|
@@ -427,7 +646,22 @@ export class AgentManager {
|
|
|
427
646
|
}
|
|
428
647
|
}
|
|
429
648
|
this.clearEvictionTimer(agentTask.taskId);
|
|
430
|
-
|
|
649
|
+
if (retainHandle) {
|
|
650
|
+
agentTask.result ??= {
|
|
651
|
+
runId: agentTask.context.parentRunId,
|
|
652
|
+
status: 'failed',
|
|
653
|
+
usage: { ...EMPTY_TOKEN_USAGE },
|
|
654
|
+
cost: { ...ZERO_COST },
|
|
655
|
+
iterations: 0,
|
|
656
|
+
durationMs: Date.now() - agentTask.createdAt,
|
|
657
|
+
messages: [],
|
|
658
|
+
lastError: toErrorMessage(reason),
|
|
659
|
+
};
|
|
660
|
+
agentTask.completedAt = Date.now();
|
|
661
|
+
this.scheduleEviction(agentTask.taskId);
|
|
662
|
+
}
|
|
663
|
+
else
|
|
664
|
+
this.instances.delete(agentTask.taskId);
|
|
431
665
|
this.spawnRecords.delete(agentTask.taskId);
|
|
432
666
|
this.resolveCompletionCallbacks(agentTask.taskId);
|
|
433
667
|
await this.rollbackSpawnResources(spawnRecord);
|
|
@@ -448,14 +682,24 @@ export class AgentManager {
|
|
|
448
682
|
}
|
|
449
683
|
}
|
|
450
684
|
cancel(taskId, cause) {
|
|
685
|
+
if (this.cancelingTasks.has(taskId))
|
|
686
|
+
return;
|
|
451
687
|
const agentTask = this.instances.get(taskId);
|
|
452
688
|
if (!agentTask || isTerminalAgentTaskState(agentTask.state))
|
|
453
689
|
return;
|
|
454
690
|
// Was the bare string `'canceled'`, which `abortReasonText` suppresses
|
|
455
691
|
// by name — its docblock cites this exact call site — so the child's
|
|
456
692
|
// run saw a cancellation with no attributable origin at all.
|
|
457
|
-
|
|
458
|
-
this
|
|
693
|
+
// Abort listeners run synchronously. A pending task's parent observer
|
|
694
|
+
// must not reenter this method and replace an explicit user's cause.
|
|
695
|
+
this.cancelingTasks.add(taskId);
|
|
696
|
+
try {
|
|
697
|
+
agentTask.childAbortController.abort(cause ? new RunCancelled(cause) : undefined);
|
|
698
|
+
this.markCanceled(taskId, cause);
|
|
699
|
+
}
|
|
700
|
+
finally {
|
|
701
|
+
this.cancelingTasks.delete(taskId);
|
|
702
|
+
}
|
|
459
703
|
}
|
|
460
704
|
cancelAll(parentRunId, cause = 'parent') {
|
|
461
705
|
// `'parent'` by default, because this call site IS a parent
|
|
@@ -539,11 +783,20 @@ export class AgentManager {
|
|
|
539
783
|
if (isTerminalAgentTaskState(agentTask.state)) {
|
|
540
784
|
this.clearEvictionTimer(taskId);
|
|
541
785
|
this.instances.delete(taskId);
|
|
542
|
-
this.
|
|
786
|
+
if (!this.executingTasks.has(taskId))
|
|
787
|
+
this.spawnRecords.delete(taskId);
|
|
543
788
|
}
|
|
544
789
|
}
|
|
545
790
|
}
|
|
546
791
|
dispose() {
|
|
792
|
+
this.disposed = true;
|
|
793
|
+
if (this.admissionTimer)
|
|
794
|
+
clearTimeout(this.admissionTimer);
|
|
795
|
+
this.admissionTimer = undefined;
|
|
796
|
+
for (const queue of this.pendingSpawns.values())
|
|
797
|
+
for (const entry of queue)
|
|
798
|
+
entry.removeAbortListener();
|
|
799
|
+
this.pendingSpawns.clear();
|
|
547
800
|
for (const taskId of this.instances.keys()) {
|
|
548
801
|
this.clearEvictionTimer(taskId);
|
|
549
802
|
}
|
|
@@ -555,7 +808,9 @@ export class AgentManager {
|
|
|
555
808
|
this.cancel(taskId);
|
|
556
809
|
}
|
|
557
810
|
this.instances.clear();
|
|
558
|
-
this.spawnRecords.
|
|
811
|
+
for (const taskId of this.spawnRecords.keys())
|
|
812
|
+
if (!this.executingTasks.has(taskId))
|
|
813
|
+
this.spawnRecords.delete(taskId);
|
|
559
814
|
this.listeners.length = 0;
|
|
560
815
|
}
|
|
561
816
|
/**
|
|
@@ -591,7 +846,7 @@ export class AgentManager {
|
|
|
591
846
|
this.spawnLocks.delete(key);
|
|
592
847
|
}
|
|
593
848
|
}
|
|
594
|
-
async
|
|
849
|
+
async validateSpawn(options, context) {
|
|
595
850
|
// Phase 9: deps are unconditional required. Every spawn produces a
|
|
596
851
|
// SubSession + Session + WorkspaceRef triple (Convention #0: no
|
|
597
852
|
// partial/legacy path).
|
|
@@ -618,6 +873,8 @@ export class AgentManager {
|
|
|
618
873
|
if (!parentSession) {
|
|
619
874
|
throw new Error(`Parent session ${options.parentSessionId} not found for tenant ${context.tenantId} — spawn rejected`);
|
|
620
875
|
}
|
|
876
|
+
if (parentSession.status === 'archived')
|
|
877
|
+
throw new Error('Delegation parent session is archived');
|
|
621
878
|
if (parentSession.topicId !== context.topicId) {
|
|
622
879
|
throw new Error(`Topic mismatch on spawn: parent session ${parentSession.id} is on topic ${parentSession.topicId}, but context.topicId=${context.topicId}. Cross-topic spawn is forbidden (session-hierarchy.md §6.3).`);
|
|
623
880
|
}
|
|
@@ -633,6 +890,11 @@ export class AgentManager {
|
|
|
633
890
|
// chain; width counts existing direct children of the parent.
|
|
634
891
|
await this.deps.capacity.validateDepth(options.parentSessionId, project.config.maxDelegationDepth, context.tenantId);
|
|
635
892
|
await this.deps.capacity.validateWidth(options.parentSessionId, 1, project.config.maxDelegationWidth, context.tenantId);
|
|
893
|
+
}
|
|
894
|
+
async provisionSpawnUnlocked(options, context) {
|
|
895
|
+
await this.validateSpawn(options, context);
|
|
896
|
+
context.parentAbortController.signal.throwIfAborted();
|
|
897
|
+
const store = this.deps.sessionStore;
|
|
636
898
|
// Ancestry walk gives both the child depth and the root session id
|
|
637
899
|
// attached to every sub-session event from here down.
|
|
638
900
|
const parentAncestry = await store.getAncestry(options.parentSessionId, context.tenantId);
|
|
@@ -995,13 +1257,16 @@ export class AgentManager {
|
|
|
995
1257
|
return agentTask;
|
|
996
1258
|
}
|
|
997
1259
|
scheduleEviction(taskId) {
|
|
1260
|
+
if (this.disposed)
|
|
1261
|
+
return;
|
|
998
1262
|
const agentTask = this.instances.get(taskId);
|
|
999
1263
|
if (!agentTask)
|
|
1000
1264
|
return;
|
|
1001
1265
|
agentTask.evictAfter = Date.now() + this.config.evictionMs;
|
|
1002
1266
|
const timer = setTimeout(() => {
|
|
1003
1267
|
this.instances.delete(taskId);
|
|
1004
|
-
this.
|
|
1268
|
+
if (!this.executingTasks.has(taskId))
|
|
1269
|
+
this.spawnRecords.delete(taskId);
|
|
1005
1270
|
this.evictionTimers.delete(taskId);
|
|
1006
1271
|
this.log.info('Agent task evicted', { 'namzu.agent.task_id': taskId });
|
|
1007
1272
|
}, this.config.evictionMs);
|
|
@@ -1038,15 +1303,19 @@ export class AgentManager {
|
|
|
1038
1303
|
emitRunEvent(agentTask, event) {
|
|
1039
1304
|
if (!agentTask.runEventListener)
|
|
1040
1305
|
return;
|
|
1041
|
-
|
|
1042
|
-
agentTask.runEventListener(event);
|
|
1043
|
-
}
|
|
1044
|
-
catch (err) {
|
|
1306
|
+
const reportFailure = (error) => {
|
|
1045
1307
|
this.log.error('RunEvent emission error', {
|
|
1046
1308
|
'namzu.event.type': event.type,
|
|
1047
|
-
'
|
|
1048
|
-
'exception.message': toErrorMessage(err),
|
|
1309
|
+
'exception.message': toErrorMessage(error),
|
|
1049
1310
|
});
|
|
1311
|
+
};
|
|
1312
|
+
try {
|
|
1313
|
+
// Terminal observation must not delay completion or leak a rejected
|
|
1314
|
+
// listener promise into the host as an unhandled rejection.
|
|
1315
|
+
void Promise.resolve(agentTask.runEventListener(event)).catch(reportFailure);
|
|
1316
|
+
}
|
|
1317
|
+
catch (error) {
|
|
1318
|
+
reportFailure(error);
|
|
1050
1319
|
}
|
|
1051
1320
|
}
|
|
1052
1321
|
}
|