@caupulican/pi-adaptative 0.81.41 → 0.81.42
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 +16 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/commands/text.py +5 -1
- package/dist/bundled-resources/runtimes/pi-shell-engine/context.py +3 -3
- package/dist/bundled-resources/runtimes/pi-shell-engine/errors.py +8 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/exec.py +26 -3
- package/dist/bundled-resources/runtimes/pi-shell-engine/expand.py +3 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/main.py +4 -1
- package/dist/bundled-resources/runtimes/pi-shell-engine/state.py +2 -1
- package/dist/bundled-resources/runtimes/pi-shell-engine/tokens.py +2 -0
- package/dist/core/agent-paths.d.ts +32 -0
- package/dist/core/agent-paths.d.ts.map +1 -1
- package/dist/core/agent-paths.js +65 -0
- package/dist/core/agent-paths.js.map +1 -1
- package/dist/core/agent-session-contracts.d.ts +19 -1
- package/dist/core/agent-session-contracts.d.ts.map +1 -1
- package/dist/core/agent-session-contracts.js.map +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +4 -9
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/contracts.d.ts +2 -0
- package/dist/core/autonomy/contracts.d.ts.map +1 -1
- package/dist/core/autonomy/contracts.js.map +1 -1
- package/dist/core/autonomy/envelope-enforcement.d.ts.map +1 -1
- package/dist/core/autonomy/envelope-enforcement.js +4 -9
- package/dist/core/autonomy/envelope-enforcement.js.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.d.ts +3 -1
- package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tool-surface.js +17 -4
- package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
- package/dist/core/autonomy/path-scope.d.ts +14 -0
- package/dist/core/autonomy/path-scope.d.ts.map +1 -1
- package/dist/core/autonomy/path-scope.js +37 -6
- package/dist/core/autonomy/path-scope.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +27 -1
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +32 -1
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/delegation/managed-lane-controller.d.ts +11 -1
- package/dist/core/delegation/managed-lane-controller.d.ts.map +1 -1
- package/dist/core/delegation/managed-lane-controller.js +84 -41
- package/dist/core/delegation/managed-lane-controller.js.map +1 -1
- package/dist/core/delegation/session-worker-claim.d.ts.map +1 -1
- package/dist/core/delegation/session-worker-claim.js +4 -3
- package/dist/core/delegation/session-worker-claim.js.map +1 -1
- package/dist/core/delegation/worker-action-journal.d.ts +73 -0
- package/dist/core/delegation/worker-action-journal.d.ts.map +1 -0
- package/dist/core/delegation/worker-action-journal.js +297 -0
- package/dist/core/delegation/worker-action-journal.js.map +1 -0
- package/dist/core/delegation/worker-actions.d.ts +36 -1
- package/dist/core/delegation/worker-actions.d.ts.map +1 -1
- package/dist/core/delegation/worker-actions.js +171 -46
- package/dist/core/delegation/worker-actions.js.map +1 -1
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts +75 -0
- package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -0
- package/dist/core/delegation/worker-agent-control-coordinator.js +218 -0
- package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -0
- package/dist/core/delegation/worker-agent-control.d.ts +66 -0
- package/dist/core/delegation/worker-agent-control.d.ts.map +1 -0
- package/dist/core/delegation/worker-agent-control.js +163 -0
- package/dist/core/delegation/worker-agent-control.js.map +1 -0
- package/dist/core/delegation/worker-attempt-executor.d.ts +80 -0
- package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -0
- package/dist/core/delegation/worker-attempt-executor.js +343 -0
- package/dist/core/delegation/worker-attempt-executor.js.map +1 -0
- package/dist/core/delegation/worker-claim.d.ts +30 -0
- package/dist/core/delegation/worker-claim.d.ts.map +1 -1
- package/dist/core/delegation/worker-claim.js +205 -53
- package/dist/core/delegation/worker-claim.js.map +1 -1
- package/dist/core/delegation/worker-conversation-store.d.ts +116 -0
- package/dist/core/delegation/worker-conversation-store.d.ts.map +1 -0
- package/dist/core/delegation/worker-conversation-store.js +442 -0
- package/dist/core/delegation/worker-conversation-store.js.map +1 -0
- package/dist/core/delegation/worker-delegation-controller.d.ts +21 -5
- package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-controller.js +386 -251
- package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
- package/dist/core/delegation/worker-delegation-request.d.ts +14 -0
- package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -1
- package/dist/core/delegation/worker-delegation-request.js.map +1 -1
- package/dist/core/delegation/worker-dispatch-scheduler.d.ts +4 -2
- package/dist/core/delegation/worker-dispatch-scheduler.d.ts.map +1 -1
- package/dist/core/delegation/worker-dispatch-scheduler.js +16 -6
- package/dist/core/delegation/worker-dispatch-scheduler.js.map +1 -1
- package/dist/core/delegation/worker-execution-policy.d.ts +2 -1
- package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -1
- package/dist/core/delegation/worker-execution-policy.js +5 -7
- package/dist/core/delegation/worker-execution-policy.js.map +1 -1
- package/dist/core/delegation/worker-lifecycle.d.ts +44 -1
- package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -1
- package/dist/core/delegation/worker-lifecycle.js +120 -0
- package/dist/core/delegation/worker-lifecycle.js.map +1 -1
- package/dist/core/delegation/worker-process-owner.d.ts +18 -0
- package/dist/core/delegation/worker-process-owner.d.ts.map +1 -0
- package/dist/core/delegation/worker-process-owner.js +54 -0
- package/dist/core/delegation/worker-process-owner.js.map +1 -0
- package/dist/core/delegation/worker-profile-resolver.d.ts +5 -1
- package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -1
- package/dist/core/delegation/worker-profile-resolver.js +8 -0
- package/dist/core/delegation/worker-profile-resolver.js.map +1 -1
- package/dist/core/delegation/worker-recovery-coordinator.d.ts +54 -0
- package/dist/core/delegation/worker-recovery-coordinator.d.ts.map +1 -0
- package/dist/core/delegation/worker-recovery-coordinator.js +181 -0
- package/dist/core/delegation/worker-recovery-coordinator.js.map +1 -0
- package/dist/core/delegation/worker-resource-catalog.d.ts +32 -0
- package/dist/core/delegation/worker-resource-catalog.d.ts.map +1 -0
- package/dist/core/delegation/worker-resource-catalog.js +116 -0
- package/dist/core/delegation/worker-resource-catalog.js.map +1 -0
- package/dist/core/delegation/worker-resource-materializer.d.ts +47 -0
- package/dist/core/delegation/worker-resource-materializer.d.ts.map +1 -0
- package/dist/core/delegation/worker-resource-materializer.js +137 -0
- package/dist/core/delegation/worker-resource-materializer.js.map +1 -0
- package/dist/core/delegation/worker-runner.d.ts +3 -1
- package/dist/core/delegation/worker-runner.d.ts.map +1 -1
- package/dist/core/delegation/worker-runner.js +189 -54
- package/dist/core/delegation/worker-runner.js.map +1 -1
- package/dist/core/delegation/worker-terminal-finalizer.d.ts +23 -0
- package/dist/core/delegation/worker-terminal-finalizer.d.ts.map +1 -0
- package/dist/core/delegation/worker-terminal-finalizer.js +12 -0
- package/dist/core/delegation/worker-terminal-finalizer.js.map +1 -0
- package/dist/core/delegation/worker-write-reservation-coordinator.d.ts +38 -0
- package/dist/core/delegation/worker-write-reservation-coordinator.d.ts.map +1 -0
- package/dist/core/delegation/worker-write-reservation-coordinator.js +107 -0
- package/dist/core/delegation/worker-write-reservation-coordinator.js.map +1 -0
- package/dist/core/delegation/worker-write-reservation.d.ts +90 -0
- package/dist/core/delegation/worker-write-reservation.d.ts.map +1 -0
- package/dist/core/delegation/worker-write-reservation.js +348 -0
- package/dist/core/delegation/worker-write-reservation.js.map +1 -0
- package/dist/core/models/model-endpoint.d.ts +3 -0
- package/dist/core/models/model-endpoint.d.ts.map +1 -0
- package/dist/core/models/model-endpoint.js +11 -0
- package/dist/core/models/model-endpoint.js.map +1 -0
- package/dist/core/orchestration/agent-resume.d.ts +2 -0
- package/dist/core/orchestration/agent-resume.d.ts.map +1 -1
- package/dist/core/orchestration/agent-resume.js +7 -0
- package/dist/core/orchestration/agent-resume.js.map +1 -1
- package/dist/core/orchestration/attempt-usage.d.ts +28 -0
- package/dist/core/orchestration/attempt-usage.d.ts.map +1 -0
- package/dist/core/orchestration/attempt-usage.js +168 -0
- package/dist/core/orchestration/attempt-usage.js.map +1 -0
- package/dist/core/orchestration/capability-gateway.d.ts +19 -1
- package/dist/core/orchestration/capability-gateway.d.ts.map +1 -1
- package/dist/core/orchestration/capability-gateway.js +128 -28
- package/dist/core/orchestration/capability-gateway.js.map +1 -1
- package/dist/core/orchestration/contracts.d.ts +35 -0
- package/dist/core/orchestration/contracts.d.ts.map +1 -1
- package/dist/core/orchestration/contracts.js +17 -0
- package/dist/core/orchestration/contracts.js.map +1 -1
- package/dist/core/orchestration/delegation-ledger.d.ts +17 -2
- package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -1
- package/dist/core/orchestration/delegation-ledger.js +78 -3
- package/dist/core/orchestration/delegation-ledger.js.map +1 -1
- package/dist/core/orchestration/event-store.d.ts +1 -0
- package/dist/core/orchestration/event-store.d.ts.map +1 -1
- package/dist/core/orchestration/event-store.js +78 -38
- package/dist/core/orchestration/event-store.js.map +1 -1
- package/dist/core/orchestration/profile-registry.d.ts.map +1 -1
- package/dist/core/orchestration/profile-registry.js +81 -41
- package/dist/core/orchestration/profile-registry.js.map +1 -1
- package/dist/core/orchestration/profile-store.d.ts.map +1 -1
- package/dist/core/orchestration/profile-store.js +18 -4
- package/dist/core/orchestration/profile-store.js.map +1 -1
- package/dist/core/orchestration/risk-budget.d.ts +2 -0
- package/dist/core/orchestration/risk-budget.d.ts.map +1 -1
- package/dist/core/orchestration/risk-budget.js +26 -0
- package/dist/core/orchestration/risk-budget.js.map +1 -1
- package/dist/core/orchestration/task-runtime.d.ts +13 -1
- package/dist/core/orchestration/task-runtime.d.ts.map +1 -1
- package/dist/core/orchestration/task-runtime.js +127 -16
- package/dist/core/orchestration/task-runtime.js.map +1 -1
- package/dist/core/orchestration/worker-execution-contract.d.ts +3 -1
- package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -1
- package/dist/core/orchestration/worker-execution-contract.js +75 -23
- package/dist/core/orchestration/worker-execution-contract.js.map +1 -1
- package/dist/core/orchestration/worker-result-adapter.d.ts +9 -3
- package/dist/core/orchestration/worker-result-adapter.d.ts.map +1 -1
- package/dist/core/orchestration/worker-result-adapter.js +167 -14
- package/dist/core/orchestration/worker-result-adapter.js.map +1 -1
- package/dist/core/reflection-controller.d.ts +1 -1
- package/dist/core/reflection-controller.d.ts.map +1 -1
- package/dist/core/reflection-controller.js +90 -54
- package/dist/core/reflection-controller.js.map +1 -1
- package/dist/core/research/evidence-bundle.d.ts +20 -0
- package/dist/core/research/evidence-bundle.d.ts.map +1 -1
- package/dist/core/research/evidence-bundle.js +173 -69
- package/dist/core/research/evidence-bundle.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +7 -0
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +15 -1
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/session-artifact-bundle.d.ts +35 -0
- package/dist/core/session-artifact-bundle.d.ts.map +1 -0
- package/dist/core/session-artifact-bundle.js +61 -0
- package/dist/core/session-artifact-bundle.js.map +1 -0
- package/dist/core/tools/delegate-status.d.ts +6 -1
- package/dist/core/tools/delegate-status.d.ts.map +1 -1
- package/dist/core/tools/delegate-status.js +100 -18
- package/dist/core/tools/delegate-status.js.map +1 -1
- package/dist/core/tools/delegate.d.ts +9 -1
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +323 -61
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/run-process.d.ts +1 -1
- package/dist/core/tools/run-process.d.ts.map +1 -1
- package/dist/core/tools/run-process.js +69 -9
- package/dist/core/tools/run-process.js.map +1 -1
- package/dist/core/tools/shell-contract-router.d.ts.map +1 -1
- package/dist/core/tools/shell-contract-router.js +12 -5
- package/dist/core/tools/shell-contract-router.js.map +1 -1
- package/dist/core/util/bounded-file.d.ts +15 -0
- package/dist/core/util/bounded-file.d.ts.map +1 -0
- package/dist/core/util/bounded-file.js +120 -0
- package/dist/core/util/bounded-file.js.map +1 -0
- package/dist/core/util/bounded-jsonl.d.ts.map +1 -1
- package/dist/core/util/bounded-jsonl.js +119 -9
- package/dist/core/util/bounded-jsonl.js.map +1 -1
- package/dist/core/util/bounded-value.d.ts +3 -0
- package/dist/core/util/bounded-value.d.ts.map +1 -0
- package/dist/core/util/bounded-value.js +12 -0
- package/dist/core/util/bounded-value.js.map +1 -0
- package/dist/core/util/value-guards.d.ts +2 -0
- package/dist/core/util/value-guards.d.ts.map +1 -1
- package/dist/core/util/value-guards.js +5 -0
- package/dist/core/util/value-guards.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +27 -44
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/docs/tool-repair.md +3 -0
- package/docs/windows.md +4 -2
- 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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-agent-control.js","sourceRoot":"","sources":["../../../src/core/delegation/worker-agent-control.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomUUID } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { workerAgentMailboxFile } from \"../agent-paths.ts\";\nimport type { LaneRecord } from \"../autonomy/lane-tracker.ts\";\nimport { withFileLockSync, writeFileAtomicSync } from \"../util/atomic-file.ts\";\nimport { readBoundedTextFileSync } from \"../util/bounded-file.ts\";\n\nconst MAX_MAILBOX_MESSAGES = 64;\nconst MAX_MAILBOX_MESSAGE_CHARS = 4_096;\nconst MAX_MAILBOX_BYTES = 128 * 1024;\nconst MAX_MAILBOX_MESSAGE_ID_CHARS = 512;\nconst MAX_MAILBOX_TIMESTAMP_CHARS = 128;\n\nexport type WorkerAgentMessageKind = \"steer\" | \"follow_up\";\n\nexport interface WorkerAgentMessage {\n\tmessageId: string;\n\tkind: WorkerAgentMessageKind;\n\tcontent: string;\n\tcreatedAt: string;\n\tdeliveredAt?: string;\n}\n\ninterface WorkerAgentMailboxState {\n\tversion: 1;\n\tparentSessionId: string;\n\tagentId: string;\n\tmessages: WorkerAgentMessage[];\n}\n\nexport interface WorkerAgentMailboxOptions {\n\tagentDir: string;\n\tparentSessionId: string;\n\tagentId: string;\n}\n\n/** One canonical host port for model-facing logical-agent controls. */\nexport interface WorkerAgentControlPort {\n\tsendWorkerAgentMessage(agentId: string, message: string): { messageId: string; queued: true };\n\tfollowUpWorkerAgent(\n\t\tagentId: string,\n\t\tmessage: string,\n\t): { started: boolean; steering: boolean; messageId: string; record?: LaneRecord; skipReason?: string };\n\tinterruptWorkerAgent(agentId: string): { interrupted: boolean; reason?: string };\n\tresumeWorkerAgent(agentId: string): { started: boolean; record?: LaneRecord; skipReason?: string };\n\tcancelWorkerAgent(agentId: string, reasonCode?: string): LaneRecord | undefined;\n\twaitForWorkerAgent(\n\t\tagentId: string,\n\t\ttimeoutMs?: number,\n\t): Promise<{ status: \"active\" | \"suspended\" | \"idle\" | \"unknown\" }>;\n}\n\nfunction mailboxDigest(parentSessionId: string, agentId: string): string {\n\treturn createHash(\"sha256\")\n\t\t.update(\"pi-worker-agent-mailbox-v1\")\n\t\t.update(\"\\0\")\n\t\t.update(parentSessionId)\n\t\t.update(\"\\0\")\n\t\t.update(agentId)\n\t\t.digest(\"hex\");\n}\n\nfunction assertIdentity(value: string, label: string): string {\n\tconst normalized = value.trim();\n\tif (!normalized) throw new TypeError(`A worker ${label} is required.`);\n\tif (normalized.length > 512) throw new TypeError(`Worker ${label} exceeds 512 characters.`);\n\treturn normalized;\n}\n\nfunction parseState(raw: string, parentSessionId: string, agentId: string): WorkerAgentMailboxState {\n\tlet candidate: unknown;\n\ttry {\n\t\tcandidate = JSON.parse(raw);\n\t} catch {\n\t\tthrow new Error(\"Worker agent mailbox is invalid JSON.\");\n\t}\n\tif (!candidate || typeof candidate !== \"object\" || Array.isArray(candidate)) {\n\t\tthrow new Error(\"Worker agent mailbox is invalid.\");\n\t}\n\tconst state = candidate as Partial<WorkerAgentMailboxState>;\n\tif (\n\t\tstate.version !== 1 ||\n\t\tstate.parentSessionId !== parentSessionId ||\n\t\tstate.agentId !== agentId ||\n\t\t!Array.isArray(state.messages)\n\t) {\n\t\tthrow new Error(\"Worker agent mailbox identity conflicts with the requested logical worker.\");\n\t}\n\tconst messages = state.messages.map((message): WorkerAgentMessage => {\n\t\tif (\n\t\t\t!message ||\n\t\t\ttypeof message !== \"object\" ||\n\t\t\tArray.isArray(message) ||\n\t\t\ttypeof message.messageId !== \"string\" ||\n\t\t\tmessage.messageId.length === 0 ||\n\t\t\tmessage.messageId.length > MAX_MAILBOX_MESSAGE_ID_CHARS ||\n\t\t\t(message.kind !== \"steer\" && message.kind !== \"follow_up\") ||\n\t\t\ttypeof message.content !== \"string\" ||\n\t\t\tmessage.content.length === 0 ||\n\t\t\tmessage.content.length > MAX_MAILBOX_MESSAGE_CHARS ||\n\t\t\ttypeof message.createdAt !== \"string\" ||\n\t\t\tmessage.createdAt.length === 0 ||\n\t\t\tmessage.createdAt.length > MAX_MAILBOX_TIMESTAMP_CHARS ||\n\t\t\t(message.deliveredAt !== undefined &&\n\t\t\t\t(typeof message.deliveredAt !== \"string\" ||\n\t\t\t\t\tmessage.deliveredAt.length === 0 ||\n\t\t\t\t\tmessage.deliveredAt.length > MAX_MAILBOX_TIMESTAMP_CHARS))\n\t\t) {\n\t\t\tthrow new Error(\"Worker agent mailbox contains an invalid message.\");\n\t\t}\n\t\treturn { ...message };\n\t});\n\tconst pendingMessages = messages.filter((message) => message.deliveredAt === undefined);\n\tif (pendingMessages.length > MAX_MAILBOX_MESSAGES)\n\t\tthrow new Error(\"Worker agent mailbox exceeds its pending-message bound.\");\n\treturn { version: 1, parentSessionId, agentId, messages: pendingMessages };\n}\n\nfunction encodedStateBytes(state: WorkerAgentMailboxState): number {\n\treturn Buffer.byteLength(JSON.stringify(state), \"utf-8\");\n}\n\n/**\n * Bounded durable inbox for a single logical worker agent.\n *\n * A message is never considered delivered merely because a controller read it. Its caller must\n * acknowledge it only after the exact corresponding user message has been appended to the child\n * WorkerConversation. The in-process subscription is a notification edge, not a polling loop.\n */\nexport class WorkerAgentMailbox {\n\tprivate readonly parentSessionId: string;\n\tprivate readonly agentId: string;\n\tprivate readonly file: string;\n\tprivate readonly listeners = new Set<() => void>();\n\n\tconstructor(options: WorkerAgentMailboxOptions) {\n\t\tthis.parentSessionId = assertIdentity(options.parentSessionId, \"parent session id\");\n\t\tthis.agentId = assertIdentity(options.agentId, \"agent id\");\n\t\tthis.file = workerAgentMailboxFile(\n\t\t\toptions.agentDir,\n\t\t\tthis.parentSessionId,\n\t\t\tmailboxDigest(this.parentSessionId, this.agentId),\n\t\t);\n\t}\n\n\tenqueue(input: { kind: WorkerAgentMessageKind; content: string }): WorkerAgentMessage {\n\t\tconst content = input.content.trim();\n\t\tif (!content) throw new TypeError(\"A worker control message is required.\");\n\t\tif (content.length > MAX_MAILBOX_MESSAGE_CHARS) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`Worker control messages may not exceed ${MAX_MAILBOX_MESSAGE_CHARS.toLocaleString(\"en-US\")} characters.`,\n\t\t\t);\n\t\t}\n\t\tconst message: WorkerAgentMessage = {\n\t\t\tmessageId: `worker-message-${randomUUID()}`,\n\t\t\tkind: input.kind,\n\t\t\tcontent,\n\t\t\tcreatedAt: new Date().toISOString(),\n\t\t};\n\t\tthis.update((state) => {\n\t\t\tif (state.messages.length >= MAX_MAILBOX_MESSAGES) {\n\t\t\t\tthrow new Error(`Worker agent mailbox reached its ${MAX_MAILBOX_MESSAGES} message limit.`);\n\t\t\t}\n\t\t\treturn { ...state, messages: [...state.messages, message] };\n\t\t});\n\t\tthis.notify();\n\t\treturn structuredClone(message);\n\t}\n\n\tpending(kind?: WorkerAgentMessageKind): WorkerAgentMessage[] {\n\t\treturn this.read()\n\t\t\t.messages.filter(\n\t\t\t\t(message) => message.deliveredAt === undefined && (kind === undefined || message.kind === kind),\n\t\t\t)\n\t\t\t.map((message) => structuredClone(message));\n\t}\n\n\tacknowledgeDelivered(messageId: string): void {\n\t\tconst normalized = messageId.trim();\n\t\tif (!normalized) throw new TypeError(\"A worker control message id is required.\");\n\t\tlet changed = false;\n\t\tthis.update((state) => {\n\t\t\tconst messages = state.messages.filter((message) => {\n\t\t\t\tif (message.messageId !== normalized) return true;\n\t\t\t\tchanged = true;\n\t\t\t\treturn false;\n\t\t\t});\n\t\t\treturn changed ? { ...state, messages } : state;\n\t\t});\n\t\tif (changed) this.notify();\n\t}\n\n\tsubscribe(listener: () => void): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => this.listeners.delete(listener);\n\t}\n\n\tprivate notify(): void {\n\t\tfor (const listener of this.listeners) listener();\n\t}\n\n\tprivate read(): WorkerAgentMailboxState {\n\t\tif (!existsSync(this.file)) {\n\t\t\treturn { version: 1, parentSessionId: this.parentSessionId, agentId: this.agentId, messages: [] };\n\t\t}\n\t\treturn parseState(\n\t\t\treadBoundedTextFileSync(this.file, MAX_MAILBOX_BYTES, \"Worker agent mailbox durable size bound\"),\n\t\t\tthis.parentSessionId,\n\t\t\tthis.agentId,\n\t\t);\n\t}\n\n\tprivate update(mutator: (state: WorkerAgentMailboxState) => WorkerAgentMailboxState): void {\n\t\twithFileLockSync(this.file, () => {\n\t\t\tconst state = this.read();\n\t\t\tconst next = mutator(state);\n\t\t\tif (next.messages.length > MAX_MAILBOX_MESSAGES || encodedStateBytes(next) > MAX_MAILBOX_BYTES) {\n\t\t\t\tthrow new Error(\"Worker agent mailbox exceeds its durable size bound.\");\n\t\t\t}\n\t\t\tif (JSON.stringify(next) !== JSON.stringify(state))\n\t\t\t\twriteFileAtomicSync(this.file, `${JSON.stringify(next)}\\n`, { mode: 0o600 });\n\t\t});\n\t}\n}\n"]}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { ThinkingLevel } from "@caupulican/pi-agent-core";
|
|
2
|
+
import type { Api, Model, Usage } from "@caupulican/pi-ai";
|
|
3
|
+
import type { IsolatedCompletionOptions, IsolatedCompletionResult } from "../agent-session-contracts.ts";
|
|
4
|
+
import type { WorkerRequest } from "../autonomy/contracts.ts";
|
|
5
|
+
import type { LaneToolSurface } from "../autonomy/lane-tool-surface.ts";
|
|
6
|
+
import type { ModelCapabilityProfile } from "../model-capability.ts";
|
|
7
|
+
import type { AttemptUsageSnapshot, ExecutionGrant } from "../orchestration/contracts.ts";
|
|
8
|
+
import type { StartedDelegationAttempt } from "../orchestration/delegation-ledger.ts";
|
|
9
|
+
import { WorkerActionJournal } from "./worker-action-journal.ts";
|
|
10
|
+
import type { AppliedActionsReport, WorkerAction } from "./worker-actions.ts";
|
|
11
|
+
import type { WorkerAgentControlCoordinator } from "./worker-agent-control-coordinator.ts";
|
|
12
|
+
import type { WorkerConversation, WorkerConversationRetentionPolicy } from "./worker-conversation-store.ts";
|
|
13
|
+
import type { WorkerExecutionPlan } from "./worker-execution-policy.ts";
|
|
14
|
+
import type { WorkerLifecycle } from "./worker-lifecycle.ts";
|
|
15
|
+
import { type WorkerRunOutcome } from "./worker-runner.ts";
|
|
16
|
+
export interface RecoveredWorkerTerminalCompletion {
|
|
17
|
+
text: string;
|
|
18
|
+
usage: Usage;
|
|
19
|
+
stopReason: string;
|
|
20
|
+
}
|
|
21
|
+
/** The live mutable state that must be visible to session disposal before provider work yields. */
|
|
22
|
+
export interface WorkerAttemptExecutionLedger {
|
|
23
|
+
changedFiles: Set<string>;
|
|
24
|
+
getUsage(): AttemptUsageSnapshot;
|
|
25
|
+
}
|
|
26
|
+
export interface WorkerAttemptExecutionResult {
|
|
27
|
+
rawOutcome: WorkerRunOutcome;
|
|
28
|
+
usage: AttemptUsageSnapshot;
|
|
29
|
+
changedFiles: readonly string[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The provider/tool-loop portion of a prepared worker attempt.
|
|
33
|
+
*
|
|
34
|
+
* Admission, durable leasing, grant compilation, terminalization, notification, verification, and
|
|
35
|
+
* scheduling remain outside this boundary. This unit owns only the ordered child conversation:
|
|
36
|
+
* persist assistant tool requests before execution, append messages before mailbox acknowledgements,
|
|
37
|
+
* checkpoint cumulative usage before later boundaries, and compact only the provider projection.
|
|
38
|
+
*/
|
|
39
|
+
export interface WorkerAttemptExecutorOptions {
|
|
40
|
+
request: WorkerRequest;
|
|
41
|
+
grant: ExecutionGrant;
|
|
42
|
+
executionPlan: WorkerExecutionPlan;
|
|
43
|
+
toolSurface: LaneToolSurface;
|
|
44
|
+
conversation: WorkerConversation;
|
|
45
|
+
lifecycle: Pick<WorkerLifecycle, "checkpoint">;
|
|
46
|
+
laneId: string;
|
|
47
|
+
agentId: string;
|
|
48
|
+
durableHandle: StartedDelegationAttempt;
|
|
49
|
+
parentSessionId: string;
|
|
50
|
+
agentDir: string;
|
|
51
|
+
cwd: string;
|
|
52
|
+
model: Model<Api>;
|
|
53
|
+
thinkingLevel?: ThinkingLevel;
|
|
54
|
+
laneCapability: Pick<ModelCapabilityProfile, "laneMaxOutputTokens">;
|
|
55
|
+
soul?: string;
|
|
56
|
+
workerResourceSystemPrompt: string;
|
|
57
|
+
initialUsage: AttemptUsageSnapshot;
|
|
58
|
+
hasPersistedUsageCheckpoint: boolean;
|
|
59
|
+
usageReportId: string;
|
|
60
|
+
processCapable: boolean;
|
|
61
|
+
verificationSubjectTaskId?: string;
|
|
62
|
+
recoveredTerminal?: RecoveredWorkerTerminalCompletion;
|
|
63
|
+
retentionPolicy?: WorkerConversationRetentionPolicy;
|
|
64
|
+
signal?: AbortSignal;
|
|
65
|
+
runIsolatedCompletion(options: IsolatedCompletionOptions): Promise<IsolatedCompletionResult>;
|
|
66
|
+
agentControl: Pick<WorkerAgentControlCoordinator, "acknowledgeMailboxMessage" | "mailboxMessagesForConversation">;
|
|
67
|
+
applyActions?(actions: readonly WorkerAction[], actionJournal?: WorkerActionJournal): AppliedActionsReport;
|
|
68
|
+
warn(message: string): void;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Constructs one execution exactly once. The caller registers {@link ledger} before calling
|
|
72
|
+
* {@link run}, allowing synchronous disposal to observe mutations and cumulative usage while the
|
|
73
|
+
* provider/tool loop is suspended.
|
|
74
|
+
*/
|
|
75
|
+
export declare function createWorkerAttemptExecutor(options: WorkerAttemptExecutorOptions): {
|
|
76
|
+
ledger: WorkerAttemptExecutionLedger;
|
|
77
|
+
checkpointUsage(summary: string): AttemptUsageSnapshot;
|
|
78
|
+
run(): Promise<WorkerAttemptExecutionResult>;
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=worker-attempt-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-attempt-executor.d.ts","sourceRoot":"","sources":["../../../src/core/delegation/worker-attempt-executor.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\nimport type { AgentMessage, ThinkingLevel } from \"@caupulican/pi-agent-core\";\nimport { addUsage, createEmptyUsage, sanitizeToolFailureContext } from \"@caupulican/pi-agent-core\";\nimport { compact } from \"@caupulican/pi-agent-core/node\";\nimport type { Api, AssistantMessage, Message, Model, Usage } from \"@caupulican/pi-ai\";\nimport type { IsolatedCompletionOptions, IsolatedCompletionResult } from \"../agent-session-contracts.ts\";\nimport type { WorkerRequest } from \"../autonomy/contracts.ts\";\nimport type { LaneToolSurface } from \"../autonomy/lane-tool-surface.ts\";\nimport { safeRealpathSync } from \"../autonomy/path-scope.ts\";\nimport { composeSubagentSystemPrompt } from \"../autonomy/subagent-prompt.ts\";\nimport type { ModelCapabilityProfile } from \"../model-capability.ts\";\nimport {\n\tattemptUsageFromGatewayUsage,\n\tEMPTY_ATTEMPT_USAGE,\n\tremainingTokenBudget,\n} from \"../orchestration/attempt-usage.ts\";\nimport type { AttemptUsageSnapshot, ExecutionGrant } from \"../orchestration/contracts.ts\";\nimport type { StartedDelegationAttempt } from \"../orchestration/delegation-ledger.ts\";\nimport { WorkerActionJournal } from \"./worker-action-journal.ts\";\nimport type { AppliedActionsReport, WorkerAction } from \"./worker-actions.ts\";\nimport type { WorkerAgentControlCoordinator } from \"./worker-agent-control-coordinator.ts\";\nimport type { WorkerConversation, WorkerConversationRetentionPolicy } from \"./worker-conversation-store.ts\";\nimport type { WorkerExecutionPlan } from \"./worker-execution-policy.ts\";\nimport type { WorkerLifecycle } from \"./worker-lifecycle.ts\";\nimport { runWorker, type WorkerRunOutcome } from \"./worker-runner.ts\";\n\nexport interface RecoveredWorkerTerminalCompletion {\n\ttext: string;\n\tusage: Usage;\n\tstopReason: string;\n}\n\n/** The live mutable state that must be visible to session disposal before provider work yields. */\nexport interface WorkerAttemptExecutionLedger {\n\tchangedFiles: Set<string>;\n\tgetUsage(): AttemptUsageSnapshot;\n}\n\nexport interface WorkerAttemptExecutionResult {\n\trawOutcome: WorkerRunOutcome;\n\tusage: AttemptUsageSnapshot;\n\tchangedFiles: readonly string[];\n}\n\n/**\n * The provider/tool-loop portion of a prepared worker attempt.\n *\n * Admission, durable leasing, grant compilation, terminalization, notification, verification, and\n * scheduling remain outside this boundary. This unit owns only the ordered child conversation:\n * persist assistant tool requests before execution, append messages before mailbox acknowledgements,\n * checkpoint cumulative usage before later boundaries, and compact only the provider projection.\n */\nexport interface WorkerAttemptExecutorOptions {\n\trequest: WorkerRequest;\n\tgrant: ExecutionGrant;\n\texecutionPlan: WorkerExecutionPlan;\n\ttoolSurface: LaneToolSurface;\n\tconversation: WorkerConversation;\n\tlifecycle: Pick<WorkerLifecycle, \"checkpoint\">;\n\tlaneId: string;\n\tagentId: string;\n\tdurableHandle: StartedDelegationAttempt;\n\tparentSessionId: string;\n\tagentDir: string;\n\tcwd: string;\n\tmodel: Model<Api>;\n\tthinkingLevel?: ThinkingLevel;\n\tlaneCapability: Pick<ModelCapabilityProfile, \"laneMaxOutputTokens\">;\n\tsoul?: string;\n\tworkerResourceSystemPrompt: string;\n\tinitialUsage: AttemptUsageSnapshot;\n\thasPersistedUsageCheckpoint: boolean;\n\tusageReportId: string;\n\tprocessCapable: boolean;\n\tverificationSubjectTaskId?: string;\n\trecoveredTerminal?: RecoveredWorkerTerminalCompletion;\n\tretentionPolicy?: WorkerConversationRetentionPolicy;\n\tsignal?: AbortSignal;\n\trunIsolatedCompletion(options: IsolatedCompletionOptions): Promise<IsolatedCompletionResult>;\n\tagentControl: Pick<WorkerAgentControlCoordinator, \"acknowledgeMailboxMessage\" | \"mailboxMessagesForConversation\">;\n\tapplyActions?(actions: readonly WorkerAction[], actionJournal?: WorkerActionJournal): AppliedActionsReport;\n\twarn(message: string): void;\n}\n\nfunction recordAssistantUsage(surface: LaneToolSurface, message: Extract<Message, { role: \"assistant\" }>): void {\n\tsurface.gateway?.recordUsage({\n\t\tinputTokens: message.usage.input,\n\t\toutputTokens: message.usage.output,\n\t\tcacheReadTokens: message.usage.cacheRead,\n\t\tcacheWriteTokens: message.usage.cacheWrite,\n\t\ttotalTokens: message.usage.totalTokens,\n\t\tcostUsd: message.usage.cost.total,\n\t});\n}\n\nfunction isToolRequest(message: Message): boolean {\n\treturn message.role === \"assistant\" && message.content.some((content) => content.type === \"toolCall\");\n}\n\n/**\n * Constructs one execution exactly once. The caller registers {@link ledger} before calling\n * {@link run}, allowing synchronous disposal to observe mutations and cumulative usage while the\n * provider/tool loop is suspended.\n */\nexport function createWorkerAttemptExecutor(options: WorkerAttemptExecutorOptions): {\n\tledger: WorkerAttemptExecutionLedger;\n\tcheckpointUsage(summary: string): AttemptUsageSnapshot;\n\trun(): Promise<WorkerAttemptExecutionResult>;\n} {\n\tconst changedFiles = new Set(options.conversation.getChangedFiles(options.durableHandle.attemptId));\n\tconst toolIssues = new Set<string>();\n\tconst recordChangedFile = (filePath: string): void => {\n\t\tchangedFiles.add(filePath);\n\t\ttry {\n\t\t\toptions.conversation.recordChangedFile(options.durableHandle.attemptId, filePath);\n\t\t} catch (error) {\n\t\t\ttoolIssues.add(\"worker changed-file progress could not be persisted; parent review is required\");\n\t\t\toptions.warn(\n\t\t\t\t`Worker changed-file progress persistence failed: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t);\n\t\t}\n\t};\n\tconst actionJournal = options.request.envelope.capabilities.includes(\"filesystem.write\")\n\t\t? new WorkerActionJournal({\n\t\t\t\tagentDir: options.agentDir,\n\t\t\t\tparentSessionId: options.parentSessionId,\n\t\t\t\ttaskId: options.durableHandle.taskId,\n\t\t\t\tattemptId: options.durableHandle.attemptId,\n\t\t\t\tfencingToken: options.durableHandle.fencingToken,\n\t\t\t})\n\t\t: undefined;\n\tlet providerContextCompacted = options.conversation.hasProviderCompaction();\n\tlet retentionWarningEmitted = false;\n\tlet firstMailboxPoll = true;\n\tlet ran = false;\n\n\tconst currentUsage = (): AttemptUsageSnapshot =>\n\t\tattemptUsageFromGatewayUsage(\n\t\t\toptions.toolSurface.gateway?.getUsage() ?? {\n\t\t\t\t...EMPTY_ATTEMPT_USAGE,\n\t\t\t\twallClockMs: options.initialUsage.activeWallClockMs,\n\t\t\t},\n\t\t);\n\tconst checkpointUsage = (summary: string): AttemptUsageSnapshot => {\n\t\tconst usage = currentUsage();\n\t\toptions.lifecycle.checkpoint(options.laneId, { summary, usage });\n\t\treturn usage;\n\t};\n\tlet failedCompactionUsage: Usage | undefined;\n\tconst retentionPolicy = options.retentionPolicy && {\n\t\t...options.retentionPolicy,\n\t\tgenerateVerifiedCompaction: async (preparation: Parameters<typeof compact>[0]) => {\n\t\t\tconst compactionUsage = createEmptyUsage();\n\t\t\tfailedCompactionUsage = compactionUsage;\n\t\t\treturn compact(\n\t\t\t\tpreparation,\n\t\t\t\toptions.model,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\toptions.signal,\n\t\t\t\toptions.thinkingLevel,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\t{\n\t\t\t\t\tcompletion: async (model, context, requestOptions): Promise<AssistantMessage> => {\n\t\t\t\t\t\tif (model.provider !== options.model.provider || model.id !== options.model.id) {\n\t\t\t\t\t\t\tthrow new Error(\"Worker compaction attempted to select a model outside the lane binding.\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\toptions.toolSurface.gateway?.assertBudgetAvailable(\"worker_compaction_provider_completion\");\n\t\t\t\t\t\tconst remainingTokens = remainingTokenBudget(options.grant.budget.maxTokens, currentUsage());\n\t\t\t\t\t\tif (remainingTokens !== undefined && remainingTokens <= 0) {\n\t\t\t\t\t\t\tthrow new Error(\"Worker token budget exhausted before compaction provider completion.\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst requestedMaxTokens = requestOptions.maxTokens;\n\t\t\t\t\t\tconst configuredMaxTokens =\n\t\t\t\t\t\t\ttypeof requestedMaxTokens === \"number\" &&\n\t\t\t\t\t\t\tNumber.isSafeInteger(requestedMaxTokens) &&\n\t\t\t\t\t\t\trequestedMaxTokens > 0\n\t\t\t\t\t\t\t\t? requestedMaxTokens\n\t\t\t\t\t\t\t\t: options.laneCapability.laneMaxOutputTokens;\n\t\t\t\t\t\tconst maxTokens = Math.min(configuredMaxTokens, remainingTokens ?? configuredMaxTokens);\n\t\t\t\t\t\tif (!Number.isSafeInteger(maxTokens) || maxTokens <= 0) {\n\t\t\t\t\t\t\tthrow new Error(\"Worker compaction provider completion has no valid remaining token budget.\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst completion = await options.runIsolatedCompletion({\n\t\t\t\t\t\t\tsystemPrompt: context.systemPrompt ?? \"\",\n\t\t\t\t\t\t\tmessages: context.messages,\n\t\t\t\t\t\t\tmodel: options.model,\n\t\t\t\t\t\t\tthinkingLevel: options.thinkingLevel,\n\t\t\t\t\t\t\tmaxTokens,\n\t\t\t\t\t\t\trequestPreflight: async () => {\n\t\t\t\t\t\t\t\toptions.toolSurface.gateway?.assertBudgetAvailable(\"worker_compaction_provider_completion\");\n\t\t\t\t\t\t\t\tconst requestRemainingTokens = remainingTokenBudget(\n\t\t\t\t\t\t\t\t\toptions.grant.budget.maxTokens,\n\t\t\t\t\t\t\t\t\tcurrentUsage(),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tif (requestRemainingTokens !== undefined && requestRemainingTokens <= 0) {\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Worker token budget exhausted before compaction provider completion.\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\tmaxTokens: Math.min(maxTokens, requestRemainingTokens ?? maxTokens),\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tsignal: requestOptions.signal ?? options.signal,\n\t\t\t\t\t\t\tcacheRetention: \"none\",\n\t\t\t\t\t\t\tlaneKind: \"worker-compaction\",\n\t\t\t\t\t\t});\n\t\t\t\t\t\taddUsage(compactionUsage, completion.usage);\n\t\t\t\t\t\tconst response: AssistantMessage = {\n\t\t\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\t\t\tcontent: completion.text ? [{ type: \"text\", text: completion.text }] : [],\n\t\t\t\t\t\t\tapi: options.model.api,\n\t\t\t\t\t\t\tprovider: options.model.provider,\n\t\t\t\t\t\t\tmodel: options.model.id,\n\t\t\t\t\t\t\tusage: completion.usage,\n\t\t\t\t\t\t\tstopReason: completion.stopReason,\n\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t\t...(completion.stopReason === \"error\"\n\t\t\t\t\t\t\t\t? { errorMessage: completion.text || \"Worker compaction provider request failed.\" }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t};\n\t\t\t\t\t\trecordAssistantUsage(options.toolSurface, response);\n\t\t\t\t\t\tcheckpointUsage(\"Persisted worker compaction provider usage before verification.\");\n\t\t\t\t\t\treturn response;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tgetFailedCompactionUsage: () => failedCompactionUsage,\n\t};\n\tconst ledger: WorkerAttemptExecutionLedger = {\n\t\tchangedFiles,\n\t\tgetUsage: currentUsage,\n\t};\n\n\treturn {\n\t\tledger,\n\t\tcheckpointUsage,\n\t\tasync run(): Promise<WorkerAttemptExecutionResult> {\n\t\t\tif (ran) throw new Error(\"A worker attempt executor may run only once.\");\n\t\t\tran = true;\n\t\t\tif (!options.hasPersistedUsageCheckpoint) {\n\t\t\t\tcheckpointUsage(\"Persisted deterministic cumulative usage baseline for the durable worker transcript.\");\n\t\t\t}\n\t\t\tconst rawOutcome = await runWorker({\n\t\t\t\trequest: options.request,\n\t\t\t\tmaxUsd: options.grant.budget.maxCostUsd,\n\t\t\t\tmaxWallClockMs: options.grant.budget.maxWallClockMs ?? 0,\n\t\t\t\tusageReportId: options.usageReportId,\n\t\t\t\tgetChangedFiles: () => [...changedFiles],\n\t\t\t\tsignal: options.signal,\n\t\t\t\tcwd: options.cwd,\n\t\t\t\tprocessCapable: options.processCapable,\n\t\t\t\t...(options.verificationSubjectTaskId\n\t\t\t\t\t? { verificationSubjectTaskId: options.verificationSubjectTaskId }\n\t\t\t\t\t: {}),\n\t\t\t\t...(options.applyActions\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tapplyActions: (actions: readonly WorkerAction[]) => {\n\t\t\t\t\t\t\t\tconst report = options.applyActions!(actions, actionJournal);\n\t\t\t\t\t\t\t\tfor (const filePath of report.changedFiles) recordChangedFile(filePath);\n\t\t\t\t\t\t\t\treturn report;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\tcomplete: async ({ systemPrompt, userPrompt, signal }) => {\n\t\t\t\t\tif (options.recoveredTerminal) {\n\t\t\t\t\t\tcheckpointUsage(\"Reused the persisted terminal worker assistant response after recovery.\");\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttext: options.recoveredTerminal.text,\n\t\t\t\t\t\t\tcostUsd: options.initialUsage.costUsd,\n\t\t\t\t\t\t\tstopReason: options.recoveredTerminal.stopReason,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tconst persistedToolAssistantIds = new Set<string>();\n\t\t\t\t\tconst pendingToolAssistants = new Map<string, AssistantMessage>();\n\t\t\t\t\tconst persistToolRequest = (message: AssistantMessage): void => {\n\t\t\t\t\t\tconst toolCallIds = message.content.flatMap((content) =>\n\t\t\t\t\t\t\tcontent.type === \"toolCall\" ? [content.id] : [],\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (toolCallIds.length === 0 || toolCallIds.every((id) => persistedToolAssistantIds.has(id))) return;\n\t\t\t\t\t\trecordAssistantUsage(options.toolSurface, message);\n\t\t\t\t\t\toptions.conversation.appendMessage(message);\n\t\t\t\t\t\tfor (const id of toolCallIds) {\n\t\t\t\t\t\t\tpersistedToolAssistantIds.add(id);\n\t\t\t\t\t\t\tpendingToolAssistants.delete(id);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcheckpointUsage(\"Persisted worker assistant tool request and its cumulative provider usage.\");\n\t\t\t\t\t};\n\t\t\t\t\toptions.toolSurface.gateway?.assertBudgetAvailable(\"worker_provider_completion\");\n\t\t\t\t\tconst remainingTokens = remainingTokenBudget(options.grant.budget.maxTokens, currentUsage());\n\t\t\t\t\tif (remainingTokens !== undefined && remainingTokens <= 0) {\n\t\t\t\t\t\tthrow new Error(\"Worker token budget exhausted before provider completion.\");\n\t\t\t\t\t}\n\t\t\t\t\tlet history = options.conversation.getProviderMessages();\n\t\t\t\t\tif (history.length === 0) {\n\t\t\t\t\t\toptions.conversation.appendMessage({\n\t\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: userPrompt }],\n\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t});\n\t\t\t\t\t\thistory = options.conversation.getProviderMessages();\n\t\t\t\t\t}\n\t\t\t\t\tconst completion = await options.runIsolatedCompletion({\n\t\t\t\t\t\tsystemPrompt: composeSubagentSystemPrompt({\n\t\t\t\t\t\t\tsoul: options.soul,\n\t\t\t\t\t\t\trolePrompt: [systemPrompt, options.workerResourceSystemPrompt].filter(Boolean).join(\"\\n\\n\"),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\thistory,\n\t\t\t\t\t\tmessages: [],\n\t\t\t\t\t\tmodel: options.model,\n\t\t\t\t\t\tthinkingLevel: options.thinkingLevel,\n\t\t\t\t\t\tmaxTokens: Math.min(\n\t\t\t\t\t\t\toptions.laneCapability.laneMaxOutputTokens,\n\t\t\t\t\t\t\tremainingTokens ?? Number.POSITIVE_INFINITY,\n\t\t\t\t\t\t),\n\t\t\t\t\t\ttools: options.toolSurface.tools,\n\t\t\t\t\t\trequestPreflight: async () => {\n\t\t\t\t\t\t\toptions.toolSurface.gateway?.assertBudgetAvailable(\"worker_provider_completion\");\n\t\t\t\t\t\t\tconst requestRemainingTokens = remainingTokenBudget(\n\t\t\t\t\t\t\t\toptions.grant.budget.maxTokens,\n\t\t\t\t\t\t\t\tcurrentUsage(),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (requestRemainingTokens !== undefined && requestRemainingTokens <= 0) {\n\t\t\t\t\t\t\t\tthrow new Error(\"Worker token budget exhausted before provider completion.\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tmaxTokens: Math.min(\n\t\t\t\t\t\t\t\t\toptions.laneCapability.laneMaxOutputTokens,\n\t\t\t\t\t\t\t\t\trequestRemainingTokens ?? Number.POSITIVE_INFINITY,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbeforeToolCall: async (context, toolSignal) => {\n\t\t\t\t\t\t\tpersistToolRequest(context.assistantMessage);\n\t\t\t\t\t\t\tconst decision = await options.toolSurface.beforeToolCall(context, toolSignal);\n\t\t\t\t\t\t\tif (decision?.block) {\n\t\t\t\t\t\t\t\ttoolIssues.add(`${context.toolCall.name} blocked: ${decision.reason ?? \"capability denied\"}`);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcheckpointUsage(`Authorized worker tool '${context.toolCall.name}' under its durable grant.`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn decision;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tafterToolCall: async ({ toolCall, args, isError }) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t(toolCall.name === \"write\" || toolCall.name === \"edit\") &&\n\t\t\t\t\t\t\t\targs &&\n\t\t\t\t\t\t\t\ttypeof args === \"object\" &&\n\t\t\t\t\t\t\t\t!Array.isArray(args)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tconst rawPath = (args as Record<string, unknown>).path;\n\t\t\t\t\t\t\t\tif (typeof rawPath === \"string\" && rawPath.length > 0) {\n\t\t\t\t\t\t\t\t\tconst absolutePath = path.isAbsolute(rawPath)\n\t\t\t\t\t\t\t\t\t\t? path.resolve(rawPath)\n\t\t\t\t\t\t\t\t\t\t: path.resolve(options.cwd, rawPath);\n\t\t\t\t\t\t\t\t\tlet canonicalPath = absolutePath;\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tcanonicalPath = safeRealpathSync(absolutePath);\n\t\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t\t// The operation entered execution; retain its lexical target if canonicalization failed.\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\trecordChangedFile(path.relative(options.cwd, canonicalPath).split(path.sep).join(\"/\"));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (isError) toolIssues.add(`${toolCall.name} failed during isolated execution`);\n\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonMessage: (message) => {\n\t\t\t\t\t\t\tif (message.role === \"assistant\" && isToolRequest(message)) {\n\t\t\t\t\t\t\t\t// Known calls are normalized before beforeToolCall and persist from that hook.\n\t\t\t\t\t\t\t\t// Retain the request only so immediate unknown/malformed results can close the\n\t\t\t\t\t\t\t\t// transcript without freezing pre-repair arguments into durable history.\n\t\t\t\t\t\t\t\tfor (const content of message.content) {\n\t\t\t\t\t\t\t\t\tif (content.type === \"toolCall\") pendingToolAssistants.set(content.id, message);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (message.role === \"toolResult\" && !persistedToolAssistantIds.has(message.toolCallId)) {\n\t\t\t\t\t\t\t\tconst pending = pendingToolAssistants.get(message.toolCallId);\n\t\t\t\t\t\t\t\tif (pending) persistToolRequest(pending);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (message.role === \"assistant\") recordAssistantUsage(options.toolSurface, message);\n\t\t\t\t\t\t\toptions.conversation.appendMessage(message);\n\t\t\t\t\t\t\toptions.agentControl.acknowledgeMailboxMessage(options.agentId, message);\n\t\t\t\t\t\t\tif (message.role === \"assistant\") {\n\t\t\t\t\t\t\t\tcheckpointUsage(\"Persisted worker assistant response and its cumulative provider usage.\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (message.role === \"toolResult\")\n\t\t\t\t\t\t\t\tcheckpointUsage(`Persisted worker tool result '${message.toolCallId}'.`);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tgetSteeringMessages: async (): Promise<AgentMessage[]> => {\n\t\t\t\t\t\t\tconst includeFollowUp = firstMailboxPoll;\n\t\t\t\t\t\t\tfirstMailboxPoll = false;\n\t\t\t\t\t\t\treturn options.agentControl.mailboxMessagesForConversation(\n\t\t\t\t\t\t\t\toptions.agentId,\n\t\t\t\t\t\t\t\toptions.conversation,\n\t\t\t\t\t\t\t\tincludeFollowUp,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tgetFollowUpMessages: async (): Promise<AgentMessage[]> =>\n\t\t\t\t\t\t\toptions.agentControl.mailboxMessagesForConversation(options.agentId, options.conversation, true),\n\t\t\t\t\t\t...(retentionPolicy\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\ttransformContext: async (messages: AgentMessage[]) => {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tconst retained = await options.conversation.compactProviderContext(\n\t\t\t\t\t\t\t\t\t\t\t\tretentionPolicy,\n\t\t\t\t\t\t\t\t\t\t\t\toptions.signal,\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\t\tretained.status === \"compacted_verified\" ||\n\t\t\t\t\t\t\t\t\t\t\t\tretained.status === \"compacted_deterministic\"\n\t\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t\tproviderContextCompacted = true;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\t\tretained.contextUsage.tokens > retentionPolicy.maxContextTokens &&\n\t\t\t\t\t\t\t\t\t\t\t\t!retentionWarningEmitted\n\t\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t\tretentionWarningEmitted = true;\n\t\t\t\t\t\t\t\t\t\t\t\toptions.warn(\n\t\t\t\t\t\t\t\t\t\t\t\t\t`Worker ${options.laneId} has one retained turn larger than its context policy; provider overflow recovery may be required.`,\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\t\tretained.status !== \"compacted_verified\" &&\n\t\t\t\t\t\t\t\t\t\t\t\tretained.status !== \"compacted_deterministic\"\n\t\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t\treturn messages;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\treturn sanitizeToolFailureContext(retained.context.messages, \"\").messages;\n\t\t\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\t\t\tif (!retentionWarningEmitted) {\n\t\t\t\t\t\t\t\t\t\t\t\tretentionWarningEmitted = true;\n\t\t\t\t\t\t\t\t\t\t\t\toptions.warn(\n\t\t\t\t\t\t\t\t\t\t\t\t\t`Worker context retention failed: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\treturn messages;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t\tcacheRetention: \"short\",\n\t\t\t\t\t\tlaneKind: \"worker\",\n\t\t\t\t\t});\n\t\t\t\t\tif (!providerContextCompacted) {\n\t\t\t\t\t\toptions.conversation.commitTranscript(\n\t\t\t\t\t\t\tcompletion.messages ?? options.conversation.getProviderMessages(),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tcheckpointUsage(\n\t\t\t\t\t\t`Persisted worker conversation through ${options.conversation.getProviderContext().messages.length} messages.`,\n\t\t\t\t\t);\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttext: completion.text,\n\t\t\t\t\t\tcostUsd: completion.usage.cost.total,\n\t\t\t\t\t\tstopReason: String(completion.stopReason),\n\t\t\t\t\t\tchangedFiles: [...changedFiles],\n\t\t\t\t\t\tblockers: [...toolIssues],\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst usage = checkpointUsage(\"Persisted final cumulative worker usage before terminal result.\");\n\t\t\treturn { rawOutcome, usage, changedFiles: [...changedFiles] };\n\t\t},\n\t};\n}\n"]}
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { addUsage, createEmptyUsage, sanitizeToolFailureContext } from "@caupulican/pi-agent-core";
|
|
3
|
+
import { compact } from "@caupulican/pi-agent-core/node";
|
|
4
|
+
import { safeRealpathSync } from "../autonomy/path-scope.js";
|
|
5
|
+
import { composeSubagentSystemPrompt } from "../autonomy/subagent-prompt.js";
|
|
6
|
+
import { attemptUsageFromGatewayUsage, EMPTY_ATTEMPT_USAGE, remainingTokenBudget, } from "../orchestration/attempt-usage.js";
|
|
7
|
+
import { WorkerActionJournal } from "./worker-action-journal.js";
|
|
8
|
+
import { runWorker } from "./worker-runner.js";
|
|
9
|
+
function recordAssistantUsage(surface, message) {
|
|
10
|
+
surface.gateway?.recordUsage({
|
|
11
|
+
inputTokens: message.usage.input,
|
|
12
|
+
outputTokens: message.usage.output,
|
|
13
|
+
cacheReadTokens: message.usage.cacheRead,
|
|
14
|
+
cacheWriteTokens: message.usage.cacheWrite,
|
|
15
|
+
totalTokens: message.usage.totalTokens,
|
|
16
|
+
costUsd: message.usage.cost.total,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function isToolRequest(message) {
|
|
20
|
+
return message.role === "assistant" && message.content.some((content) => content.type === "toolCall");
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Constructs one execution exactly once. The caller registers {@link ledger} before calling
|
|
24
|
+
* {@link run}, allowing synchronous disposal to observe mutations and cumulative usage while the
|
|
25
|
+
* provider/tool loop is suspended.
|
|
26
|
+
*/
|
|
27
|
+
export function createWorkerAttemptExecutor(options) {
|
|
28
|
+
const changedFiles = new Set(options.conversation.getChangedFiles(options.durableHandle.attemptId));
|
|
29
|
+
const toolIssues = new Set();
|
|
30
|
+
const recordChangedFile = (filePath) => {
|
|
31
|
+
changedFiles.add(filePath);
|
|
32
|
+
try {
|
|
33
|
+
options.conversation.recordChangedFile(options.durableHandle.attemptId, filePath);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
toolIssues.add("worker changed-file progress could not be persisted; parent review is required");
|
|
37
|
+
options.warn(`Worker changed-file progress persistence failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const actionJournal = options.request.envelope.capabilities.includes("filesystem.write")
|
|
41
|
+
? new WorkerActionJournal({
|
|
42
|
+
agentDir: options.agentDir,
|
|
43
|
+
parentSessionId: options.parentSessionId,
|
|
44
|
+
taskId: options.durableHandle.taskId,
|
|
45
|
+
attemptId: options.durableHandle.attemptId,
|
|
46
|
+
fencingToken: options.durableHandle.fencingToken,
|
|
47
|
+
})
|
|
48
|
+
: undefined;
|
|
49
|
+
let providerContextCompacted = options.conversation.hasProviderCompaction();
|
|
50
|
+
let retentionWarningEmitted = false;
|
|
51
|
+
let firstMailboxPoll = true;
|
|
52
|
+
let ran = false;
|
|
53
|
+
const currentUsage = () => attemptUsageFromGatewayUsage(options.toolSurface.gateway?.getUsage() ?? {
|
|
54
|
+
...EMPTY_ATTEMPT_USAGE,
|
|
55
|
+
wallClockMs: options.initialUsage.activeWallClockMs,
|
|
56
|
+
});
|
|
57
|
+
const checkpointUsage = (summary) => {
|
|
58
|
+
const usage = currentUsage();
|
|
59
|
+
options.lifecycle.checkpoint(options.laneId, { summary, usage });
|
|
60
|
+
return usage;
|
|
61
|
+
};
|
|
62
|
+
let failedCompactionUsage;
|
|
63
|
+
const retentionPolicy = options.retentionPolicy && {
|
|
64
|
+
...options.retentionPolicy,
|
|
65
|
+
generateVerifiedCompaction: async (preparation) => {
|
|
66
|
+
const compactionUsage = createEmptyUsage();
|
|
67
|
+
failedCompactionUsage = compactionUsage;
|
|
68
|
+
return compact(preparation, options.model, undefined, undefined, undefined, options.signal, options.thinkingLevel, undefined, undefined, {
|
|
69
|
+
completion: async (model, context, requestOptions) => {
|
|
70
|
+
if (model.provider !== options.model.provider || model.id !== options.model.id) {
|
|
71
|
+
throw new Error("Worker compaction attempted to select a model outside the lane binding.");
|
|
72
|
+
}
|
|
73
|
+
options.toolSurface.gateway?.assertBudgetAvailable("worker_compaction_provider_completion");
|
|
74
|
+
const remainingTokens = remainingTokenBudget(options.grant.budget.maxTokens, currentUsage());
|
|
75
|
+
if (remainingTokens !== undefined && remainingTokens <= 0) {
|
|
76
|
+
throw new Error("Worker token budget exhausted before compaction provider completion.");
|
|
77
|
+
}
|
|
78
|
+
const requestedMaxTokens = requestOptions.maxTokens;
|
|
79
|
+
const configuredMaxTokens = typeof requestedMaxTokens === "number" &&
|
|
80
|
+
Number.isSafeInteger(requestedMaxTokens) &&
|
|
81
|
+
requestedMaxTokens > 0
|
|
82
|
+
? requestedMaxTokens
|
|
83
|
+
: options.laneCapability.laneMaxOutputTokens;
|
|
84
|
+
const maxTokens = Math.min(configuredMaxTokens, remainingTokens ?? configuredMaxTokens);
|
|
85
|
+
if (!Number.isSafeInteger(maxTokens) || maxTokens <= 0) {
|
|
86
|
+
throw new Error("Worker compaction provider completion has no valid remaining token budget.");
|
|
87
|
+
}
|
|
88
|
+
const completion = await options.runIsolatedCompletion({
|
|
89
|
+
systemPrompt: context.systemPrompt ?? "",
|
|
90
|
+
messages: context.messages,
|
|
91
|
+
model: options.model,
|
|
92
|
+
thinkingLevel: options.thinkingLevel,
|
|
93
|
+
maxTokens,
|
|
94
|
+
requestPreflight: async () => {
|
|
95
|
+
options.toolSurface.gateway?.assertBudgetAvailable("worker_compaction_provider_completion");
|
|
96
|
+
const requestRemainingTokens = remainingTokenBudget(options.grant.budget.maxTokens, currentUsage());
|
|
97
|
+
if (requestRemainingTokens !== undefined && requestRemainingTokens <= 0) {
|
|
98
|
+
throw new Error("Worker token budget exhausted before compaction provider completion.");
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
maxTokens: Math.min(maxTokens, requestRemainingTokens ?? maxTokens),
|
|
102
|
+
};
|
|
103
|
+
},
|
|
104
|
+
signal: requestOptions.signal ?? options.signal,
|
|
105
|
+
cacheRetention: "none",
|
|
106
|
+
laneKind: "worker-compaction",
|
|
107
|
+
});
|
|
108
|
+
addUsage(compactionUsage, completion.usage);
|
|
109
|
+
const response = {
|
|
110
|
+
role: "assistant",
|
|
111
|
+
content: completion.text ? [{ type: "text", text: completion.text }] : [],
|
|
112
|
+
api: options.model.api,
|
|
113
|
+
provider: options.model.provider,
|
|
114
|
+
model: options.model.id,
|
|
115
|
+
usage: completion.usage,
|
|
116
|
+
stopReason: completion.stopReason,
|
|
117
|
+
timestamp: Date.now(),
|
|
118
|
+
...(completion.stopReason === "error"
|
|
119
|
+
? { errorMessage: completion.text || "Worker compaction provider request failed." }
|
|
120
|
+
: {}),
|
|
121
|
+
};
|
|
122
|
+
recordAssistantUsage(options.toolSurface, response);
|
|
123
|
+
checkpointUsage("Persisted worker compaction provider usage before verification.");
|
|
124
|
+
return response;
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
},
|
|
128
|
+
getFailedCompactionUsage: () => failedCompactionUsage,
|
|
129
|
+
};
|
|
130
|
+
const ledger = {
|
|
131
|
+
changedFiles,
|
|
132
|
+
getUsage: currentUsage,
|
|
133
|
+
};
|
|
134
|
+
return {
|
|
135
|
+
ledger,
|
|
136
|
+
checkpointUsage,
|
|
137
|
+
async run() {
|
|
138
|
+
if (ran)
|
|
139
|
+
throw new Error("A worker attempt executor may run only once.");
|
|
140
|
+
ran = true;
|
|
141
|
+
if (!options.hasPersistedUsageCheckpoint) {
|
|
142
|
+
checkpointUsage("Persisted deterministic cumulative usage baseline for the durable worker transcript.");
|
|
143
|
+
}
|
|
144
|
+
const rawOutcome = await runWorker({
|
|
145
|
+
request: options.request,
|
|
146
|
+
maxUsd: options.grant.budget.maxCostUsd,
|
|
147
|
+
maxWallClockMs: options.grant.budget.maxWallClockMs ?? 0,
|
|
148
|
+
usageReportId: options.usageReportId,
|
|
149
|
+
getChangedFiles: () => [...changedFiles],
|
|
150
|
+
signal: options.signal,
|
|
151
|
+
cwd: options.cwd,
|
|
152
|
+
processCapable: options.processCapable,
|
|
153
|
+
...(options.verificationSubjectTaskId
|
|
154
|
+
? { verificationSubjectTaskId: options.verificationSubjectTaskId }
|
|
155
|
+
: {}),
|
|
156
|
+
...(options.applyActions
|
|
157
|
+
? {
|
|
158
|
+
applyActions: (actions) => {
|
|
159
|
+
const report = options.applyActions(actions, actionJournal);
|
|
160
|
+
for (const filePath of report.changedFiles)
|
|
161
|
+
recordChangedFile(filePath);
|
|
162
|
+
return report;
|
|
163
|
+
},
|
|
164
|
+
}
|
|
165
|
+
: {}),
|
|
166
|
+
complete: async ({ systemPrompt, userPrompt, signal }) => {
|
|
167
|
+
if (options.recoveredTerminal) {
|
|
168
|
+
checkpointUsage("Reused the persisted terminal worker assistant response after recovery.");
|
|
169
|
+
return {
|
|
170
|
+
text: options.recoveredTerminal.text,
|
|
171
|
+
costUsd: options.initialUsage.costUsd,
|
|
172
|
+
stopReason: options.recoveredTerminal.stopReason,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
const persistedToolAssistantIds = new Set();
|
|
176
|
+
const pendingToolAssistants = new Map();
|
|
177
|
+
const persistToolRequest = (message) => {
|
|
178
|
+
const toolCallIds = message.content.flatMap((content) => content.type === "toolCall" ? [content.id] : []);
|
|
179
|
+
if (toolCallIds.length === 0 || toolCallIds.every((id) => persistedToolAssistantIds.has(id)))
|
|
180
|
+
return;
|
|
181
|
+
recordAssistantUsage(options.toolSurface, message);
|
|
182
|
+
options.conversation.appendMessage(message);
|
|
183
|
+
for (const id of toolCallIds) {
|
|
184
|
+
persistedToolAssistantIds.add(id);
|
|
185
|
+
pendingToolAssistants.delete(id);
|
|
186
|
+
}
|
|
187
|
+
checkpointUsage("Persisted worker assistant tool request and its cumulative provider usage.");
|
|
188
|
+
};
|
|
189
|
+
options.toolSurface.gateway?.assertBudgetAvailable("worker_provider_completion");
|
|
190
|
+
const remainingTokens = remainingTokenBudget(options.grant.budget.maxTokens, currentUsage());
|
|
191
|
+
if (remainingTokens !== undefined && remainingTokens <= 0) {
|
|
192
|
+
throw new Error("Worker token budget exhausted before provider completion.");
|
|
193
|
+
}
|
|
194
|
+
let history = options.conversation.getProviderMessages();
|
|
195
|
+
if (history.length === 0) {
|
|
196
|
+
options.conversation.appendMessage({
|
|
197
|
+
role: "user",
|
|
198
|
+
content: [{ type: "text", text: userPrompt }],
|
|
199
|
+
timestamp: Date.now(),
|
|
200
|
+
});
|
|
201
|
+
history = options.conversation.getProviderMessages();
|
|
202
|
+
}
|
|
203
|
+
const completion = await options.runIsolatedCompletion({
|
|
204
|
+
systemPrompt: composeSubagentSystemPrompt({
|
|
205
|
+
soul: options.soul,
|
|
206
|
+
rolePrompt: [systemPrompt, options.workerResourceSystemPrompt].filter(Boolean).join("\n\n"),
|
|
207
|
+
}),
|
|
208
|
+
history,
|
|
209
|
+
messages: [],
|
|
210
|
+
model: options.model,
|
|
211
|
+
thinkingLevel: options.thinkingLevel,
|
|
212
|
+
maxTokens: Math.min(options.laneCapability.laneMaxOutputTokens, remainingTokens ?? Number.POSITIVE_INFINITY),
|
|
213
|
+
tools: options.toolSurface.tools,
|
|
214
|
+
requestPreflight: async () => {
|
|
215
|
+
options.toolSurface.gateway?.assertBudgetAvailable("worker_provider_completion");
|
|
216
|
+
const requestRemainingTokens = remainingTokenBudget(options.grant.budget.maxTokens, currentUsage());
|
|
217
|
+
if (requestRemainingTokens !== undefined && requestRemainingTokens <= 0) {
|
|
218
|
+
throw new Error("Worker token budget exhausted before provider completion.");
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
maxTokens: Math.min(options.laneCapability.laneMaxOutputTokens, requestRemainingTokens ?? Number.POSITIVE_INFINITY),
|
|
222
|
+
};
|
|
223
|
+
},
|
|
224
|
+
beforeToolCall: async (context, toolSignal) => {
|
|
225
|
+
persistToolRequest(context.assistantMessage);
|
|
226
|
+
const decision = await options.toolSurface.beforeToolCall(context, toolSignal);
|
|
227
|
+
if (decision?.block) {
|
|
228
|
+
toolIssues.add(`${context.toolCall.name} blocked: ${decision.reason ?? "capability denied"}`);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
checkpointUsage(`Authorized worker tool '${context.toolCall.name}' under its durable grant.`);
|
|
232
|
+
}
|
|
233
|
+
return decision;
|
|
234
|
+
},
|
|
235
|
+
afterToolCall: async ({ toolCall, args, isError }) => {
|
|
236
|
+
if ((toolCall.name === "write" || toolCall.name === "edit") &&
|
|
237
|
+
args &&
|
|
238
|
+
typeof args === "object" &&
|
|
239
|
+
!Array.isArray(args)) {
|
|
240
|
+
const rawPath = args.path;
|
|
241
|
+
if (typeof rawPath === "string" && rawPath.length > 0) {
|
|
242
|
+
const absolutePath = path.isAbsolute(rawPath)
|
|
243
|
+
? path.resolve(rawPath)
|
|
244
|
+
: path.resolve(options.cwd, rawPath);
|
|
245
|
+
let canonicalPath = absolutePath;
|
|
246
|
+
try {
|
|
247
|
+
canonicalPath = safeRealpathSync(absolutePath);
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
// The operation entered execution; retain its lexical target if canonicalization failed.
|
|
251
|
+
}
|
|
252
|
+
recordChangedFile(path.relative(options.cwd, canonicalPath).split(path.sep).join("/"));
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (isError)
|
|
256
|
+
toolIssues.add(`${toolCall.name} failed during isolated execution`);
|
|
257
|
+
return undefined;
|
|
258
|
+
},
|
|
259
|
+
onMessage: (message) => {
|
|
260
|
+
if (message.role === "assistant" && isToolRequest(message)) {
|
|
261
|
+
// Known calls are normalized before beforeToolCall and persist from that hook.
|
|
262
|
+
// Retain the request only so immediate unknown/malformed results can close the
|
|
263
|
+
// transcript without freezing pre-repair arguments into durable history.
|
|
264
|
+
for (const content of message.content) {
|
|
265
|
+
if (content.type === "toolCall")
|
|
266
|
+
pendingToolAssistants.set(content.id, message);
|
|
267
|
+
}
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
if (message.role === "toolResult" && !persistedToolAssistantIds.has(message.toolCallId)) {
|
|
271
|
+
const pending = pendingToolAssistants.get(message.toolCallId);
|
|
272
|
+
if (pending)
|
|
273
|
+
persistToolRequest(pending);
|
|
274
|
+
}
|
|
275
|
+
if (message.role === "assistant")
|
|
276
|
+
recordAssistantUsage(options.toolSurface, message);
|
|
277
|
+
options.conversation.appendMessage(message);
|
|
278
|
+
options.agentControl.acknowledgeMailboxMessage(options.agentId, message);
|
|
279
|
+
if (message.role === "assistant") {
|
|
280
|
+
checkpointUsage("Persisted worker assistant response and its cumulative provider usage.");
|
|
281
|
+
}
|
|
282
|
+
if (message.role === "toolResult")
|
|
283
|
+
checkpointUsage(`Persisted worker tool result '${message.toolCallId}'.`);
|
|
284
|
+
},
|
|
285
|
+
getSteeringMessages: async () => {
|
|
286
|
+
const includeFollowUp = firstMailboxPoll;
|
|
287
|
+
firstMailboxPoll = false;
|
|
288
|
+
return options.agentControl.mailboxMessagesForConversation(options.agentId, options.conversation, includeFollowUp);
|
|
289
|
+
},
|
|
290
|
+
getFollowUpMessages: async () => options.agentControl.mailboxMessagesForConversation(options.agentId, options.conversation, true),
|
|
291
|
+
...(retentionPolicy
|
|
292
|
+
? {
|
|
293
|
+
transformContext: async (messages) => {
|
|
294
|
+
try {
|
|
295
|
+
const retained = await options.conversation.compactProviderContext(retentionPolicy, options.signal);
|
|
296
|
+
if (retained.status === "compacted_verified" ||
|
|
297
|
+
retained.status === "compacted_deterministic") {
|
|
298
|
+
providerContextCompacted = true;
|
|
299
|
+
}
|
|
300
|
+
if (retained.contextUsage.tokens > retentionPolicy.maxContextTokens &&
|
|
301
|
+
!retentionWarningEmitted) {
|
|
302
|
+
retentionWarningEmitted = true;
|
|
303
|
+
options.warn(`Worker ${options.laneId} has one retained turn larger than its context policy; provider overflow recovery may be required.`);
|
|
304
|
+
}
|
|
305
|
+
if (retained.status !== "compacted_verified" &&
|
|
306
|
+
retained.status !== "compacted_deterministic") {
|
|
307
|
+
return messages;
|
|
308
|
+
}
|
|
309
|
+
return sanitizeToolFailureContext(retained.context.messages, "").messages;
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
if (!retentionWarningEmitted) {
|
|
313
|
+
retentionWarningEmitted = true;
|
|
314
|
+
options.warn(`Worker context retention failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
315
|
+
}
|
|
316
|
+
return messages;
|
|
317
|
+
}
|
|
318
|
+
},
|
|
319
|
+
}
|
|
320
|
+
: {}),
|
|
321
|
+
signal,
|
|
322
|
+
cacheRetention: "short",
|
|
323
|
+
laneKind: "worker",
|
|
324
|
+
});
|
|
325
|
+
if (!providerContextCompacted) {
|
|
326
|
+
options.conversation.commitTranscript(completion.messages ?? options.conversation.getProviderMessages());
|
|
327
|
+
}
|
|
328
|
+
checkpointUsage(`Persisted worker conversation through ${options.conversation.getProviderContext().messages.length} messages.`);
|
|
329
|
+
return {
|
|
330
|
+
text: completion.text,
|
|
331
|
+
costUsd: completion.usage.cost.total,
|
|
332
|
+
stopReason: String(completion.stopReason),
|
|
333
|
+
changedFiles: [...changedFiles],
|
|
334
|
+
blockers: [...toolIssues],
|
|
335
|
+
};
|
|
336
|
+
},
|
|
337
|
+
});
|
|
338
|
+
const usage = checkpointUsage("Persisted final cumulative worker usage before terminal result.");
|
|
339
|
+
return { rawOutcome, usage, changedFiles: [...changedFiles] };
|
|
340
|
+
},
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=worker-attempt-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-attempt-executor.js","sourceRoot":"","sources":["../../../src/core/delegation/worker-attempt-executor.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\nimport type { AgentMessage, ThinkingLevel } from \"@caupulican/pi-agent-core\";\nimport { addUsage, createEmptyUsage, sanitizeToolFailureContext } from \"@caupulican/pi-agent-core\";\nimport { compact } from \"@caupulican/pi-agent-core/node\";\nimport type { Api, AssistantMessage, Message, Model, Usage } from \"@caupulican/pi-ai\";\nimport type { IsolatedCompletionOptions, IsolatedCompletionResult } from \"../agent-session-contracts.ts\";\nimport type { WorkerRequest } from \"../autonomy/contracts.ts\";\nimport type { LaneToolSurface } from \"../autonomy/lane-tool-surface.ts\";\nimport { safeRealpathSync } from \"../autonomy/path-scope.ts\";\nimport { composeSubagentSystemPrompt } from \"../autonomy/subagent-prompt.ts\";\nimport type { ModelCapabilityProfile } from \"../model-capability.ts\";\nimport {\n\tattemptUsageFromGatewayUsage,\n\tEMPTY_ATTEMPT_USAGE,\n\tremainingTokenBudget,\n} from \"../orchestration/attempt-usage.ts\";\nimport type { AttemptUsageSnapshot, ExecutionGrant } from \"../orchestration/contracts.ts\";\nimport type { StartedDelegationAttempt } from \"../orchestration/delegation-ledger.ts\";\nimport { WorkerActionJournal } from \"./worker-action-journal.ts\";\nimport type { AppliedActionsReport, WorkerAction } from \"./worker-actions.ts\";\nimport type { WorkerAgentControlCoordinator } from \"./worker-agent-control-coordinator.ts\";\nimport type { WorkerConversation, WorkerConversationRetentionPolicy } from \"./worker-conversation-store.ts\";\nimport type { WorkerExecutionPlan } from \"./worker-execution-policy.ts\";\nimport type { WorkerLifecycle } from \"./worker-lifecycle.ts\";\nimport { runWorker, type WorkerRunOutcome } from \"./worker-runner.ts\";\n\nexport interface RecoveredWorkerTerminalCompletion {\n\ttext: string;\n\tusage: Usage;\n\tstopReason: string;\n}\n\n/** The live mutable state that must be visible to session disposal before provider work yields. */\nexport interface WorkerAttemptExecutionLedger {\n\tchangedFiles: Set<string>;\n\tgetUsage(): AttemptUsageSnapshot;\n}\n\nexport interface WorkerAttemptExecutionResult {\n\trawOutcome: WorkerRunOutcome;\n\tusage: AttemptUsageSnapshot;\n\tchangedFiles: readonly string[];\n}\n\n/**\n * The provider/tool-loop portion of a prepared worker attempt.\n *\n * Admission, durable leasing, grant compilation, terminalization, notification, verification, and\n * scheduling remain outside this boundary. This unit owns only the ordered child conversation:\n * persist assistant tool requests before execution, append messages before mailbox acknowledgements,\n * checkpoint cumulative usage before later boundaries, and compact only the provider projection.\n */\nexport interface WorkerAttemptExecutorOptions {\n\trequest: WorkerRequest;\n\tgrant: ExecutionGrant;\n\texecutionPlan: WorkerExecutionPlan;\n\ttoolSurface: LaneToolSurface;\n\tconversation: WorkerConversation;\n\tlifecycle: Pick<WorkerLifecycle, \"checkpoint\">;\n\tlaneId: string;\n\tagentId: string;\n\tdurableHandle: StartedDelegationAttempt;\n\tparentSessionId: string;\n\tagentDir: string;\n\tcwd: string;\n\tmodel: Model<Api>;\n\tthinkingLevel?: ThinkingLevel;\n\tlaneCapability: Pick<ModelCapabilityProfile, \"laneMaxOutputTokens\">;\n\tsoul?: string;\n\tworkerResourceSystemPrompt: string;\n\tinitialUsage: AttemptUsageSnapshot;\n\thasPersistedUsageCheckpoint: boolean;\n\tusageReportId: string;\n\tprocessCapable: boolean;\n\tverificationSubjectTaskId?: string;\n\trecoveredTerminal?: RecoveredWorkerTerminalCompletion;\n\tretentionPolicy?: WorkerConversationRetentionPolicy;\n\tsignal?: AbortSignal;\n\trunIsolatedCompletion(options: IsolatedCompletionOptions): Promise<IsolatedCompletionResult>;\n\tagentControl: Pick<WorkerAgentControlCoordinator, \"acknowledgeMailboxMessage\" | \"mailboxMessagesForConversation\">;\n\tapplyActions?(actions: readonly WorkerAction[], actionJournal?: WorkerActionJournal): AppliedActionsReport;\n\twarn(message: string): void;\n}\n\nfunction recordAssistantUsage(surface: LaneToolSurface, message: Extract<Message, { role: \"assistant\" }>): void {\n\tsurface.gateway?.recordUsage({\n\t\tinputTokens: message.usage.input,\n\t\toutputTokens: message.usage.output,\n\t\tcacheReadTokens: message.usage.cacheRead,\n\t\tcacheWriteTokens: message.usage.cacheWrite,\n\t\ttotalTokens: message.usage.totalTokens,\n\t\tcostUsd: message.usage.cost.total,\n\t});\n}\n\nfunction isToolRequest(message: Message): boolean {\n\treturn message.role === \"assistant\" && message.content.some((content) => content.type === \"toolCall\");\n}\n\n/**\n * Constructs one execution exactly once. The caller registers {@link ledger} before calling\n * {@link run}, allowing synchronous disposal to observe mutations and cumulative usage while the\n * provider/tool loop is suspended.\n */\nexport function createWorkerAttemptExecutor(options: WorkerAttemptExecutorOptions): {\n\tledger: WorkerAttemptExecutionLedger;\n\tcheckpointUsage(summary: string): AttemptUsageSnapshot;\n\trun(): Promise<WorkerAttemptExecutionResult>;\n} {\n\tconst changedFiles = new Set(options.conversation.getChangedFiles(options.durableHandle.attemptId));\n\tconst toolIssues = new Set<string>();\n\tconst recordChangedFile = (filePath: string): void => {\n\t\tchangedFiles.add(filePath);\n\t\ttry {\n\t\t\toptions.conversation.recordChangedFile(options.durableHandle.attemptId, filePath);\n\t\t} catch (error) {\n\t\t\ttoolIssues.add(\"worker changed-file progress could not be persisted; parent review is required\");\n\t\t\toptions.warn(\n\t\t\t\t`Worker changed-file progress persistence failed: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t);\n\t\t}\n\t};\n\tconst actionJournal = options.request.envelope.capabilities.includes(\"filesystem.write\")\n\t\t? new WorkerActionJournal({\n\t\t\t\tagentDir: options.agentDir,\n\t\t\t\tparentSessionId: options.parentSessionId,\n\t\t\t\ttaskId: options.durableHandle.taskId,\n\t\t\t\tattemptId: options.durableHandle.attemptId,\n\t\t\t\tfencingToken: options.durableHandle.fencingToken,\n\t\t\t})\n\t\t: undefined;\n\tlet providerContextCompacted = options.conversation.hasProviderCompaction();\n\tlet retentionWarningEmitted = false;\n\tlet firstMailboxPoll = true;\n\tlet ran = false;\n\n\tconst currentUsage = (): AttemptUsageSnapshot =>\n\t\tattemptUsageFromGatewayUsage(\n\t\t\toptions.toolSurface.gateway?.getUsage() ?? {\n\t\t\t\t...EMPTY_ATTEMPT_USAGE,\n\t\t\t\twallClockMs: options.initialUsage.activeWallClockMs,\n\t\t\t},\n\t\t);\n\tconst checkpointUsage = (summary: string): AttemptUsageSnapshot => {\n\t\tconst usage = currentUsage();\n\t\toptions.lifecycle.checkpoint(options.laneId, { summary, usage });\n\t\treturn usage;\n\t};\n\tlet failedCompactionUsage: Usage | undefined;\n\tconst retentionPolicy = options.retentionPolicy && {\n\t\t...options.retentionPolicy,\n\t\tgenerateVerifiedCompaction: async (preparation: Parameters<typeof compact>[0]) => {\n\t\t\tconst compactionUsage = createEmptyUsage();\n\t\t\tfailedCompactionUsage = compactionUsage;\n\t\t\treturn compact(\n\t\t\t\tpreparation,\n\t\t\t\toptions.model,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\toptions.signal,\n\t\t\t\toptions.thinkingLevel,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\t{\n\t\t\t\t\tcompletion: async (model, context, requestOptions): Promise<AssistantMessage> => {\n\t\t\t\t\t\tif (model.provider !== options.model.provider || model.id !== options.model.id) {\n\t\t\t\t\t\t\tthrow new Error(\"Worker compaction attempted to select a model outside the lane binding.\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\toptions.toolSurface.gateway?.assertBudgetAvailable(\"worker_compaction_provider_completion\");\n\t\t\t\t\t\tconst remainingTokens = remainingTokenBudget(options.grant.budget.maxTokens, currentUsage());\n\t\t\t\t\t\tif (remainingTokens !== undefined && remainingTokens <= 0) {\n\t\t\t\t\t\t\tthrow new Error(\"Worker token budget exhausted before compaction provider completion.\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst requestedMaxTokens = requestOptions.maxTokens;\n\t\t\t\t\t\tconst configuredMaxTokens =\n\t\t\t\t\t\t\ttypeof requestedMaxTokens === \"number\" &&\n\t\t\t\t\t\t\tNumber.isSafeInteger(requestedMaxTokens) &&\n\t\t\t\t\t\t\trequestedMaxTokens > 0\n\t\t\t\t\t\t\t\t? requestedMaxTokens\n\t\t\t\t\t\t\t\t: options.laneCapability.laneMaxOutputTokens;\n\t\t\t\t\t\tconst maxTokens = Math.min(configuredMaxTokens, remainingTokens ?? configuredMaxTokens);\n\t\t\t\t\t\tif (!Number.isSafeInteger(maxTokens) || maxTokens <= 0) {\n\t\t\t\t\t\t\tthrow new Error(\"Worker compaction provider completion has no valid remaining token budget.\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst completion = await options.runIsolatedCompletion({\n\t\t\t\t\t\t\tsystemPrompt: context.systemPrompt ?? \"\",\n\t\t\t\t\t\t\tmessages: context.messages,\n\t\t\t\t\t\t\tmodel: options.model,\n\t\t\t\t\t\t\tthinkingLevel: options.thinkingLevel,\n\t\t\t\t\t\t\tmaxTokens,\n\t\t\t\t\t\t\trequestPreflight: async () => {\n\t\t\t\t\t\t\t\toptions.toolSurface.gateway?.assertBudgetAvailable(\"worker_compaction_provider_completion\");\n\t\t\t\t\t\t\t\tconst requestRemainingTokens = remainingTokenBudget(\n\t\t\t\t\t\t\t\t\toptions.grant.budget.maxTokens,\n\t\t\t\t\t\t\t\t\tcurrentUsage(),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tif (requestRemainingTokens !== undefined && requestRemainingTokens <= 0) {\n\t\t\t\t\t\t\t\t\tthrow new Error(\"Worker token budget exhausted before compaction provider completion.\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\tmaxTokens: Math.min(maxTokens, requestRemainingTokens ?? maxTokens),\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tsignal: requestOptions.signal ?? options.signal,\n\t\t\t\t\t\t\tcacheRetention: \"none\",\n\t\t\t\t\t\t\tlaneKind: \"worker-compaction\",\n\t\t\t\t\t\t});\n\t\t\t\t\t\taddUsage(compactionUsage, completion.usage);\n\t\t\t\t\t\tconst response: AssistantMessage = {\n\t\t\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\t\t\tcontent: completion.text ? [{ type: \"text\", text: completion.text }] : [],\n\t\t\t\t\t\t\tapi: options.model.api,\n\t\t\t\t\t\t\tprovider: options.model.provider,\n\t\t\t\t\t\t\tmodel: options.model.id,\n\t\t\t\t\t\t\tusage: completion.usage,\n\t\t\t\t\t\t\tstopReason: completion.stopReason,\n\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t\t...(completion.stopReason === \"error\"\n\t\t\t\t\t\t\t\t? { errorMessage: completion.text || \"Worker compaction provider request failed.\" }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t};\n\t\t\t\t\t\trecordAssistantUsage(options.toolSurface, response);\n\t\t\t\t\t\tcheckpointUsage(\"Persisted worker compaction provider usage before verification.\");\n\t\t\t\t\t\treturn response;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tgetFailedCompactionUsage: () => failedCompactionUsage,\n\t};\n\tconst ledger: WorkerAttemptExecutionLedger = {\n\t\tchangedFiles,\n\t\tgetUsage: currentUsage,\n\t};\n\n\treturn {\n\t\tledger,\n\t\tcheckpointUsage,\n\t\tasync run(): Promise<WorkerAttemptExecutionResult> {\n\t\t\tif (ran) throw new Error(\"A worker attempt executor may run only once.\");\n\t\t\tran = true;\n\t\t\tif (!options.hasPersistedUsageCheckpoint) {\n\t\t\t\tcheckpointUsage(\"Persisted deterministic cumulative usage baseline for the durable worker transcript.\");\n\t\t\t}\n\t\t\tconst rawOutcome = await runWorker({\n\t\t\t\trequest: options.request,\n\t\t\t\tmaxUsd: options.grant.budget.maxCostUsd,\n\t\t\t\tmaxWallClockMs: options.grant.budget.maxWallClockMs ?? 0,\n\t\t\t\tusageReportId: options.usageReportId,\n\t\t\t\tgetChangedFiles: () => [...changedFiles],\n\t\t\t\tsignal: options.signal,\n\t\t\t\tcwd: options.cwd,\n\t\t\t\tprocessCapable: options.processCapable,\n\t\t\t\t...(options.verificationSubjectTaskId\n\t\t\t\t\t? { verificationSubjectTaskId: options.verificationSubjectTaskId }\n\t\t\t\t\t: {}),\n\t\t\t\t...(options.applyActions\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tapplyActions: (actions: readonly WorkerAction[]) => {\n\t\t\t\t\t\t\t\tconst report = options.applyActions!(actions, actionJournal);\n\t\t\t\t\t\t\t\tfor (const filePath of report.changedFiles) recordChangedFile(filePath);\n\t\t\t\t\t\t\t\treturn report;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\tcomplete: async ({ systemPrompt, userPrompt, signal }) => {\n\t\t\t\t\tif (options.recoveredTerminal) {\n\t\t\t\t\t\tcheckpointUsage(\"Reused the persisted terminal worker assistant response after recovery.\");\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttext: options.recoveredTerminal.text,\n\t\t\t\t\t\t\tcostUsd: options.initialUsage.costUsd,\n\t\t\t\t\t\t\tstopReason: options.recoveredTerminal.stopReason,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tconst persistedToolAssistantIds = new Set<string>();\n\t\t\t\t\tconst pendingToolAssistants = new Map<string, AssistantMessage>();\n\t\t\t\t\tconst persistToolRequest = (message: AssistantMessage): void => {\n\t\t\t\t\t\tconst toolCallIds = message.content.flatMap((content) =>\n\t\t\t\t\t\t\tcontent.type === \"toolCall\" ? [content.id] : [],\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (toolCallIds.length === 0 || toolCallIds.every((id) => persistedToolAssistantIds.has(id))) return;\n\t\t\t\t\t\trecordAssistantUsage(options.toolSurface, message);\n\t\t\t\t\t\toptions.conversation.appendMessage(message);\n\t\t\t\t\t\tfor (const id of toolCallIds) {\n\t\t\t\t\t\t\tpersistedToolAssistantIds.add(id);\n\t\t\t\t\t\t\tpendingToolAssistants.delete(id);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcheckpointUsage(\"Persisted worker assistant tool request and its cumulative provider usage.\");\n\t\t\t\t\t};\n\t\t\t\t\toptions.toolSurface.gateway?.assertBudgetAvailable(\"worker_provider_completion\");\n\t\t\t\t\tconst remainingTokens = remainingTokenBudget(options.grant.budget.maxTokens, currentUsage());\n\t\t\t\t\tif (remainingTokens !== undefined && remainingTokens <= 0) {\n\t\t\t\t\t\tthrow new Error(\"Worker token budget exhausted before provider completion.\");\n\t\t\t\t\t}\n\t\t\t\t\tlet history = options.conversation.getProviderMessages();\n\t\t\t\t\tif (history.length === 0) {\n\t\t\t\t\t\toptions.conversation.appendMessage({\n\t\t\t\t\t\t\trole: \"user\",\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: userPrompt }],\n\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t});\n\t\t\t\t\t\thistory = options.conversation.getProviderMessages();\n\t\t\t\t\t}\n\t\t\t\t\tconst completion = await options.runIsolatedCompletion({\n\t\t\t\t\t\tsystemPrompt: composeSubagentSystemPrompt({\n\t\t\t\t\t\t\tsoul: options.soul,\n\t\t\t\t\t\t\trolePrompt: [systemPrompt, options.workerResourceSystemPrompt].filter(Boolean).join(\"\\n\\n\"),\n\t\t\t\t\t\t}),\n\t\t\t\t\t\thistory,\n\t\t\t\t\t\tmessages: [],\n\t\t\t\t\t\tmodel: options.model,\n\t\t\t\t\t\tthinkingLevel: options.thinkingLevel,\n\t\t\t\t\t\tmaxTokens: Math.min(\n\t\t\t\t\t\t\toptions.laneCapability.laneMaxOutputTokens,\n\t\t\t\t\t\t\tremainingTokens ?? Number.POSITIVE_INFINITY,\n\t\t\t\t\t\t),\n\t\t\t\t\t\ttools: options.toolSurface.tools,\n\t\t\t\t\t\trequestPreflight: async () => {\n\t\t\t\t\t\t\toptions.toolSurface.gateway?.assertBudgetAvailable(\"worker_provider_completion\");\n\t\t\t\t\t\t\tconst requestRemainingTokens = remainingTokenBudget(\n\t\t\t\t\t\t\t\toptions.grant.budget.maxTokens,\n\t\t\t\t\t\t\t\tcurrentUsage(),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (requestRemainingTokens !== undefined && requestRemainingTokens <= 0) {\n\t\t\t\t\t\t\t\tthrow new Error(\"Worker token budget exhausted before provider completion.\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tmaxTokens: Math.min(\n\t\t\t\t\t\t\t\t\toptions.laneCapability.laneMaxOutputTokens,\n\t\t\t\t\t\t\t\t\trequestRemainingTokens ?? Number.POSITIVE_INFINITY,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t},\n\t\t\t\t\t\tbeforeToolCall: async (context, toolSignal) => {\n\t\t\t\t\t\t\tpersistToolRequest(context.assistantMessage);\n\t\t\t\t\t\t\tconst decision = await options.toolSurface.beforeToolCall(context, toolSignal);\n\t\t\t\t\t\t\tif (decision?.block) {\n\t\t\t\t\t\t\t\ttoolIssues.add(`${context.toolCall.name} blocked: ${decision.reason ?? \"capability denied\"}`);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcheckpointUsage(`Authorized worker tool '${context.toolCall.name}' under its durable grant.`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn decision;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tafterToolCall: async ({ toolCall, args, isError }) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t(toolCall.name === \"write\" || toolCall.name === \"edit\") &&\n\t\t\t\t\t\t\t\targs &&\n\t\t\t\t\t\t\t\ttypeof args === \"object\" &&\n\t\t\t\t\t\t\t\t!Array.isArray(args)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tconst rawPath = (args as Record<string, unknown>).path;\n\t\t\t\t\t\t\t\tif (typeof rawPath === \"string\" && rawPath.length > 0) {\n\t\t\t\t\t\t\t\t\tconst absolutePath = path.isAbsolute(rawPath)\n\t\t\t\t\t\t\t\t\t\t? path.resolve(rawPath)\n\t\t\t\t\t\t\t\t\t\t: path.resolve(options.cwd, rawPath);\n\t\t\t\t\t\t\t\t\tlet canonicalPath = absolutePath;\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tcanonicalPath = safeRealpathSync(absolutePath);\n\t\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t\t// The operation entered execution; retain its lexical target if canonicalization failed.\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\trecordChangedFile(path.relative(options.cwd, canonicalPath).split(path.sep).join(\"/\"));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (isError) toolIssues.add(`${toolCall.name} failed during isolated execution`);\n\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tonMessage: (message) => {\n\t\t\t\t\t\t\tif (message.role === \"assistant\" && isToolRequest(message)) {\n\t\t\t\t\t\t\t\t// Known calls are normalized before beforeToolCall and persist from that hook.\n\t\t\t\t\t\t\t\t// Retain the request only so immediate unknown/malformed results can close the\n\t\t\t\t\t\t\t\t// transcript without freezing pre-repair arguments into durable history.\n\t\t\t\t\t\t\t\tfor (const content of message.content) {\n\t\t\t\t\t\t\t\t\tif (content.type === \"toolCall\") pendingToolAssistants.set(content.id, message);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (message.role === \"toolResult\" && !persistedToolAssistantIds.has(message.toolCallId)) {\n\t\t\t\t\t\t\t\tconst pending = pendingToolAssistants.get(message.toolCallId);\n\t\t\t\t\t\t\t\tif (pending) persistToolRequest(pending);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (message.role === \"assistant\") recordAssistantUsage(options.toolSurface, message);\n\t\t\t\t\t\t\toptions.conversation.appendMessage(message);\n\t\t\t\t\t\t\toptions.agentControl.acknowledgeMailboxMessage(options.agentId, message);\n\t\t\t\t\t\t\tif (message.role === \"assistant\") {\n\t\t\t\t\t\t\t\tcheckpointUsage(\"Persisted worker assistant response and its cumulative provider usage.\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (message.role === \"toolResult\")\n\t\t\t\t\t\t\t\tcheckpointUsage(`Persisted worker tool result '${message.toolCallId}'.`);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tgetSteeringMessages: async (): Promise<AgentMessage[]> => {\n\t\t\t\t\t\t\tconst includeFollowUp = firstMailboxPoll;\n\t\t\t\t\t\t\tfirstMailboxPoll = false;\n\t\t\t\t\t\t\treturn options.agentControl.mailboxMessagesForConversation(\n\t\t\t\t\t\t\t\toptions.agentId,\n\t\t\t\t\t\t\t\toptions.conversation,\n\t\t\t\t\t\t\t\tincludeFollowUp,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t},\n\t\t\t\t\t\tgetFollowUpMessages: async (): Promise<AgentMessage[]> =>\n\t\t\t\t\t\t\toptions.agentControl.mailboxMessagesForConversation(options.agentId, options.conversation, true),\n\t\t\t\t\t\t...(retentionPolicy\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\ttransformContext: async (messages: AgentMessage[]) => {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tconst retained = await options.conversation.compactProviderContext(\n\t\t\t\t\t\t\t\t\t\t\t\tretentionPolicy,\n\t\t\t\t\t\t\t\t\t\t\t\toptions.signal,\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\t\tretained.status === \"compacted_verified\" ||\n\t\t\t\t\t\t\t\t\t\t\t\tretained.status === \"compacted_deterministic\"\n\t\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t\tproviderContextCompacted = true;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\t\tretained.contextUsage.tokens > retentionPolicy.maxContextTokens &&\n\t\t\t\t\t\t\t\t\t\t\t\t!retentionWarningEmitted\n\t\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t\tretentionWarningEmitted = true;\n\t\t\t\t\t\t\t\t\t\t\t\toptions.warn(\n\t\t\t\t\t\t\t\t\t\t\t\t\t`Worker ${options.laneId} has one retained turn larger than its context policy; provider overflow recovery may be required.`,\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\t\tretained.status !== \"compacted_verified\" &&\n\t\t\t\t\t\t\t\t\t\t\t\tretained.status !== \"compacted_deterministic\"\n\t\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t\treturn messages;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\treturn sanitizeToolFailureContext(retained.context.messages, \"\").messages;\n\t\t\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\t\t\tif (!retentionWarningEmitted) {\n\t\t\t\t\t\t\t\t\t\t\t\tretentionWarningEmitted = true;\n\t\t\t\t\t\t\t\t\t\t\t\toptions.warn(\n\t\t\t\t\t\t\t\t\t\t\t\t\t`Worker context retention failed: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\treturn messages;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t\tcacheRetention: \"short\",\n\t\t\t\t\t\tlaneKind: \"worker\",\n\t\t\t\t\t});\n\t\t\t\t\tif (!providerContextCompacted) {\n\t\t\t\t\t\toptions.conversation.commitTranscript(\n\t\t\t\t\t\t\tcompletion.messages ?? options.conversation.getProviderMessages(),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tcheckpointUsage(\n\t\t\t\t\t\t`Persisted worker conversation through ${options.conversation.getProviderContext().messages.length} messages.`,\n\t\t\t\t\t);\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttext: completion.text,\n\t\t\t\t\t\tcostUsd: completion.usage.cost.total,\n\t\t\t\t\t\tstopReason: String(completion.stopReason),\n\t\t\t\t\t\tchangedFiles: [...changedFiles],\n\t\t\t\t\t\tblockers: [...toolIssues],\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst usage = checkpointUsage(\"Persisted final cumulative worker usage before terminal result.\");\n\t\t\treturn { rawOutcome, usage, changedFiles: [...changedFiles] };\n\t\t},\n\t};\n}\n"]}
|