@caupulican/pi-adaptative 0.85.8 → 0.86.2
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 +42 -0
- package/dist/core/agent-paths.d.ts +6 -3
- package/dist/core/agent-paths.d.ts.map +1 -1
- package/dist/core/agent-paths.js +10 -3
- package/dist/core/agent-paths.js.map +1 -1
- package/dist/core/agent-session.d.ts +5 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +7 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
- package/dist/core/autonomy/bounded-completion.js +19 -8
- package/dist/core/autonomy/bounded-completion.js.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.d.ts +11 -5
- package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.js +34 -8
- package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
- package/dist/core/autonomy/subagent-prompt.d.ts +3 -3
- package/dist/core/autonomy/subagent-prompt.js +9 -9
- package/dist/core/autonomy/subagent-prompt.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +10 -8
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +23 -13
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/bash-execution-controller.d.ts +4 -0
- package/dist/core/bash-execution-controller.d.ts.map +1 -1
- package/dist/core/bash-execution-controller.js +11 -4
- package/dist/core/bash-execution-controller.js.map +1 -1
- package/dist/core/bash-executor.d.ts +2 -0
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +2 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/capability-contract.d.ts +1 -1
- package/dist/core/capability-contract.d.ts.map +1 -1
- package/dist/core/capability-contract.js +0 -1
- package/dist/core/capability-contract.js.map +1 -1
- package/dist/core/default-tool-surface.d.ts +1 -0
- package/dist/core/default-tool-surface.d.ts.map +1 -1
- package/dist/core/default-tool-surface.js +3 -2
- package/dist/core/default-tool-surface.js.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts +27 -8
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.js +191 -33
- package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-agent-control.d.ts +45 -6
- package/dist/core/delegation/worker-agent-control.d.ts.map +1 -1
- package/dist/core/delegation/worker-agent-control.js +110 -13
- package/dist/core/delegation/worker-agent-control.js.map +1 -1
- package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -1
- package/dist/core/delegation/worker-attempt-executor.js +177 -158
- package/dist/core/delegation/worker-attempt-executor.js.map +1 -1
- package/dist/core/delegation/worker-authority-resolver.d.ts +23 -0
- package/dist/core/delegation/worker-authority-resolver.d.ts.map +1 -0
- package/dist/core/delegation/worker-authority-resolver.js +128 -0
- package/dist/core/delegation/worker-authority-resolver.js.map +1 -0
- package/dist/core/delegation/worker-conversation-store.d.ts.map +1 -1
- package/dist/core/delegation/worker-conversation-store.js +1 -1
- package/dist/core/delegation/worker-conversation-store.js.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.d.ts +7 -1
- package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.js +260 -87
- package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
- package/dist/core/delegation/worker-delegation-request.d.ts +25 -4
- package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-request.js +90 -1
- package/dist/core/delegation/worker-delegation-request.js.map +1 -1
- package/dist/core/delegation/worker-execution-policy.d.ts +2 -0
- package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -1
- package/dist/core/delegation/worker-execution-policy.js +22 -12
- package/dist/core/delegation/worker-execution-policy.js.map +1 -1
- package/dist/core/delegation/worker-lifecycle.d.ts +1 -0
- package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -1
- package/dist/core/delegation/worker-lifecycle.js +4 -2
- package/dist/core/delegation/worker-lifecycle.js.map +1 -1
- package/dist/core/delegation/worker-profile-resolver.d.ts +0 -2
- package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -1
- package/dist/core/delegation/worker-profile-resolver.js +8 -35
- package/dist/core/delegation/worker-profile-resolver.js.map +1 -1
- package/dist/core/delegation/worker-recovery-coordinator.d.ts.map +1 -1
- package/dist/core/delegation/worker-recovery-coordinator.js +1 -0
- package/dist/core/delegation/worker-recovery-coordinator.js.map +1 -1
- package/dist/core/delegation/worker-runner.d.ts +6 -1
- package/dist/core/delegation/worker-runner.d.ts.map +1 -1
- package/dist/core/delegation/worker-runner.js +20 -6
- package/dist/core/delegation/worker-runner.js.map +1 -1
- package/dist/core/delegation/worker-tree-budget-coordinator.d.ts +47 -0
- package/dist/core/delegation/worker-tree-budget-coordinator.d.ts.map +1 -0
- package/dist/core/delegation/worker-tree-budget-coordinator.js +210 -0
- package/dist/core/delegation/worker-tree-budget-coordinator.js.map +1 -0
- package/dist/core/memory/providers/file-store.d.ts +2 -0
- package/dist/core/memory/providers/file-store.d.ts.map +1 -1
- package/dist/core/memory/providers/file-store.js +22 -20
- package/dist/core/memory/providers/file-store.js.map +1 -1
- package/dist/core/models/runtime-process.d.ts.map +1 -1
- package/dist/core/models/runtime-process.js +5 -18
- package/dist/core/models/runtime-process.js.map +1 -1
- package/dist/core/orchestration/bounded-string-array.d.ts +11 -0
- package/dist/core/orchestration/bounded-string-array.d.ts.map +1 -0
- package/dist/core/orchestration/bounded-string-array.js +17 -0
- package/dist/core/orchestration/bounded-string-array.js.map +1 -0
- package/dist/core/orchestration/capability-gateway.d.ts +16 -0
- package/dist/core/orchestration/capability-gateway.d.ts.map +1 -1
- package/dist/core/orchestration/capability-gateway.js +38 -0
- package/dist/core/orchestration/capability-gateway.js.map +1 -1
- package/dist/core/orchestration/contracts.d.ts +11 -3
- package/dist/core/orchestration/contracts.d.ts.map +1 -1
- package/dist/core/orchestration/contracts.js +0 -1
- package/dist/core/orchestration/contracts.js.map +1 -1
- package/dist/core/orchestration/delegation-ledger.d.ts +1 -0
- package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -1
- package/dist/core/orchestration/delegation-ledger.js +3 -0
- package/dist/core/orchestration/delegation-ledger.js.map +1 -1
- package/dist/core/orchestration/event-store.d.ts +12 -10
- package/dist/core/orchestration/event-store.d.ts.map +1 -1
- package/dist/core/orchestration/event-store.js +94 -104
- package/dist/core/orchestration/event-store.js.map +1 -1
- package/dist/core/orchestration/lane-tool-manifests.d.ts +2 -2
- package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -1
- package/dist/core/orchestration/lane-tool-manifests.js +4 -1
- package/dist/core/orchestration/lane-tool-manifests.js.map +1 -1
- package/dist/core/orchestration/policy-compiler.d.ts.map +1 -1
- package/dist/core/orchestration/policy-compiler.js +8 -9
- package/dist/core/orchestration/policy-compiler.js.map +1 -1
- package/dist/core/orchestration/profile-registry.d.ts.map +1 -1
- package/dist/core/orchestration/profile-registry.js +4 -10
- package/dist/core/orchestration/profile-registry.js.map +1 -1
- package/dist/core/orchestration/task-runtime.d.ts +1 -0
- package/dist/core/orchestration/task-runtime.d.ts.map +1 -1
- package/dist/core/orchestration/task-runtime.js +58 -3
- package/dist/core/orchestration/task-runtime.js.map +1 -1
- package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -1
- package/dist/core/orchestration/worker-execution-contract.js +10 -17
- package/dist/core/orchestration/worker-execution-contract.js.map +1 -1
- package/dist/core/risk-classifier.js +3 -3
- package/dist/core/risk-classifier.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +4 -1
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +34 -15
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/secrets/bitwarden-credential-storage.d.ts +51 -0
- package/dist/core/secrets/bitwarden-credential-storage.d.ts.map +1 -0
- package/dist/core/secrets/bitwarden-credential-storage.js +345 -0
- package/dist/core/secrets/bitwarden-credential-storage.js.map +1 -0
- package/dist/core/secrets/credential-exposure-guard.d.ts +8 -4
- package/dist/core/secrets/credential-exposure-guard.d.ts.map +1 -1
- package/dist/core/secrets/credential-exposure-guard.js +30 -31
- package/dist/core/secrets/credential-exposure-guard.js.map +1 -1
- package/dist/core/secrets/credential-manager.d.ts +109 -0
- package/dist/core/secrets/credential-manager.d.ts.map +1 -0
- package/dist/core/secrets/credential-manager.js +384 -0
- package/dist/core/secrets/credential-manager.js.map +1 -0
- package/dist/core/secrets/credential-project.d.ts +4 -0
- package/dist/core/secrets/credential-project.d.ts.map +1 -0
- package/dist/core/secrets/credential-project.js +145 -0
- package/dist/core/secrets/credential-project.js.map +1 -0
- package/dist/core/secrets/secret-dotenv.d.ts +1 -1
- package/dist/core/secrets/secret-dotenv.js +1 -1
- package/dist/core/secrets/secret-dotenv.js.map +1 -1
- package/dist/core/settings-manager.d.ts +4 -2
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +9 -5
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tool-capability-policy.js +2 -2
- package/dist/core/tool-capability-policy.js.map +1 -1
- package/dist/core/tools/delegate.d.ts +29 -1
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +179 -28
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/git-filter.d.ts +1 -0
- package/dist/core/tools/git-filter.d.ts.map +1 -1
- package/dist/core/tools/git-filter.js +1 -1
- package/dist/core/tools/git-filter.js.map +1 -1
- package/dist/core/tools/profile-writer.js +3 -3
- package/dist/core/tools/profile-writer.js.map +1 -1
- package/dist/core/tools/python.d.ts +2 -0
- package/dist/core/tools/python.d.ts.map +1 -1
- package/dist/core/tools/python.js +17 -12
- package/dist/core/tools/python.js.map +1 -1
- package/dist/core/tools/run-process.d.ts +2 -0
- package/dist/core/tools/run-process.d.ts.map +1 -1
- package/dist/core/tools/run-process.js +7 -3
- package/dist/core/tools/run-process.js.map +1 -1
- package/dist/core/tools/secret-store.d.ts +8 -18
- package/dist/core/tools/secret-store.d.ts.map +1 -1
- package/dist/core/tools/secret-store.js +83 -348
- package/dist/core/tools/secret-store.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +38 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +35 -14
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +26 -3
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/secret-menu-controller.d.ts +21 -0
- package/dist/modes/interactive/secret-menu-controller.d.ts.map +1 -0
- package/dist/modes/interactive/secret-menu-controller.js +276 -0
- package/dist/modes/interactive/secret-menu-controller.js.map +1 -0
- package/dist/utils/tools-manager.d.ts +2 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +43 -48
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/zip-extractor.d.ts +8 -0
- package/dist/utils/zip-extractor.d.ts.map +1 -0
- package/dist/utils/zip-extractor.js +275 -0
- package/dist/utils/zip-extractor.js.map +1 -0
- package/docs/harness-architecture.md +34 -22
- package/docs/index.md +1 -1
- package/docs/resources.md +1 -1
- package/docs/settings.md +39 -103
- package/docs/usage.md +7 -5
- package/docs/worker-profiles.md +9 -7
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
- package/dist/core/secrets/secret-vault-format.d.ts +0 -112
- package/dist/core/secrets/secret-vault-format.d.ts.map +0 -1
- package/dist/core/secrets/secret-vault-format.js +0 -396
- package/dist/core/secrets/secret-vault-format.js.map +0 -1
- package/dist/core/secrets/secret-vault.d.ts +0 -72
- package/dist/core/secrets/secret-vault.d.ts.map +0 -1
- package/dist/core/secrets/secret-vault.js +0 -663
- package/dist/core/secrets/secret-vault.js.map +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { WorkerAgentMailbox } from "./worker-agent-control.js";
|
|
1
|
+
import { WorkerAgentMailbox, } from "./worker-agent-control.js";
|
|
2
|
+
import { WorkerConversationStore } from "./worker-conversation-store.js";
|
|
2
3
|
/**
|
|
3
4
|
* Sole owner of model-facing logical-agent controls and their durable inboxes.
|
|
4
5
|
*
|
|
@@ -9,34 +10,70 @@ export class WorkerAgentControlCoordinator {
|
|
|
9
10
|
constructor(options) {
|
|
10
11
|
this.mailboxes = new Map();
|
|
11
12
|
this.stateListeners = new Set();
|
|
13
|
+
this.conversations = new WorkerConversationStore();
|
|
12
14
|
this.options = options;
|
|
13
15
|
}
|
|
14
16
|
getProcessOwnerId() {
|
|
15
17
|
return this.options.processOwnerId;
|
|
16
18
|
}
|
|
17
|
-
|
|
19
|
+
listWorkerAgents(scope = {}) {
|
|
18
20
|
this.requireControl();
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
+
const agents = Object.values(this.options.getLifecycle().getTaskRuntimeSnapshot().agents);
|
|
22
|
+
const caller = scope.callerAgentId ? this.requireKnownAgent(scope.callerAgentId) : undefined;
|
|
23
|
+
return agents
|
|
24
|
+
.filter((agent) => !caller || agent.rootAgentId === caller.rootAgentId)
|
|
25
|
+
.sort((left, right) => left.depth - right.depth || left.createdAt.localeCompare(right.createdAt));
|
|
26
|
+
}
|
|
27
|
+
readWorkerAgentTranscript(agentId, options = {}) {
|
|
28
|
+
this.requireControl();
|
|
29
|
+
const agent = this.requireVisibleAgent(agentId, options);
|
|
30
|
+
const cursor = options.cursor ?? 0;
|
|
31
|
+
const maxMessages = options.maxMessages ?? 16;
|
|
32
|
+
if (!Number.isSafeInteger(cursor) || cursor < 0)
|
|
33
|
+
throw new TypeError("Worker transcript cursor is invalid.");
|
|
34
|
+
if (!Number.isSafeInteger(maxMessages) || maxMessages < 1 || maxMessages > 64) {
|
|
35
|
+
throw new TypeError("Worker transcript page size must be from 1 through 64 messages.");
|
|
36
|
+
}
|
|
37
|
+
const transcript = this.conversations
|
|
38
|
+
.open({
|
|
39
|
+
agentDir: this.options.agentDir,
|
|
40
|
+
resumeContext: agent.resumeContext,
|
|
41
|
+
expectedLogicalAgentId: agent.agentId,
|
|
42
|
+
})
|
|
43
|
+
.getRawTranscript();
|
|
44
|
+
if (cursor > transcript.length)
|
|
45
|
+
throw new TypeError("Worker transcript cursor exceeds the transcript length.");
|
|
46
|
+
const messages = transcript.slice(cursor, cursor + maxMessages);
|
|
47
|
+
const nextCursor = cursor + messages.length;
|
|
48
|
+
return {
|
|
49
|
+
agentId: agent.agentId,
|
|
50
|
+
cursor,
|
|
51
|
+
totalMessages: transcript.length,
|
|
52
|
+
messages,
|
|
53
|
+
...(nextCursor < transcript.length ? { nextCursor } : {}),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
sendWorkerAgentMessage(agentId, message, options = {}) {
|
|
57
|
+
this.requireControl();
|
|
58
|
+
const agent = this.requireVisibleAgent(agentId, { callerAgentId: options.senderAgentId });
|
|
59
|
+
const queued = this.enqueuePeerMessage(agent, "follow_up", message, options);
|
|
21
60
|
this.signalStateChanged();
|
|
22
61
|
return { messageId: queued.messageId, queued: true };
|
|
23
62
|
}
|
|
24
|
-
followUpWorkerAgent(agentId, message) {
|
|
63
|
+
followUpWorkerAgent(agentId, message, options = {}) {
|
|
25
64
|
this.requireControl();
|
|
26
|
-
const agent = this.
|
|
65
|
+
const agent = this.requireVisibleAgent(agentId, { callerAgentId: options.senderAgentId });
|
|
27
66
|
const canonicalAgentId = agent.agentId;
|
|
28
|
-
const active = agent
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (active?.status === "running" || active?.status === "leased") {
|
|
32
|
-
const queued = this.getMailbox(canonicalAgentId).enqueue({ kind: "steer", content: message });
|
|
67
|
+
const active = this.latestAgentAttempt(agent);
|
|
68
|
+
if (active?.status === "queued" || active?.status === "running" || active?.status === "leased") {
|
|
69
|
+
const queued = this.enqueuePeerMessage(agent, "steer", message, options);
|
|
33
70
|
this.signalStateChanged();
|
|
34
71
|
return { started: false, steering: true, messageId: queued.messageId };
|
|
35
72
|
}
|
|
36
73
|
if (agent.status !== "registered") {
|
|
37
74
|
return { started: false, steering: false, messageId: "", skipReason: `agent_${agent.status}` };
|
|
38
75
|
}
|
|
39
|
-
const queued = this.
|
|
76
|
+
const queued = this.enqueuePeerMessage(agent, "follow_up", message, options);
|
|
40
77
|
try {
|
|
41
78
|
const prepared = this.options
|
|
42
79
|
.getLifecycle()
|
|
@@ -56,8 +93,8 @@ export class WorkerAgentControlCoordinator {
|
|
|
56
93
|
};
|
|
57
94
|
}
|
|
58
95
|
}
|
|
59
|
-
interruptWorkerAgent(agentId) {
|
|
60
|
-
const { agent, attempt } = this.controlledAgentAttempt(agentId);
|
|
96
|
+
interruptWorkerAgent(agentId, scope = {}) {
|
|
97
|
+
const { agent, attempt } = this.controlledAgentAttempt(agentId, scope);
|
|
61
98
|
if (!attempt || (attempt.status !== "running" && attempt.status !== "leased")) {
|
|
62
99
|
return { interrupted: false, reason: "agent_not_running" };
|
|
63
100
|
}
|
|
@@ -71,8 +108,8 @@ export class WorkerAgentControlCoordinator {
|
|
|
71
108
|
return { interrupted: false, reason: error instanceof Error ? error.message : String(error) };
|
|
72
109
|
}
|
|
73
110
|
}
|
|
74
|
-
resumeWorkerAgent(agentId) {
|
|
75
|
-
const { attempt } = this.controlledAgentAttempt(agentId);
|
|
111
|
+
resumeWorkerAgent(agentId, scope = {}) {
|
|
112
|
+
const { attempt } = this.controlledAgentAttempt(agentId, scope);
|
|
76
113
|
if (!attempt || attempt.status !== "suspended")
|
|
77
114
|
return { started: false, skipReason: "agent_not_suspended" };
|
|
78
115
|
const record = this.options.getLifecycle().getRecord(attempt.taskId);
|
|
@@ -83,8 +120,8 @@ export class WorkerAgentControlCoordinator {
|
|
|
83
120
|
this.signalStateChanged();
|
|
84
121
|
return { started: true, record };
|
|
85
122
|
}
|
|
86
|
-
cancelWorkerAgent(agentId, reasonCode = "agent_cancelled") {
|
|
87
|
-
const { attempt } = this.controlledAgentAttempt(agentId);
|
|
123
|
+
cancelWorkerAgent(agentId, reasonCode = "agent_cancelled", scope = {}) {
|
|
124
|
+
const { attempt } = this.controlledAgentAttempt(agentId, scope);
|
|
88
125
|
if (!attempt)
|
|
89
126
|
return undefined;
|
|
90
127
|
this.options.abortLane(attempt.taskId, reasonCode);
|
|
@@ -93,9 +130,14 @@ export class WorkerAgentControlCoordinator {
|
|
|
93
130
|
return record;
|
|
94
131
|
}
|
|
95
132
|
/** Event-driven wait: durable projection plus state/mailbox notifications, never output polling. */
|
|
96
|
-
waitForWorkerAgent(agentId, timeoutMs = 30_000) {
|
|
133
|
+
waitForWorkerAgent(agentId, timeoutMs = 30_000, scope = {}) {
|
|
97
134
|
this.requireControl();
|
|
98
135
|
const canonicalAgentId = agentId.trim();
|
|
136
|
+
if (!canonicalAgentId)
|
|
137
|
+
throw new Error("Logical worker agent id is required.");
|
|
138
|
+
const target = this.options.getLifecycle().getAgent(canonicalAgentId);
|
|
139
|
+
if (target)
|
|
140
|
+
this.requireVisibleAgent(canonicalAgentId, scope);
|
|
99
141
|
const boundedTimeoutMs = Number.isFinite(timeoutMs)
|
|
100
142
|
? Math.max(1, Math.min(Math.floor(timeoutMs), 300_000))
|
|
101
143
|
: 30_000;
|
|
@@ -103,10 +145,12 @@ export class WorkerAgentControlCoordinator {
|
|
|
103
145
|
const agent = this.options.getLifecycle().getAgent(canonicalAgentId);
|
|
104
146
|
if (!agent)
|
|
105
147
|
return "unknown";
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (agent.status === "suspended")
|
|
148
|
+
const attempt = this.latestAgentAttempt(agent);
|
|
149
|
+
if (attempt?.status === "suspended" || agent.status === "suspended")
|
|
109
150
|
return "suspended";
|
|
151
|
+
if (attempt?.status === "queued" || attempt?.status === "leased" || attempt?.status === "running") {
|
|
152
|
+
return "active";
|
|
153
|
+
}
|
|
110
154
|
return "idle";
|
|
111
155
|
};
|
|
112
156
|
const immediate = currentStatus();
|
|
@@ -114,6 +158,10 @@ export class WorkerAgentControlCoordinator {
|
|
|
114
158
|
return Promise.resolve({ status: immediate });
|
|
115
159
|
return new Promise((resolve) => {
|
|
116
160
|
let settled = false;
|
|
161
|
+
let releaseYield = () => undefined;
|
|
162
|
+
let unsubscribeMailbox = () => undefined;
|
|
163
|
+
let unsubscribeState = () => undefined;
|
|
164
|
+
let timeout;
|
|
117
165
|
const settle = () => {
|
|
118
166
|
if (settled)
|
|
119
167
|
return;
|
|
@@ -123,21 +171,32 @@ export class WorkerAgentControlCoordinator {
|
|
|
123
171
|
settled = true;
|
|
124
172
|
unsubscribeMailbox();
|
|
125
173
|
unsubscribeState();
|
|
126
|
-
|
|
174
|
+
if (timeout)
|
|
175
|
+
clearTimeout(timeout);
|
|
176
|
+
releaseYield();
|
|
127
177
|
resolve({ status: next });
|
|
128
178
|
};
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
179
|
+
unsubscribeMailbox = this.getMailbox(canonicalAgentId).subscribe(settle);
|
|
180
|
+
unsubscribeState = this.subscribeStateChanges(settle);
|
|
181
|
+
timeout = setTimeout(() => {
|
|
132
182
|
if (settled)
|
|
133
183
|
return;
|
|
134
184
|
settled = true;
|
|
135
185
|
unsubscribeMailbox();
|
|
136
186
|
unsubscribeState();
|
|
187
|
+
releaseYield();
|
|
137
188
|
resolve({ status: currentStatus() });
|
|
138
189
|
}, boundedTimeoutMs);
|
|
139
190
|
if (typeof timeout === "object" && "unref" in timeout)
|
|
140
191
|
timeout.unref();
|
|
192
|
+
if (scope.callerAgentId && this.options.yieldCapacity) {
|
|
193
|
+
const yielded = this.options.yieldCapacity(scope.callerAgentId, canonicalAgentId);
|
|
194
|
+
if (settled)
|
|
195
|
+
yielded();
|
|
196
|
+
else
|
|
197
|
+
releaseYield = yielded;
|
|
198
|
+
}
|
|
199
|
+
settle();
|
|
141
200
|
});
|
|
142
201
|
}
|
|
143
202
|
/** Read mailbox items at a safe boundary and reconcile the narrow append-before-ack crash window. */
|
|
@@ -158,7 +217,7 @@ export class WorkerAgentControlCoordinator {
|
|
|
158
217
|
acknowledgeMailboxMessage(agentId, message) {
|
|
159
218
|
if (message.role !== "user" || typeof message.content !== "string")
|
|
160
219
|
return;
|
|
161
|
-
const messageId = /^\[Worker control (worker-message-[^\]]+)
|
|
220
|
+
const messageId = /^\[Worker control (worker-message-[^\]\s]+)(?: [^\]]+)?\]\n/.exec(message.content)?.[1];
|
|
162
221
|
if (messageId)
|
|
163
222
|
this.getMailbox(agentId).acknowledgeDelivered(messageId);
|
|
164
223
|
}
|
|
@@ -167,6 +226,39 @@ export class WorkerAgentControlCoordinator {
|
|
|
167
226
|
for (const listener of this.stateListeners)
|
|
168
227
|
listener();
|
|
169
228
|
}
|
|
229
|
+
/** Route a terminal child edge to its owning parent without injecting into an active model turn. */
|
|
230
|
+
deliverWorkerTerminalHandoff(args) {
|
|
231
|
+
const parent = this.requireKnownAgent(args.parentAgentId);
|
|
232
|
+
const latest = this.latestAgentAttempt(parent);
|
|
233
|
+
const active = latest?.status === "queued" || latest?.status === "leased" || latest?.status === "running";
|
|
234
|
+
const content = [
|
|
235
|
+
"Worker terminal handoff",
|
|
236
|
+
`childAgentId=${args.childAgentId}`,
|
|
237
|
+
`laneId=${args.record.laneId}`,
|
|
238
|
+
`status=${args.record.status}`,
|
|
239
|
+
...(args.record.reasonCode ? [`reasonCode=${args.record.reasonCode}`] : []),
|
|
240
|
+
`Read the exact child evidence with delegate action="transcript" agentId="${args.childAgentId}".`,
|
|
241
|
+
].join("\n");
|
|
242
|
+
const queued = this.getMailbox(parent.agentId).enqueue({
|
|
243
|
+
kind: active ? "steer" : "follow_up",
|
|
244
|
+
content,
|
|
245
|
+
senderAgentId: args.childAgentId,
|
|
246
|
+
idempotencyKey: `terminal-handoff:${args.terminalAttemptId}`,
|
|
247
|
+
});
|
|
248
|
+
let started = false;
|
|
249
|
+
if (!active && parent.status === "registered") {
|
|
250
|
+
const prepared = this.options.getLifecycle().prepareAgentTurn({
|
|
251
|
+
agentId: parent.agentId,
|
|
252
|
+
instructions: content,
|
|
253
|
+
});
|
|
254
|
+
this.options.scheduler.enqueue(prepared.record, this.options.recoveredRequest(prepared.attempt));
|
|
255
|
+
this.options.statusChanged();
|
|
256
|
+
this.options.scheduler.drain();
|
|
257
|
+
started = true;
|
|
258
|
+
}
|
|
259
|
+
this.signalStateChanged();
|
|
260
|
+
return { messageId: queued.messageId, started };
|
|
261
|
+
}
|
|
170
262
|
requireControl() {
|
|
171
263
|
if (!this.options.isControlAvailable()) {
|
|
172
264
|
throw new Error("Worker delegation control is unavailable in this UAC surface.");
|
|
@@ -181,12 +273,42 @@ export class WorkerAgentControlCoordinator {
|
|
|
181
273
|
throw new Error(`Unknown logical worker agent '${normalized}'.`);
|
|
182
274
|
return agent;
|
|
183
275
|
}
|
|
184
|
-
|
|
276
|
+
requireVisibleAgent(agentId, scope) {
|
|
277
|
+
const target = this.requireKnownAgent(agentId);
|
|
278
|
+
if (!scope.callerAgentId)
|
|
279
|
+
return target;
|
|
280
|
+
const caller = this.requireKnownAgent(scope.callerAgentId);
|
|
281
|
+
if (caller.rootAgentId !== target.rootAgentId) {
|
|
282
|
+
throw new Error(`Logical worker agent '${target.agentId}' is outside the caller's agent tree.`);
|
|
283
|
+
}
|
|
284
|
+
return target;
|
|
285
|
+
}
|
|
286
|
+
requireControllableAgent(agentId, scope) {
|
|
287
|
+
const target = this.requireVisibleAgent(agentId, scope);
|
|
288
|
+
if (!scope.callerAgentId)
|
|
289
|
+
return target;
|
|
290
|
+
const caller = this.requireKnownAgent(scope.callerAgentId);
|
|
291
|
+
let cursor = target;
|
|
292
|
+
const visited = new Set();
|
|
293
|
+
while (cursor && !visited.has(cursor.agentId)) {
|
|
294
|
+
if (cursor.agentId === caller.agentId)
|
|
295
|
+
return target;
|
|
296
|
+
visited.add(cursor.agentId);
|
|
297
|
+
cursor = cursor.parentAgentId ? this.options.getLifecycle().getAgent(cursor.parentAgentId) : undefined;
|
|
298
|
+
}
|
|
299
|
+
throw new Error(`Logical worker agent '${target.agentId}' is outside its control subtree.`);
|
|
300
|
+
}
|
|
301
|
+
latestAgentAttempt(agent) {
|
|
302
|
+
const lifecycle = this.options.getLifecycle();
|
|
303
|
+
const latest = lifecycle.getLatestAgentAttempt?.(agent.agentId);
|
|
304
|
+
if (latest)
|
|
305
|
+
return latest;
|
|
306
|
+
return agent.activeAttemptId ? lifecycle.getTaskRuntimeSnapshot().attempts[agent.activeAttemptId] : undefined;
|
|
307
|
+
}
|
|
308
|
+
controlledAgentAttempt(agentId, scope) {
|
|
185
309
|
this.requireControl();
|
|
186
|
-
const agent = this.
|
|
187
|
-
const attempt = agent
|
|
188
|
-
? this.options.getLifecycle().getTaskRuntimeSnapshot().attempts[agent.activeAttemptId]
|
|
189
|
-
: undefined;
|
|
310
|
+
const agent = this.requireControllableAgent(agentId, scope);
|
|
311
|
+
const attempt = this.latestAgentAttempt(agent);
|
|
190
312
|
return { agent, attempt };
|
|
191
313
|
}
|
|
192
314
|
getMailbox(agentId) {
|
|
@@ -205,10 +327,46 @@ export class WorkerAgentControlCoordinator {
|
|
|
205
327
|
this.stateListeners.add(listener);
|
|
206
328
|
return () => this.stateListeners.delete(listener);
|
|
207
329
|
}
|
|
330
|
+
enqueuePeerMessage(target, kind, content, options) {
|
|
331
|
+
if (!options.replyToMessageId) {
|
|
332
|
+
return this.getMailbox(target.agentId).enqueue({ kind, content, ...options });
|
|
333
|
+
}
|
|
334
|
+
if (!options.senderAgentId)
|
|
335
|
+
throw new Error("A worker reply requires its sender agent identity.");
|
|
336
|
+
const sender = this.requireKnownAgent(options.senderAgentId);
|
|
337
|
+
if (sender.rootAgentId !== target.rootAgentId)
|
|
338
|
+
throw new Error("A worker reply target is outside its agent tree.");
|
|
339
|
+
const senderMailbox = this.getMailbox(sender.agentId);
|
|
340
|
+
const request = senderMailbox.getMessage(options.replyToMessageId);
|
|
341
|
+
if (!request || request.expectReply !== true || request.deliveredAt === undefined) {
|
|
342
|
+
throw new Error("Worker reply does not reference a delivered reply-expected message.");
|
|
343
|
+
}
|
|
344
|
+
if (request.senderAgentId !== target.agentId) {
|
|
345
|
+
throw new Error("Worker reply target does not match the original requester.");
|
|
346
|
+
}
|
|
347
|
+
if (request.threadId && options.threadId && request.threadId !== options.threadId) {
|
|
348
|
+
throw new Error("Worker reply thread conflicts with the original request.");
|
|
349
|
+
}
|
|
350
|
+
const queued = this.getMailbox(target.agentId).enqueue({
|
|
351
|
+
kind,
|
|
352
|
+
content,
|
|
353
|
+
...options,
|
|
354
|
+
...(request.threadId && !options.threadId ? { threadId: request.threadId } : {}),
|
|
355
|
+
idempotencyKey: `peer-reply:${sender.agentId}:${request.messageId}`,
|
|
356
|
+
});
|
|
357
|
+
senderMailbox.markReplied(request.messageId);
|
|
358
|
+
return queued;
|
|
359
|
+
}
|
|
208
360
|
mailboxMessage(message) {
|
|
361
|
+
const metadata = [
|
|
362
|
+
message.senderAgentId ? `from=${message.senderAgentId}` : undefined,
|
|
363
|
+
message.threadId ? `thread=${message.threadId}` : undefined,
|
|
364
|
+
message.replyToMessageId ? `replyTo=${message.replyToMessageId}` : undefined,
|
|
365
|
+
message.expectReply ? "replyExpected=true" : undefined,
|
|
366
|
+
].filter((value) => value !== undefined);
|
|
209
367
|
return {
|
|
210
368
|
role: "user",
|
|
211
|
-
content: `[Worker control ${message.messageId}]\n${message.content}`,
|
|
369
|
+
content: `[Worker control ${message.messageId}${metadata.length > 0 ? ` ${metadata.join(" ")}` : ""}]\n${message.content}`,
|
|
212
370
|
timestamp: Date.now(),
|
|
213
371
|
};
|
|
214
372
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-agent-control-coordinator.js","sourceRoot":"","sources":["../../../src/core/delegation/worker-agent-control-coordinator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@caupulican/pi-agent-core\";\nimport type { WorkerDelegationRunOutcome } from \"../agent-session-contracts.ts\";\nimport type { LaneRecord } from \"../autonomy/lane-tracker.ts\";\nimport type { AgentBindingContract } from \"../orchestration/contracts.ts\";\nimport type { AttemptRuntimeState } from \"../orchestration/task-runtime.ts\";\nimport { type WorkerAgentControlPort, WorkerAgentMailbox, type WorkerAgentMessage } from \"./worker-agent-control.ts\";\nimport type { WorkerConversation } from \"./worker-conversation-store.ts\";\nimport type { WorkerDelegationRequest } from \"./worker-delegation-request.ts\";\nimport type { WorkerDispatchScheduler } from \"./worker-dispatch-scheduler.ts\";\nimport type { WorkerLifecycle } from \"./worker-lifecycle.ts\";\n\nexport interface WorkerAgentControlCoordinatorOptions {\n\tagentDir: string;\n\tparentSessionId: string;\n\tprocessOwnerId: string;\n\tisControlAvailable(): boolean;\n\tgetLifecycle(): WorkerLifecycle;\n\trecoveredRequest(attempt: AttemptRuntimeState): WorkerDelegationRequest;\n\trun(request: WorkerDelegationRequest, record: LaneRecord): Promise<WorkerDelegationRunOutcome>;\n\tscheduler: Pick<WorkerDispatchScheduler, \"enqueue\" | \"track\" | \"drain\">;\n\tstatusChanged(): void;\n\tabortLane(laneId: string, reasonCode: string): void;\n\tcancelLane(laneId: string, reasonCode: string): LaneRecord | undefined;\n}\n\n/**\n * Sole owner of model-facing logical-agent controls and their durable inboxes.\n *\n * It deliberately owns no worker execution policy, provider loop, or terminal persistence. Those\n * controller-owned callbacks keep this narrow port from becoming a second lifecycle authority.\n */\nexport class WorkerAgentControlCoordinator implements WorkerAgentControlPort {\n\tprivate readonly options: WorkerAgentControlCoordinatorOptions;\n\tprivate readonly mailboxes = new Map<string, WorkerAgentMailbox>();\n\tprivate readonly stateListeners = new Set<() => void>();\n\n\tconstructor(options: WorkerAgentControlCoordinatorOptions) {\n\t\tthis.options = options;\n\t}\n\n\tgetProcessOwnerId(): string {\n\t\treturn this.options.processOwnerId;\n\t}\n\n\tsendWorkerAgentMessage(agentId: string, message: string): { messageId: string; queued: true } {\n\t\tthis.requireControl();\n\t\tconst agent = this.requireKnownAgent(agentId);\n\t\tconst queued = this.getMailbox(agent.agentId).enqueue({ kind: \"follow_up\", content: message });\n\t\tthis.signalStateChanged();\n\t\treturn { messageId: queued.messageId, queued: true };\n\t}\n\n\tfollowUpWorkerAgent(\n\t\tagentId: string,\n\t\tmessage: string,\n\t): { started: boolean; steering: boolean; messageId: string; record?: LaneRecord; skipReason?: string } {\n\t\tthis.requireControl();\n\t\tconst agent = this.requireKnownAgent(agentId);\n\t\tconst canonicalAgentId = agent.agentId;\n\t\tconst active = agent.activeAttemptId\n\t\t\t? this.options.getLifecycle().getTaskRuntimeSnapshot().attempts[agent.activeAttemptId]\n\t\t\t: undefined;\n\t\tif (active?.status === \"running\" || active?.status === \"leased\") {\n\t\t\tconst queued = this.getMailbox(canonicalAgentId).enqueue({ kind: \"steer\", content: message });\n\t\t\tthis.signalStateChanged();\n\t\t\treturn { started: false, steering: true, messageId: queued.messageId };\n\t\t}\n\t\tif (agent.status !== \"registered\") {\n\t\t\treturn { started: false, steering: false, messageId: \"\", skipReason: `agent_${agent.status}` };\n\t\t}\n\t\tconst queued = this.getMailbox(canonicalAgentId).enqueue({ kind: \"follow_up\", content: message });\n\t\ttry {\n\t\t\tconst prepared = this.options\n\t\t\t\t.getLifecycle()\n\t\t\t\t.prepareAgentTurn({ agentId: canonicalAgentId, instructions: message });\n\t\t\tthis.options.scheduler.enqueue(prepared.record, this.options.recoveredRequest(prepared.attempt));\n\t\t\tthis.options.statusChanged();\n\t\t\tthis.options.scheduler.drain();\n\t\t\tthis.signalStateChanged();\n\t\t\treturn { started: true, steering: false, messageId: queued.messageId, record: prepared.record };\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tstarted: false,\n\t\t\t\tsteering: false,\n\t\t\t\tmessageId: queued.messageId,\n\t\t\t\tskipReason: error instanceof Error ? error.message : String(error),\n\t\t\t};\n\t\t}\n\t}\n\n\tinterruptWorkerAgent(agentId: string): { interrupted: boolean; reason?: string } {\n\t\tconst { agent, attempt } = this.controlledAgentAttempt(agentId);\n\t\tif (!attempt || (attempt.status !== \"running\" && attempt.status !== \"leased\")) {\n\t\t\treturn { interrupted: false, reason: \"agent_not_running\" };\n\t\t}\n\t\ttry {\n\t\t\tthis.options.getLifecycle().suspendAgent(attempt.taskId, agent.agentId, this.options.processOwnerId);\n\t\t\tthis.options.abortLane(attempt.taskId, \"agent_interrupted\");\n\t\t\tthis.signalStateChanged();\n\t\t\treturn { interrupted: true };\n\t\t} catch (error) {\n\t\t\treturn { interrupted: false, reason: error instanceof Error ? error.message : String(error) };\n\t\t}\n\t}\n\n\tresumeWorkerAgent(agentId: string): { started: boolean; record?: LaneRecord; skipReason?: string } {\n\t\tconst { attempt } = this.controlledAgentAttempt(agentId);\n\t\tif (!attempt || attempt.status !== \"suspended\") return { started: false, skipReason: \"agent_not_suspended\" };\n\t\tconst record = this.options.getLifecycle().getRecord(attempt.taskId);\n\t\tif (!record) return { started: false, skipReason: \"orchestration_projection_missing\" };\n\t\tconst promise = this.options.run(this.options.recoveredRequest(attempt), record);\n\t\tthis.options.scheduler.track(record.laneId, promise);\n\t\tthis.signalStateChanged();\n\t\treturn { started: true, record };\n\t}\n\n\tcancelWorkerAgent(agentId: string, reasonCode = \"agent_cancelled\"): LaneRecord | undefined {\n\t\tconst { attempt } = this.controlledAgentAttempt(agentId);\n\t\tif (!attempt) return undefined;\n\t\tthis.options.abortLane(attempt.taskId, reasonCode);\n\t\tconst record = this.options.cancelLane(attempt.taskId, reasonCode);\n\t\tthis.signalStateChanged();\n\t\treturn record;\n\t}\n\n\t/** Event-driven wait: durable projection plus state/mailbox notifications, never output polling. */\n\twaitForWorkerAgent(\n\t\tagentId: string,\n\t\ttimeoutMs = 30_000,\n\t): Promise<{ status: \"active\" | \"suspended\" | \"idle\" | \"unknown\" }> {\n\t\tthis.requireControl();\n\t\tconst canonicalAgentId = agentId.trim();\n\t\tconst boundedTimeoutMs = Number.isFinite(timeoutMs)\n\t\t\t? Math.max(1, Math.min(Math.floor(timeoutMs), 300_000))\n\t\t\t: 30_000;\n\t\tconst currentStatus = (): \"active\" | \"suspended\" | \"idle\" | \"unknown\" => {\n\t\t\tconst agent = this.options.getLifecycle().getAgent(canonicalAgentId);\n\t\t\tif (!agent) return \"unknown\";\n\t\t\tif (agent.status === \"active\" || agent.status === \"resuming\") return \"active\";\n\t\t\tif (agent.status === \"suspended\") return \"suspended\";\n\t\t\treturn \"idle\";\n\t\t};\n\t\tconst immediate = currentStatus();\n\t\tif (immediate !== \"active\") return Promise.resolve({ status: immediate });\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tconst settle = () => {\n\t\t\t\tif (settled) return;\n\t\t\t\tconst next = currentStatus();\n\t\t\t\tif (next === \"active\") return;\n\t\t\t\tsettled = true;\n\t\t\t\tunsubscribeMailbox();\n\t\t\t\tunsubscribeState();\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\tresolve({ status: next });\n\t\t\t};\n\t\t\tconst unsubscribeMailbox = this.getMailbox(canonicalAgentId).subscribe(settle);\n\t\t\tconst unsubscribeState = this.subscribeStateChanges(settle);\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tunsubscribeMailbox();\n\t\t\t\tunsubscribeState();\n\t\t\t\tresolve({ status: currentStatus() });\n\t\t\t}, boundedTimeoutMs);\n\t\t\tif (typeof timeout === \"object\" && \"unref\" in timeout) timeout.unref();\n\t\t});\n\t}\n\n\t/** Read mailbox items at a safe boundary and reconcile the narrow append-before-ack crash window. */\n\tmailboxMessagesForConversation(\n\t\tagentId: string,\n\t\tconversation: WorkerConversation,\n\t\tincludeFollowUp: boolean,\n\t): AgentMessage[] {\n\t\tconst mailbox = this.getMailbox(agentId);\n\t\tconst pending = mailbox.pending();\n\t\tif (pending.length === 0) return [];\n\t\tconst delivered = conversation.findDeliveredWorkerControlMessageIds(pending.map((message) => message.messageId));\n\t\tfor (const messageId of delivered) mailbox.acknowledgeDelivered(messageId);\n\t\treturn mailbox\n\t\t\t.pending()\n\t\t\t.filter((message) => message.kind === \"steer\" || includeFollowUp)\n\t\t\t.map((message) => this.mailboxMessage(message));\n\t}\n\n\t/** Acknowledge only after the exact child transcript message has been durably appended. */\n\tacknowledgeMailboxMessage(agentId: string, message: { role: string; content: unknown }): void {\n\t\tif (message.role !== \"user\" || typeof message.content !== \"string\") return;\n\t\tconst messageId = /^\\[Worker control (worker-message-[^\\]]+)\\]\\n/.exec(message.content)?.[1];\n\t\tif (messageId) this.getMailbox(agentId).acknowledgeDelivered(messageId);\n\t}\n\n\t/** Called by controller-owned execution transitions after lifecycle state changed. */\n\tsignalStateChanged(): void {\n\t\tfor (const listener of this.stateListeners) listener();\n\t}\n\n\tprivate requireControl(): void {\n\t\tif (!this.options.isControlAvailable()) {\n\t\t\tthrow new Error(\"Worker delegation control is unavailable in this UAC surface.\");\n\t\t}\n\t}\n\n\tprivate requireKnownAgent(agentId: string): AgentBindingContract {\n\t\tconst normalized = agentId.trim();\n\t\tif (!normalized) throw new Error(\"Logical worker agent id is required.\");\n\t\tconst agent = this.options.getLifecycle().getAgent(normalized);\n\t\tif (!agent) throw new Error(`Unknown logical worker agent '${normalized}'.`);\n\t\treturn agent;\n\t}\n\n\tprivate controlledAgentAttempt(agentId: string): {\n\t\tagent: AgentBindingContract;\n\t\tattempt: AttemptRuntimeState | undefined;\n\t} {\n\t\tthis.requireControl();\n\t\tconst agent = this.requireKnownAgent(agentId);\n\t\tconst attempt = agent.activeAttemptId\n\t\t\t? this.options.getLifecycle().getTaskRuntimeSnapshot().attempts[agent.activeAttemptId]\n\t\t\t: undefined;\n\t\treturn { agent, attempt };\n\t}\n\n\tprivate getMailbox(agentId: string): WorkerAgentMailbox {\n\t\tlet mailbox = this.mailboxes.get(agentId);\n\t\tif (!mailbox) {\n\t\t\tmailbox = new WorkerAgentMailbox({\n\t\t\t\tagentDir: this.options.agentDir,\n\t\t\t\tparentSessionId: this.options.parentSessionId,\n\t\t\t\tagentId,\n\t\t\t});\n\t\t\tthis.mailboxes.set(agentId, mailbox);\n\t\t}\n\t\treturn mailbox;\n\t}\n\n\tprivate subscribeStateChanges(listener: () => void): () => void {\n\t\tthis.stateListeners.add(listener);\n\t\treturn () => this.stateListeners.delete(listener);\n\t}\n\n\tprivate mailboxMessage(message: WorkerAgentMessage): AgentMessage {\n\t\treturn {\n\t\t\trole: \"user\",\n\t\t\tcontent: `[Worker control ${message.messageId}]\\n${message.content}`,\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"worker-agent-control-coordinator.js","sourceRoot":"","sources":["../../../src/core/delegation/worker-agent-control-coordinator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@caupulican/pi-agent-core\";\nimport type { WorkerDelegationRunOutcome } from \"../agent-session-contracts.ts\";\nimport type { LaneRecord } from \"../autonomy/lane-tracker.ts\";\nimport type { AgentBindingContract } from \"../orchestration/contracts.ts\";\nimport type { AttemptRuntimeState } from \"../orchestration/task-runtime.ts\";\nimport {\n\ttype WorkerAgentControlPort,\n\ttype WorkerAgentControlScope,\n\tWorkerAgentMailbox,\n\ttype WorkerAgentMessage,\n\ttype WorkerAgentMessageOptions,\n\ttype WorkerAgentTranscriptOptions,\n} from \"./worker-agent-control.ts\";\nimport { type WorkerConversation, WorkerConversationStore } from \"./worker-conversation-store.ts\";\nimport type { WorkerDelegationRequest } from \"./worker-delegation-request.ts\";\nimport type { WorkerDispatchScheduler } from \"./worker-dispatch-scheduler.ts\";\nimport type { WorkerLifecycle } from \"./worker-lifecycle.ts\";\n\nexport interface WorkerAgentControlCoordinatorOptions {\n\tagentDir: string;\n\tparentSessionId: string;\n\tprocessOwnerId: string;\n\tisControlAvailable(): boolean;\n\tgetLifecycle(): WorkerLifecycle;\n\trecoveredRequest(attempt: AttemptRuntimeState): WorkerDelegationRequest;\n\trun(request: WorkerDelegationRequest, record: LaneRecord): Promise<WorkerDelegationRunOutcome>;\n\tscheduler: Pick<WorkerDispatchScheduler, \"enqueue\" | \"track\" | \"drain\">;\n\tstatusChanged(): void;\n\tabortLane(laneId: string, reasonCode: string): void;\n\tcancelLane(laneId: string, reasonCode: string): LaneRecord | undefined;\n\tyieldCapacity?(callerAgentId: string, targetAgentId: string): () => void;\n}\n\n/**\n * Sole owner of model-facing logical-agent controls and their durable inboxes.\n *\n * It deliberately owns no worker execution policy, provider loop, or terminal persistence. Those\n * controller-owned callbacks keep this narrow port from becoming a second lifecycle authority.\n */\nexport class WorkerAgentControlCoordinator implements WorkerAgentControlPort {\n\tprivate readonly options: WorkerAgentControlCoordinatorOptions;\n\tprivate readonly mailboxes = new Map<string, WorkerAgentMailbox>();\n\tprivate readonly stateListeners = new Set<() => void>();\n\tprivate readonly conversations = new WorkerConversationStore();\n\n\tconstructor(options: WorkerAgentControlCoordinatorOptions) {\n\t\tthis.options = options;\n\t}\n\n\tgetProcessOwnerId(): string {\n\t\treturn this.options.processOwnerId;\n\t}\n\n\tlistWorkerAgents(scope: WorkerAgentControlScope = {}): AgentBindingContract[] {\n\t\tthis.requireControl();\n\t\tconst agents = Object.values(this.options.getLifecycle().getTaskRuntimeSnapshot().agents);\n\t\tconst caller = scope.callerAgentId ? this.requireKnownAgent(scope.callerAgentId) : undefined;\n\t\treturn agents\n\t\t\t.filter((agent) => !caller || agent.rootAgentId === caller.rootAgentId)\n\t\t\t.sort((left, right) => left.depth - right.depth || left.createdAt.localeCompare(right.createdAt));\n\t}\n\n\treadWorkerAgentTranscript(\n\t\tagentId: string,\n\t\toptions: WorkerAgentTranscriptOptions = {},\n\t): ReturnType<WorkerAgentControlPort[\"readWorkerAgentTranscript\"]> {\n\t\tthis.requireControl();\n\t\tconst agent = this.requireVisibleAgent(agentId, options);\n\t\tconst cursor = options.cursor ?? 0;\n\t\tconst maxMessages = options.maxMessages ?? 16;\n\t\tif (!Number.isSafeInteger(cursor) || cursor < 0) throw new TypeError(\"Worker transcript cursor is invalid.\");\n\t\tif (!Number.isSafeInteger(maxMessages) || maxMessages < 1 || maxMessages > 64) {\n\t\t\tthrow new TypeError(\"Worker transcript page size must be from 1 through 64 messages.\");\n\t\t}\n\t\tconst transcript = this.conversations\n\t\t\t.open({\n\t\t\t\tagentDir: this.options.agentDir,\n\t\t\t\tresumeContext: agent.resumeContext,\n\t\t\t\texpectedLogicalAgentId: agent.agentId,\n\t\t\t})\n\t\t\t.getRawTranscript();\n\t\tif (cursor > transcript.length) throw new TypeError(\"Worker transcript cursor exceeds the transcript length.\");\n\t\tconst messages = transcript.slice(cursor, cursor + maxMessages);\n\t\tconst nextCursor = cursor + messages.length;\n\t\treturn {\n\t\t\tagentId: agent.agentId,\n\t\t\tcursor,\n\t\t\ttotalMessages: transcript.length,\n\t\t\tmessages,\n\t\t\t...(nextCursor < transcript.length ? { nextCursor } : {}),\n\t\t};\n\t}\n\n\tsendWorkerAgentMessage(\n\t\tagentId: string,\n\t\tmessage: string,\n\t\toptions: WorkerAgentMessageOptions = {},\n\t): { messageId: string; queued: true } {\n\t\tthis.requireControl();\n\t\tconst agent = this.requireVisibleAgent(agentId, { callerAgentId: options.senderAgentId });\n\t\tconst queued = this.enqueuePeerMessage(agent, \"follow_up\", message, options);\n\t\tthis.signalStateChanged();\n\t\treturn { messageId: queued.messageId, queued: true };\n\t}\n\n\tfollowUpWorkerAgent(\n\t\tagentId: string,\n\t\tmessage: string,\n\t\toptions: WorkerAgentMessageOptions = {},\n\t): { started: boolean; steering: boolean; messageId: string; record?: LaneRecord; skipReason?: string } {\n\t\tthis.requireControl();\n\t\tconst agent = this.requireVisibleAgent(agentId, { callerAgentId: options.senderAgentId });\n\t\tconst canonicalAgentId = agent.agentId;\n\t\tconst active = this.latestAgentAttempt(agent);\n\t\tif (active?.status === \"queued\" || active?.status === \"running\" || active?.status === \"leased\") {\n\t\t\tconst queued = this.enqueuePeerMessage(agent, \"steer\", message, options);\n\t\t\tthis.signalStateChanged();\n\t\t\treturn { started: false, steering: true, messageId: queued.messageId };\n\t\t}\n\t\tif (agent.status !== \"registered\") {\n\t\t\treturn { started: false, steering: false, messageId: \"\", skipReason: `agent_${agent.status}` };\n\t\t}\n\t\tconst queued = this.enqueuePeerMessage(agent, \"follow_up\", message, options);\n\t\ttry {\n\t\t\tconst prepared = this.options\n\t\t\t\t.getLifecycle()\n\t\t\t\t.prepareAgentTurn({ agentId: canonicalAgentId, instructions: message });\n\t\t\tthis.options.scheduler.enqueue(prepared.record, this.options.recoveredRequest(prepared.attempt));\n\t\t\tthis.options.statusChanged();\n\t\t\tthis.options.scheduler.drain();\n\t\t\tthis.signalStateChanged();\n\t\t\treturn { started: true, steering: false, messageId: queued.messageId, record: prepared.record };\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tstarted: false,\n\t\t\t\tsteering: false,\n\t\t\t\tmessageId: queued.messageId,\n\t\t\t\tskipReason: error instanceof Error ? error.message : String(error),\n\t\t\t};\n\t\t}\n\t}\n\n\tinterruptWorkerAgent(\n\t\tagentId: string,\n\t\tscope: WorkerAgentControlScope = {},\n\t): { interrupted: boolean; reason?: string } {\n\t\tconst { agent, attempt } = this.controlledAgentAttempt(agentId, scope);\n\t\tif (!attempt || (attempt.status !== \"running\" && attempt.status !== \"leased\")) {\n\t\t\treturn { interrupted: false, reason: \"agent_not_running\" };\n\t\t}\n\t\ttry {\n\t\t\tthis.options.getLifecycle().suspendAgent(attempt.taskId, agent.agentId, this.options.processOwnerId);\n\t\t\tthis.options.abortLane(attempt.taskId, \"agent_interrupted\");\n\t\t\tthis.signalStateChanged();\n\t\t\treturn { interrupted: true };\n\t\t} catch (error) {\n\t\t\treturn { interrupted: false, reason: error instanceof Error ? error.message : String(error) };\n\t\t}\n\t}\n\n\tresumeWorkerAgent(\n\t\tagentId: string,\n\t\tscope: WorkerAgentControlScope = {},\n\t): { started: boolean; record?: LaneRecord; skipReason?: string } {\n\t\tconst { attempt } = this.controlledAgentAttempt(agentId, scope);\n\t\tif (!attempt || attempt.status !== \"suspended\") return { started: false, skipReason: \"agent_not_suspended\" };\n\t\tconst record = this.options.getLifecycle().getRecord(attempt.taskId);\n\t\tif (!record) return { started: false, skipReason: \"orchestration_projection_missing\" };\n\t\tconst promise = this.options.run(this.options.recoveredRequest(attempt), record);\n\t\tthis.options.scheduler.track(record.laneId, promise);\n\t\tthis.signalStateChanged();\n\t\treturn { started: true, record };\n\t}\n\n\tcancelWorkerAgent(\n\t\tagentId: string,\n\t\treasonCode = \"agent_cancelled\",\n\t\tscope: WorkerAgentControlScope = {},\n\t): LaneRecord | undefined {\n\t\tconst { attempt } = this.controlledAgentAttempt(agentId, scope);\n\t\tif (!attempt) return undefined;\n\t\tthis.options.abortLane(attempt.taskId, reasonCode);\n\t\tconst record = this.options.cancelLane(attempt.taskId, reasonCode);\n\t\tthis.signalStateChanged();\n\t\treturn record;\n\t}\n\n\t/** Event-driven wait: durable projection plus state/mailbox notifications, never output polling. */\n\twaitForWorkerAgent(\n\t\tagentId: string,\n\t\ttimeoutMs = 30_000,\n\t\tscope: WorkerAgentControlScope = {},\n\t): Promise<{ status: \"active\" | \"suspended\" | \"idle\" | \"unknown\" }> {\n\t\tthis.requireControl();\n\t\tconst canonicalAgentId = agentId.trim();\n\t\tif (!canonicalAgentId) throw new Error(\"Logical worker agent id is required.\");\n\t\tconst target = this.options.getLifecycle().getAgent(canonicalAgentId);\n\t\tif (target) this.requireVisibleAgent(canonicalAgentId, scope);\n\t\tconst boundedTimeoutMs = Number.isFinite(timeoutMs)\n\t\t\t? Math.max(1, Math.min(Math.floor(timeoutMs), 300_000))\n\t\t\t: 30_000;\n\t\tconst currentStatus = (): \"active\" | \"suspended\" | \"idle\" | \"unknown\" => {\n\t\t\tconst agent = this.options.getLifecycle().getAgent(canonicalAgentId);\n\t\t\tif (!agent) return \"unknown\";\n\t\t\tconst attempt = this.latestAgentAttempt(agent);\n\t\t\tif (attempt?.status === \"suspended\" || agent.status === \"suspended\") return \"suspended\";\n\t\t\tif (attempt?.status === \"queued\" || attempt?.status === \"leased\" || attempt?.status === \"running\") {\n\t\t\t\treturn \"active\";\n\t\t\t}\n\t\t\treturn \"idle\";\n\t\t};\n\t\tconst immediate = currentStatus();\n\t\tif (immediate !== \"active\") return Promise.resolve({ status: immediate });\n\t\treturn new Promise((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tlet releaseYield = (): void => undefined;\n\t\t\tlet unsubscribeMailbox = (): void => undefined;\n\t\t\tlet unsubscribeState = (): void => undefined;\n\t\t\tlet timeout: ReturnType<typeof setTimeout> | undefined;\n\t\t\tconst settle = () => {\n\t\t\t\tif (settled) return;\n\t\t\t\tconst next = currentStatus();\n\t\t\t\tif (next === \"active\") return;\n\t\t\t\tsettled = true;\n\t\t\t\tunsubscribeMailbox();\n\t\t\t\tunsubscribeState();\n\t\t\t\tif (timeout) clearTimeout(timeout);\n\t\t\t\treleaseYield();\n\t\t\t\tresolve({ status: next });\n\t\t\t};\n\t\t\tunsubscribeMailbox = this.getMailbox(canonicalAgentId).subscribe(settle);\n\t\t\tunsubscribeState = this.subscribeStateChanges(settle);\n\t\t\ttimeout = setTimeout(() => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tunsubscribeMailbox();\n\t\t\t\tunsubscribeState();\n\t\t\t\treleaseYield();\n\t\t\t\tresolve({ status: currentStatus() });\n\t\t\t}, boundedTimeoutMs);\n\t\t\tif (typeof timeout === \"object\" && \"unref\" in timeout) timeout.unref();\n\t\t\tif (scope.callerAgentId && this.options.yieldCapacity) {\n\t\t\t\tconst yielded = this.options.yieldCapacity(scope.callerAgentId, canonicalAgentId);\n\t\t\t\tif (settled) yielded();\n\t\t\t\telse releaseYield = yielded;\n\t\t\t}\n\t\t\tsettle();\n\t\t});\n\t}\n\n\t/** Read mailbox items at a safe boundary and reconcile the narrow append-before-ack crash window. */\n\tmailboxMessagesForConversation(\n\t\tagentId: string,\n\t\tconversation: WorkerConversation,\n\t\tincludeFollowUp: boolean,\n\t): AgentMessage[] {\n\t\tconst mailbox = this.getMailbox(agentId);\n\t\tconst pending = mailbox.pending();\n\t\tif (pending.length === 0) return [];\n\t\tconst delivered = conversation.findDeliveredWorkerControlMessageIds(pending.map((message) => message.messageId));\n\t\tfor (const messageId of delivered) mailbox.acknowledgeDelivered(messageId);\n\t\treturn mailbox\n\t\t\t.pending()\n\t\t\t.filter((message) => message.kind === \"steer\" || includeFollowUp)\n\t\t\t.map((message) => this.mailboxMessage(message));\n\t}\n\n\t/** Acknowledge only after the exact child transcript message has been durably appended. */\n\tacknowledgeMailboxMessage(agentId: string, message: { role: string; content: unknown }): void {\n\t\tif (message.role !== \"user\" || typeof message.content !== \"string\") return;\n\t\tconst messageId = /^\\[Worker control (worker-message-[^\\]\\s]+)(?: [^\\]]+)?\\]\\n/.exec(message.content)?.[1];\n\t\tif (messageId) this.getMailbox(agentId).acknowledgeDelivered(messageId);\n\t}\n\n\t/** Called by controller-owned execution transitions after lifecycle state changed. */\n\tsignalStateChanged(): void {\n\t\tfor (const listener of this.stateListeners) listener();\n\t}\n\n\t/** Route a terminal child edge to its owning parent without injecting into an active model turn. */\n\tdeliverWorkerTerminalHandoff(args: {\n\t\tparentAgentId: string;\n\t\tchildAgentId: string;\n\t\tterminalAttemptId: string;\n\t\trecord: LaneRecord;\n\t}): { messageId: string; started: boolean } {\n\t\tconst parent = this.requireKnownAgent(args.parentAgentId);\n\t\tconst latest = this.latestAgentAttempt(parent);\n\t\tconst active = latest?.status === \"queued\" || latest?.status === \"leased\" || latest?.status === \"running\";\n\t\tconst content = [\n\t\t\t\"Worker terminal handoff\",\n\t\t\t`childAgentId=${args.childAgentId}`,\n\t\t\t`laneId=${args.record.laneId}`,\n\t\t\t`status=${args.record.status}`,\n\t\t\t...(args.record.reasonCode ? [`reasonCode=${args.record.reasonCode}`] : []),\n\t\t\t`Read the exact child evidence with delegate action=\"transcript\" agentId=\"${args.childAgentId}\".`,\n\t\t].join(\"\\n\");\n\t\tconst queued = this.getMailbox(parent.agentId).enqueue({\n\t\t\tkind: active ? \"steer\" : \"follow_up\",\n\t\t\tcontent,\n\t\t\tsenderAgentId: args.childAgentId,\n\t\t\tidempotencyKey: `terminal-handoff:${args.terminalAttemptId}`,\n\t\t});\n\t\tlet started = false;\n\t\tif (!active && parent.status === \"registered\") {\n\t\t\tconst prepared = this.options.getLifecycle().prepareAgentTurn({\n\t\t\t\tagentId: parent.agentId,\n\t\t\t\tinstructions: content,\n\t\t\t});\n\t\t\tthis.options.scheduler.enqueue(prepared.record, this.options.recoveredRequest(prepared.attempt));\n\t\t\tthis.options.statusChanged();\n\t\t\tthis.options.scheduler.drain();\n\t\t\tstarted = true;\n\t\t}\n\t\tthis.signalStateChanged();\n\t\treturn { messageId: queued.messageId, started };\n\t}\n\n\tprivate requireControl(): void {\n\t\tif (!this.options.isControlAvailable()) {\n\t\t\tthrow new Error(\"Worker delegation control is unavailable in this UAC surface.\");\n\t\t}\n\t}\n\n\tprivate requireKnownAgent(agentId: string): AgentBindingContract {\n\t\tconst normalized = agentId.trim();\n\t\tif (!normalized) throw new Error(\"Logical worker agent id is required.\");\n\t\tconst agent = this.options.getLifecycle().getAgent(normalized);\n\t\tif (!agent) throw new Error(`Unknown logical worker agent '${normalized}'.`);\n\t\treturn agent;\n\t}\n\n\tprivate requireVisibleAgent(agentId: string, scope: WorkerAgentControlScope): AgentBindingContract {\n\t\tconst target = this.requireKnownAgent(agentId);\n\t\tif (!scope.callerAgentId) return target;\n\t\tconst caller = this.requireKnownAgent(scope.callerAgentId);\n\t\tif (caller.rootAgentId !== target.rootAgentId) {\n\t\t\tthrow new Error(`Logical worker agent '${target.agentId}' is outside the caller's agent tree.`);\n\t\t}\n\t\treturn target;\n\t}\n\n\tprivate requireControllableAgent(agentId: string, scope: WorkerAgentControlScope): AgentBindingContract {\n\t\tconst target = this.requireVisibleAgent(agentId, scope);\n\t\tif (!scope.callerAgentId) return target;\n\t\tconst caller = this.requireKnownAgent(scope.callerAgentId);\n\t\tlet cursor: AgentBindingContract | undefined = target;\n\t\tconst visited = new Set<string>();\n\t\twhile (cursor && !visited.has(cursor.agentId)) {\n\t\t\tif (cursor.agentId === caller.agentId) return target;\n\t\t\tvisited.add(cursor.agentId);\n\t\t\tcursor = cursor.parentAgentId ? this.options.getLifecycle().getAgent(cursor.parentAgentId) : undefined;\n\t\t}\n\t\tthrow new Error(`Logical worker agent '${target.agentId}' is outside its control subtree.`);\n\t}\n\n\tprivate latestAgentAttempt(agent: AgentBindingContract): AttemptRuntimeState | undefined {\n\t\tconst lifecycle = this.options.getLifecycle();\n\t\tconst latest = lifecycle.getLatestAgentAttempt?.(agent.agentId);\n\t\tif (latest) return latest;\n\t\treturn agent.activeAttemptId ? lifecycle.getTaskRuntimeSnapshot().attempts[agent.activeAttemptId] : undefined;\n\t}\n\n\tprivate controlledAgentAttempt(\n\t\tagentId: string,\n\t\tscope: WorkerAgentControlScope,\n\t): {\n\t\tagent: AgentBindingContract;\n\t\tattempt: AttemptRuntimeState | undefined;\n\t} {\n\t\tthis.requireControl();\n\t\tconst agent = this.requireControllableAgent(agentId, scope);\n\t\tconst attempt = this.latestAgentAttempt(agent);\n\t\treturn { agent, attempt };\n\t}\n\n\tprivate getMailbox(agentId: string): WorkerAgentMailbox {\n\t\tlet mailbox = this.mailboxes.get(agentId);\n\t\tif (!mailbox) {\n\t\t\tmailbox = new WorkerAgentMailbox({\n\t\t\t\tagentDir: this.options.agentDir,\n\t\t\t\tparentSessionId: this.options.parentSessionId,\n\t\t\t\tagentId,\n\t\t\t});\n\t\t\tthis.mailboxes.set(agentId, mailbox);\n\t\t}\n\t\treturn mailbox;\n\t}\n\n\tprivate subscribeStateChanges(listener: () => void): () => void {\n\t\tthis.stateListeners.add(listener);\n\t\treturn () => this.stateListeners.delete(listener);\n\t}\n\n\tprivate enqueuePeerMessage(\n\t\ttarget: AgentBindingContract,\n\t\tkind: \"steer\" | \"follow_up\",\n\t\tcontent: string,\n\t\toptions: WorkerAgentMessageOptions,\n\t): WorkerAgentMessage {\n\t\tif (!options.replyToMessageId) {\n\t\t\treturn this.getMailbox(target.agentId).enqueue({ kind, content, ...options });\n\t\t}\n\t\tif (!options.senderAgentId) throw new Error(\"A worker reply requires its sender agent identity.\");\n\t\tconst sender = this.requireKnownAgent(options.senderAgentId);\n\t\tif (sender.rootAgentId !== target.rootAgentId)\n\t\t\tthrow new Error(\"A worker reply target is outside its agent tree.\");\n\t\tconst senderMailbox = this.getMailbox(sender.agentId);\n\t\tconst request = senderMailbox.getMessage(options.replyToMessageId);\n\t\tif (!request || request.expectReply !== true || request.deliveredAt === undefined) {\n\t\t\tthrow new Error(\"Worker reply does not reference a delivered reply-expected message.\");\n\t\t}\n\t\tif (request.senderAgentId !== target.agentId) {\n\t\t\tthrow new Error(\"Worker reply target does not match the original requester.\");\n\t\t}\n\t\tif (request.threadId && options.threadId && request.threadId !== options.threadId) {\n\t\t\tthrow new Error(\"Worker reply thread conflicts with the original request.\");\n\t\t}\n\t\tconst queued = this.getMailbox(target.agentId).enqueue({\n\t\t\tkind,\n\t\t\tcontent,\n\t\t\t...options,\n\t\t\t...(request.threadId && !options.threadId ? { threadId: request.threadId } : {}),\n\t\t\tidempotencyKey: `peer-reply:${sender.agentId}:${request.messageId}`,\n\t\t});\n\t\tsenderMailbox.markReplied(request.messageId);\n\t\treturn queued;\n\t}\n\n\tprivate mailboxMessage(message: WorkerAgentMessage): AgentMessage {\n\t\tconst metadata = [\n\t\t\tmessage.senderAgentId ? `from=${message.senderAgentId}` : undefined,\n\t\t\tmessage.threadId ? `thread=${message.threadId}` : undefined,\n\t\t\tmessage.replyToMessageId ? `replyTo=${message.replyToMessageId}` : undefined,\n\t\t\tmessage.expectReply ? \"replyExpected=true\" : undefined,\n\t\t].filter((value): value is string => value !== undefined);\n\t\treturn {\n\t\t\trole: \"user\",\n\t\t\tcontent: `[Worker control ${message.messageId}${metadata.length > 0 ? ` ${metadata.join(\" \")}` : \"\"}]\\n${message.content}`,\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\t}\n}\n"]}
|
|
@@ -1,41 +1,70 @@
|
|
|
1
|
+
import type { Message } from "@caupulican/pi-ai";
|
|
1
2
|
import type { LaneRecord } from "../autonomy/lane-tracker.ts";
|
|
3
|
+
import type { AgentBindingContract } from "../orchestration/contracts.ts";
|
|
2
4
|
export type WorkerAgentMessageKind = "steer" | "follow_up";
|
|
3
5
|
export interface WorkerAgentMessage {
|
|
4
6
|
messageId: string;
|
|
5
7
|
kind: WorkerAgentMessageKind;
|
|
6
8
|
content: string;
|
|
9
|
+
senderAgentId?: string;
|
|
10
|
+
threadId?: string;
|
|
11
|
+
replyToMessageId?: string;
|
|
12
|
+
expectReply?: boolean;
|
|
7
13
|
createdAt: string;
|
|
8
14
|
deliveredAt?: string;
|
|
15
|
+
repliedAt?: string;
|
|
9
16
|
}
|
|
10
17
|
export interface WorkerAgentMailboxOptions {
|
|
11
18
|
agentDir: string;
|
|
12
19
|
parentSessionId: string;
|
|
13
20
|
agentId: string;
|
|
14
21
|
}
|
|
22
|
+
export interface WorkerAgentTranscriptPage {
|
|
23
|
+
agentId: string;
|
|
24
|
+
cursor: number;
|
|
25
|
+
totalMessages: number;
|
|
26
|
+
messages: Message[];
|
|
27
|
+
nextCursor?: number;
|
|
28
|
+
}
|
|
29
|
+
export interface WorkerAgentMessageOptions {
|
|
30
|
+
senderAgentId?: string;
|
|
31
|
+
threadId?: string;
|
|
32
|
+
replyToMessageId?: string;
|
|
33
|
+
expectReply?: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface WorkerAgentControlScope {
|
|
36
|
+
callerAgentId?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface WorkerAgentTranscriptOptions extends WorkerAgentControlScope {
|
|
39
|
+
cursor?: number;
|
|
40
|
+
maxMessages?: number;
|
|
41
|
+
}
|
|
15
42
|
/** One canonical host port for model-facing logical-agent controls. */
|
|
16
43
|
export interface WorkerAgentControlPort {
|
|
17
|
-
|
|
44
|
+
listWorkerAgents(scope?: WorkerAgentControlScope): AgentBindingContract[];
|
|
45
|
+
readWorkerAgentTranscript(agentId: string, options?: WorkerAgentTranscriptOptions): WorkerAgentTranscriptPage;
|
|
46
|
+
sendWorkerAgentMessage(agentId: string, message: string, options?: WorkerAgentMessageOptions): {
|
|
18
47
|
messageId: string;
|
|
19
48
|
queued: true;
|
|
20
49
|
};
|
|
21
|
-
followUpWorkerAgent(agentId: string, message: string): {
|
|
50
|
+
followUpWorkerAgent(agentId: string, message: string, options?: WorkerAgentMessageOptions): {
|
|
22
51
|
started: boolean;
|
|
23
52
|
steering: boolean;
|
|
24
53
|
messageId: string;
|
|
25
54
|
record?: LaneRecord;
|
|
26
55
|
skipReason?: string;
|
|
27
56
|
};
|
|
28
|
-
interruptWorkerAgent(agentId: string): {
|
|
57
|
+
interruptWorkerAgent(agentId: string, scope?: WorkerAgentControlScope): {
|
|
29
58
|
interrupted: boolean;
|
|
30
59
|
reason?: string;
|
|
31
60
|
};
|
|
32
|
-
resumeWorkerAgent(agentId: string): {
|
|
61
|
+
resumeWorkerAgent(agentId: string, scope?: WorkerAgentControlScope): {
|
|
33
62
|
started: boolean;
|
|
34
63
|
record?: LaneRecord;
|
|
35
64
|
skipReason?: string;
|
|
36
65
|
};
|
|
37
|
-
cancelWorkerAgent(agentId: string, reasonCode?: string): LaneRecord | undefined;
|
|
38
|
-
waitForWorkerAgent(agentId: string, timeoutMs?: number): Promise<{
|
|
66
|
+
cancelWorkerAgent(agentId: string, reasonCode?: string, scope?: WorkerAgentControlScope): LaneRecord | undefined;
|
|
67
|
+
waitForWorkerAgent(agentId: string, timeoutMs?: number, scope?: WorkerAgentControlScope): Promise<{
|
|
39
68
|
status: "active" | "suspended" | "idle" | "unknown";
|
|
40
69
|
}>;
|
|
41
70
|
}
|
|
@@ -55,9 +84,19 @@ export declare class WorkerAgentMailbox {
|
|
|
55
84
|
enqueue(input: {
|
|
56
85
|
kind: WorkerAgentMessageKind;
|
|
57
86
|
content: string;
|
|
87
|
+
senderAgentId?: string;
|
|
88
|
+
threadId?: string;
|
|
89
|
+
replyToMessageId?: string;
|
|
90
|
+
expectReply?: boolean;
|
|
91
|
+
/** Host-owned retry identity; callers cannot choose durable message ids directly. */
|
|
92
|
+
idempotencyKey?: string;
|
|
58
93
|
}): WorkerAgentMessage;
|
|
59
94
|
pending(kind?: WorkerAgentMessageKind): WorkerAgentMessage[];
|
|
60
95
|
acknowledgeDelivered(messageId: string): void;
|
|
96
|
+
awaitingReplies(): WorkerAgentMessage[];
|
|
97
|
+
getMessage(messageId: string): WorkerAgentMessage | undefined;
|
|
98
|
+
markReplied(messageId: string): boolean;
|
|
99
|
+
private markTimestamp;
|
|
61
100
|
subscribe(listener: () => void): () => void;
|
|
62
101
|
private notify;
|
|
63
102
|
private read;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-agent-control.d.ts","sourceRoot":"","sources":["../../../src/core/delegation/worker-agent-control.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"worker-agent-control.d.ts","sourceRoot":"","sources":["../../../src/core/delegation/worker-agent-control.ts"],"names":[],"mappings":"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"}
|