@elie-laloum/outpost 7.0.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +2 -0
- package/dist/adapters/agents/antigravity-adapter.js +3 -0
- package/dist/adapters/agents/antigravity-adapter.js.map +1 -1
- package/dist/adapters/agents/claude-adapter.js +3 -0
- package/dist/adapters/agents/claude-adapter.js.map +1 -1
- package/dist/adapters/agents/claude-events.js +25 -1
- package/dist/adapters/agents/claude-events.js.map +1 -1
- package/dist/adapters/agents/codex-adapter.js +3 -0
- package/dist/adapters/agents/codex-adapter.js.map +1 -1
- package/dist/adapters/agents/copilot-adapter.js +3 -0
- package/dist/adapters/agents/copilot-adapter.js.map +1 -1
- package/dist/adapters/agents/copilot-events.js +7 -3
- package/dist/adapters/agents/copilot-events.js.map +1 -1
- package/dist/adapters/agents/kimi-adapter.js +3 -0
- package/dist/adapters/agents/kimi-adapter.js.map +1 -1
- package/dist/adapters/agents/quota.constants.d.ts +7 -0
- package/dist/adapters/agents/quota.constants.js +31 -0
- package/dist/adapters/agents/quota.constants.js.map +1 -0
- package/dist/adapters/agents/quota.d.ts +1 -0
- package/dist/adapters/agents/quota.js +4 -0
- package/dist/adapters/agents/quota.js.map +1 -0
- package/dist/adapters/models/http-provider.js +8 -2
- package/dist/adapters/models/http-provider.js.map +1 -1
- package/dist/adapters/models/model.constants.d.ts +2 -0
- package/dist/adapters/models/model.constants.js +6 -0
- package/dist/adapters/models/model.constants.js.map +1 -1
- package/dist/adapters/models/stream-events.js +11 -7
- package/dist/adapters/models/stream-events.js.map +1 -1
- package/dist/application/agent-output.js +10 -1
- package/dist/application/agent-output.js.map +1 -1
- package/dist/application/agent-quota.d.ts +7 -0
- package/dist/application/agent-quota.js +33 -0
- package/dist/application/agent-quota.js.map +1 -0
- package/dist/application/agent-turn.js +25 -9
- package/dist/application/agent-turn.js.map +1 -1
- package/dist/application/dispatch-observation.js +10 -1
- package/dist/application/dispatch-observation.js.map +1 -1
- package/dist/application/execution.types.d.ts +2 -0
- package/dist/application/execution.types.js.map +1 -1
- package/dist/application/interactive-task-execution.d.ts +3 -0
- package/dist/application/interactive-task-execution.js +76 -0
- package/dist/application/interactive-task-execution.js.map +1 -0
- package/dist/application/interactive-task-protocol.d.ts +4 -0
- package/dist/application/interactive-task-protocol.js +56 -0
- package/dist/application/interactive-task-protocol.js.map +1 -0
- package/dist/application/interactive-task.constants.d.ts +4 -0
- package/dist/application/interactive-task.constants.js +7 -0
- package/dist/application/interactive-task.constants.js.map +1 -0
- package/dist/application/interactive-task.d.ts +3 -0
- package/dist/application/interactive-task.js +84 -0
- package/dist/application/interactive-task.js.map +1 -0
- package/dist/application/interactive-task.types.d.ts +44 -0
- package/dist/application/interactive-task.types.js +2 -0
- package/dist/application/interactive-task.types.js.map +1 -0
- package/dist/application/queue-worker.js +19 -1
- package/dist/application/queue-worker.js.map +1 -1
- package/dist/application/queued-task.js +17 -2
- package/dist/application/queued-task.js.map +1 -1
- package/dist/application/quota-resume.constants.d.ts +1 -0
- package/dist/application/quota-resume.constants.js +2 -0
- package/dist/application/quota-resume.constants.js.map +1 -0
- package/dist/application/quota-resume.d.ts +9 -0
- package/dist/application/quota-resume.js +34 -0
- package/dist/application/quota-resume.js.map +1 -0
- package/dist/application/quota-resume.types.d.ts +1 -0
- package/dist/application/quota-resume.types.js +2 -0
- package/dist/application/quota-resume.types.js.map +1 -0
- package/dist/application/recovery-retention-policy.js +1 -1
- package/dist/application/recovery-retention-policy.js.map +1 -1
- package/dist/application/recovery-retention.js +3 -3
- package/dist/application/recovery-retention.js.map +1 -1
- package/dist/application/recovery-retention.types.d.ts +1 -1
- package/dist/application/recovery-retention.types.js.map +1 -1
- package/dist/application/remote-workspace.js +2 -1
- package/dist/application/remote-workspace.js.map +1 -1
- package/dist/application/replay-recording.d.ts +2 -0
- package/dist/application/replay-recording.js +22 -0
- package/dist/application/replay-recording.js.map +1 -0
- package/dist/application/replay-turn.d.ts +4 -0
- package/dist/application/replay-turn.js +47 -0
- package/dist/application/replay-turn.js.map +1 -0
- package/dist/application/replay-workspace.d.ts +4 -0
- package/dist/application/replay-workspace.js +71 -0
- package/dist/application/replay-workspace.js.map +1 -0
- package/dist/application/replay-workspace.types.d.ts +6 -0
- package/dist/application/replay-workspace.types.js +2 -0
- package/dist/application/replay-workspace.types.js.map +1 -0
- package/dist/application/repository-fingerprint.d.ts +1 -0
- package/dist/application/repository-fingerprint.js +18 -0
- package/dist/application/repository-fingerprint.js.map +1 -0
- package/dist/application/sandbox-dispatch.js +2 -0
- package/dist/application/sandbox-dispatch.js.map +1 -1
- package/dist/application/speculation-checkpoint.js +19 -2
- package/dist/application/speculation-checkpoint.js.map +1 -1
- package/dist/application/speculation-checkpoint.types.d.ts +1 -1
- package/dist/application/speculation-checkpoint.types.js.map +1 -1
- package/dist/application/speculation-resume.js +21 -0
- package/dist/application/speculation-resume.js.map +1 -1
- package/dist/application/speculation-run.js +18 -1
- package/dist/application/speculation-run.js.map +1 -1
- package/dist/application/speculation.types.d.ts +7 -2
- package/dist/application/speculation.types.js.map +1 -1
- package/dist/application/tasks.d.ts +2 -2
- package/dist/application/tasks.js +11 -4
- package/dist/application/tasks.js.map +1 -1
- package/dist/application/tasks.types.d.ts +5 -0
- package/dist/application/tasks.types.js.map +1 -1
- package/dist/application/transport-inspection.constants.js +1 -0
- package/dist/application/transport-inspection.constants.js.map +1 -1
- package/dist/application/transport-retention.js +33 -1
- package/dist/application/transport-retention.js.map +1 -1
- package/dist/domain/agent-observation.js +1 -0
- package/dist/domain/agent-observation.js.map +1 -1
- package/dist/domain/agent.types.d.ts +8 -1
- package/dist/domain/agent.types.js.map +1 -1
- package/dist/domain/errors.types.d.ts +1 -1
- package/dist/domain/errors.types.js.map +1 -1
- package/dist/domain/observation.types.d.ts +6 -1
- package/dist/domain/observation.types.js.map +1 -1
- package/dist/domain/quota.constants.d.ts +1 -0
- package/dist/domain/quota.constants.js +2 -0
- package/dist/domain/quota.constants.js.map +1 -0
- package/dist/domain/quota.d.ts +4 -0
- package/dist/domain/quota.js +28 -0
- package/dist/domain/quota.js.map +1 -0
- package/dist/domain/quota.types.d.ts +7 -0
- package/dist/domain/quota.types.js +2 -0
- package/dist/domain/quota.types.js.map +1 -0
- package/dist/domain/replay.constants.d.ts +11 -0
- package/dist/domain/replay.constants.js +42 -0
- package/dist/domain/replay.constants.js.map +1 -0
- package/dist/domain/replay.d.ts +11 -0
- package/dist/domain/replay.js +231 -0
- package/dist/domain/replay.js.map +1 -0
- package/dist/domain/replay.types.d.ts +84 -0
- package/dist/domain/replay.types.js +2 -0
- package/dist/domain/replay.types.js.map +1 -0
- package/dist/domain/task-queue.js +18 -0
- package/dist/domain/task-queue.js.map +1 -1
- package/dist/domain/task-queue.types.d.ts +9 -0
- package/dist/domain/task-queue.types.js.map +1 -1
- package/dist/domain/workflow/checkpoint-validation.js +14 -1
- package/dist/domain/workflow/checkpoint-validation.js.map +1 -1
- package/dist/domain/workflow/checkpoint.js +13 -2
- package/dist/domain/workflow/checkpoint.js.map +1 -1
- package/dist/domain/workflow/gate-validation.js +2 -1
- package/dist/domain/workflow/gate-validation.js.map +1 -1
- package/dist/domain/workflow/input-validation.d.ts +7 -0
- package/dist/domain/workflow/input-validation.js +82 -0
- package/dist/domain/workflow/input-validation.js.map +1 -0
- package/dist/domain/workflow/input.d.ts +10 -0
- package/dist/domain/workflow/input.js +93 -0
- package/dist/domain/workflow/input.js.map +1 -0
- package/dist/domain/workflow/input.types.d.ts +37 -0
- package/dist/domain/workflow/input.types.js +2 -0
- package/dist/domain/workflow/input.types.js.map +1 -0
- package/dist/domain/workflow/loop-runner.d.ts +3 -0
- package/dist/domain/workflow/loop-runner.js +91 -0
- package/dist/domain/workflow/loop-runner.js.map +1 -0
- package/dist/domain/workflow/loop-task.d.ts +10 -0
- package/dist/domain/workflow/loop-task.js +39 -0
- package/dist/domain/workflow/loop-task.js.map +1 -0
- package/dist/domain/workflow/loop-task.types.d.ts +28 -0
- package/dist/domain/workflow/loop-task.types.js +2 -0
- package/dist/domain/workflow/loop-task.types.js.map +1 -0
- package/dist/domain/workflow/loop-validation.d.ts +4 -0
- package/dist/domain/workflow/loop-validation.js +62 -0
- package/dist/domain/workflow/loop-validation.js.map +1 -0
- package/dist/domain/workflow/quota-pause.d.ts +7 -0
- package/dist/domain/workflow/quota-pause.js +83 -0
- package/dist/domain/workflow/quota-pause.js.map +1 -0
- package/dist/domain/workflow/quota-pause.types.d.ts +14 -0
- package/dist/domain/workflow/quota-pause.types.js +2 -0
- package/dist/domain/workflow/quota-pause.types.js.map +1 -0
- package/dist/domain/workflow/quota-validation.d.ts +2 -0
- package/dist/domain/workflow/quota-validation.js +30 -0
- package/dist/domain/workflow/quota-validation.js.map +1 -0
- package/dist/domain/workflow/task-cache-entry.d.ts +3 -0
- package/dist/domain/workflow/task-cache-entry.js +57 -0
- package/dist/domain/workflow/task-cache-entry.js.map +1 -0
- package/dist/domain/workflow/task-cache.constants.d.ts +3 -0
- package/dist/domain/workflow/task-cache.constants.js +3 -0
- package/dist/domain/workflow/task-cache.constants.js.map +1 -0
- package/dist/domain/workflow/task-cache.d.ts +6 -0
- package/dist/domain/workflow/task-cache.js +92 -0
- package/dist/domain/workflow/task-cache.js.map +1 -0
- package/dist/domain/workflow/task-cache.types.d.ts +35 -0
- package/dist/domain/workflow/task-cache.types.js +2 -0
- package/dist/domain/workflow/task-cache.types.js.map +1 -0
- package/dist/domain/workflow/task-runner.js +100 -34
- package/dist/domain/workflow/task-runner.js.map +1 -1
- package/dist/domain/workflow/task.js +21 -0
- package/dist/domain/workflow/task.js.map +1 -1
- package/dist/domain/workflow/validation.js +13 -2
- package/dist/domain/workflow/validation.js.map +1 -1
- package/dist/domain/workflow/workflow-scheduler.js +27 -2
- package/dist/domain/workflow/workflow-scheduler.js.map +1 -1
- package/dist/domain/workflow/workflow-state.js +20 -3
- package/dist/domain/workflow/workflow-state.js.map +1 -1
- package/dist/domain/workflow.types.d.ts +26 -3
- package/dist/domain/workflow.types.js.map +1 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/git/command.d.ts +2 -1
- package/dist/infrastructure/git/command.js +2 -2
- package/dist/infrastructure/git/command.js.map +1 -1
- package/dist/infrastructure/git/replay-commits.constants.d.ts +5 -0
- package/dist/infrastructure/git/replay-commits.constants.js +6 -0
- package/dist/infrastructure/git/replay-commits.constants.js.map +1 -0
- package/dist/infrastructure/git/replay-commits.d.ts +2 -0
- package/dist/infrastructure/git/replay-commits.js +92 -0
- package/dist/infrastructure/git/replay-commits.js.map +1 -0
- package/dist/infrastructure/journal.types.d.ts +1 -0
- package/dist/infrastructure/journal.types.js.map +1 -1
- package/dist/infrastructure/reporter.js +3 -0
- package/dist/infrastructure/reporter.js.map +1 -1
- package/dist/infrastructure/storage-inventory.types.d.ts +1 -1
- package/dist/infrastructure/storage-inventory.types.js.map +1 -1
- package/dist/infrastructure/transport-task-cache.constants.d.ts +2 -0
- package/dist/infrastructure/transport-task-cache.constants.js +3 -0
- package/dist/infrastructure/transport-task-cache.constants.js.map +1 -0
- package/dist/infrastructure/transport-task-cache.d.ts +3 -0
- package/dist/infrastructure/transport-task-cache.js +56 -0
- package/dist/infrastructure/transport-task-cache.js.map +1 -0
- package/dist/infrastructure/transport-task-cache.types.d.ts +4 -0
- package/dist/infrastructure/transport-task-cache.types.js +2 -0
- package/dist/infrastructure/transport-task-cache.types.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream-events.js","sourceRoot":"","sources":["../../../src/adapters/models/stream-events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"stream-events.js","sourceRoot":"","sources":["../../../src/adapters/models/stream-events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,UAAU,SAAS,CAAC,KAAsB;IAC9C,IAAI,KAAc,CAAC;IACnB,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,YAAY,CAAC,UAAU,EAAE,sCAAsC,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAA6B;IACzD,MAAM,MAAM,GAAG,CAAC,KAAc,EAA2B,EAAE,CACzD,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QACzC,CAAC,CAAE,KAAiC;QACpC,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9D,MAAM,IAAI,GAAG,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,MAAM,KAAK,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAC7B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,CAChE,CAAC;IACF,MAAM,IAAI,YAAY,CACpB,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,EAC5B,KAAK;QACH,CAAC,CAAC,6CAA6C;QAC/C,CAAC,CAAC,gCAAgC,EACpC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAClE,CAAC;AACJ,CAAC","sourcesContent":["import { OutpostError } from \"../../domain/errors.ts\";\nimport type { ServerSentEvent } from \"../../infrastructure/sse.types.ts\";\nimport { object } from \"./model-response.ts\";\nimport { MODEL_QUOTA_ERRORS } from \"./model.constants.ts\";\n\nexport function eventData(event: ServerSentEvent): Record<string, unknown> {\n let value: unknown;\n try {\n value = JSON.parse(event.data);\n } catch {\n throw new OutpostError(\"response\", \"Model stream event is not valid JSON\");\n }\n return object(value);\n}\n\nexport function streamFailure(data: Record<string, unknown>): never {\n const record = (value: unknown): Record<string, unknown> =>\n value !== null && typeof value === \"object\"\n ? (value as Record<string, unknown>)\n : {};\n const error = record(data.error ?? record(data.response).error);\n const type = \"type\" in error ? String(error.type) : undefined;\n const code = typeof error.code === \"string\" ? error.code : undefined;\n const quota = [type, code].some(\n (value) => value !== undefined && MODEL_QUOTA_ERRORS.has(value),\n );\n throw new OutpostError(\n quota ? \"quota\" : \"provider\",\n quota\n ? \"Model stream reported a usage or rate limit\"\n : \"Model stream reported an error\",\n { ...(type ? { type } : {}), ...(quota && code ? { code } : {}) },\n );\n}\n"]}
|
|
@@ -7,7 +7,7 @@ import { notify } from "./observation.js";
|
|
|
7
7
|
export function agentOutput(agent, options, markers, pass) {
|
|
8
8
|
const calls = new Map();
|
|
9
9
|
let pending = "", text = "", rawTail = "";
|
|
10
|
-
let finalText, conversation, failure;
|
|
10
|
+
let finalText, conversation, failure, quota;
|
|
11
11
|
let usage = { input: 0, cached: 0, output: 0 };
|
|
12
12
|
let baseline = { input: 0, cached: 0, output: 0 };
|
|
13
13
|
let reportedUsage = false, finalUsage = false;
|
|
@@ -28,6 +28,12 @@ export function agentOutput(agent, options, markers, pass) {
|
|
|
28
28
|
failure: (event) => {
|
|
29
29
|
failure = event.message;
|
|
30
30
|
},
|
|
31
|
+
quota: (event) => {
|
|
32
|
+
quota = Object.freeze({
|
|
33
|
+
message: event.message,
|
|
34
|
+
...(event.resetAt === undefined ? {} : { resetAt: event.resetAt }),
|
|
35
|
+
});
|
|
36
|
+
},
|
|
31
37
|
usage: (event) => recordUsage(event.tokens, event.cumulative),
|
|
32
38
|
};
|
|
33
39
|
function recordUsage(tokens, cumulative = false) {
|
|
@@ -108,6 +114,9 @@ export function agentOutput(agent, options, markers, pass) {
|
|
|
108
114
|
get failure() {
|
|
109
115
|
return failure;
|
|
110
116
|
},
|
|
117
|
+
get quota() {
|
|
118
|
+
return quota;
|
|
119
|
+
},
|
|
111
120
|
get completed() {
|
|
112
121
|
return completed;
|
|
113
122
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-output.js","sourceRoot":"","sources":["../../src/application/agent-output.ts"],"names":[],"mappings":"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","sourcesContent":["import { observationDefaults } from \"../domain/observation.constants.ts\";\nimport { visitAgentEvent } from \"../domain/agent-events.ts\";\nimport type { AgentAdapter, Usage } from \"../domain/agent.types.ts\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport { addUsage, usageDifference } from \"../domain/usage.ts\";\nimport { executionDefaults } from \"./execution.constants.ts\";\nimport type { AgentOutput, DispatchOptions } from \"./execution.types.ts\";\nimport { notify } from \"./observation.ts\";\n\nexport function agentOutput(\n agent: AgentAdapter,\n options: DispatchOptions<unknown>,\n markers: readonly string[],\n pass: number,\n): AgentOutput {\n const calls = new Map<string, string>();\n let pending = \"\",\n text = \"\",\n rawTail = \"\";\n let finalText: string | undefined,\n conversation: string | undefined,\n failure: string | undefined;\n let usage: Usage = { input: 0, cached: 0, output: 0 };\n let baseline: Usage | undefined = { input: 0, cached: 0, output: 0 };\n let reportedUsage = false,\n finalUsage = false;\n let completed = false,\n finished = false;\n const handlers: import(\"../domain/agent.types.ts\").AgentEventHandlers = {\n text: (event) => {\n text += event.text;\n },\n result: (event) => {\n finalText = event.text;\n },\n conversation: (event) => {\n conversation = event.id;\n },\n finished: () => {\n finished = true;\n },\n failure: (event) => {\n failure = event.message;\n },\n usage: (event) => recordUsage(event.tokens, event.cumulative),\n };\n function recordUsage(tokens: Usage, cumulative = false): void {\n reportedUsage = true;\n if (cumulative && (!baseline || baseline.complete === false)) {\n recordUsage({ input: 0, cached: 0, output: 0, complete: false });\n return;\n }\n if (cumulative && tokens.complete !== false) finalUsage = true;\n const current = cumulative ? usageDifference(tokens, baseline!) : tokens;\n const delta = cumulative ? usageDifference(current, usage) : current;\n usage = addUsage(usage, delta);\n notify(options.observe, {\n kind: \"usage\",\n tokens: delta,\n pass,\n at: new Date().toISOString(),\n });\n }\n function consume(line: string): void {\n const at = new Date().toISOString();\n if (oversized(line)) return;\n const events = agent.events(line);\n notify(options.observe, { kind: \"raw\", value: line, pass, at });\n for (const decoded of events) {\n if (decoded.kind === \"tool\" && decoded.callId) {\n if (calls.size >= observationDefaults.toolCallLimit)\n calls.delete(calls.keys().next().value!);\n calls.set(decoded.callId, decoded.name);\n }\n const event =\n decoded.kind === \"tool-result\" && !decoded.name\n ? { ...decoded, name: calls.get(decoded.callId) ?? decoded.callId }\n : decoded;\n if (event.kind === \"tool-result\") calls.delete(event.callId);\n visitAgentEvent(event, handlers);\n if (event.kind !== \"raw\" && event.kind !== \"usage\")\n notify(options.observe, { ...event, pass, at });\n }\n completed =\n (!agent.requiresFinishedEvent || finished) &&\n markers.some((marker) => (finalText ?? text).includes(marker));\n }\n function oversized(line: string): boolean {\n const bytes = Buffer.byteLength(line);\n if (bytes <= executionDefaults.eventBytes) return false;\n notify(options.observe, {\n kind: \"raw\",\n value: line.slice(0, observationDefaults.previewCharacters),\n bytes,\n truncated: true,\n pass,\n at: new Date().toISOString(),\n });\n throw new OutpostError(\"process\", \"Agent emitted an oversized event\", {\n stopReason: \"oversized-event\",\n });\n }\n return {\n get usage() {\n return usage;\n },\n get reportedUsage() {\n return reportedUsage;\n },\n get finalUsage() {\n return finalUsage;\n },\n recordUsage,\n setUsageBaseline(tokens) {\n baseline = tokens;\n if (!tokens || tokens.complete === false)\n recordUsage({ input: 0, cached: 0, output: 0, complete: false });\n },\n get failure() {\n return failure;\n },\n get completed() {\n return completed;\n },\n get conversation() {\n return conversation;\n },\n append(chunk) {\n rawTail = (rawTail + chunk).slice(-executionDefaults.rawTailBytes);\n pending += chunk;\n let end: number;\n while ((end = pending.indexOf(\"\\n\")) >= 0) {\n consume(pending.slice(0, end));\n pending = pending.slice(end + 1);\n }\n oversized(pending);\n },\n flush() {\n if (pending) consume(pending);\n pending = \"\";\n },\n result() {\n if (failure) throw new OutpostError(\"process\", failure, { conversation });\n if (agent.requiresFinishedEvent && !finished)\n throw new OutpostError(\n \"process\",\n \"Agent exited without a successful final event\",\n { conversation },\n );\n return {\n text: finalText ?? (text || rawTail),\n usage,\n ...(conversation ? { conversation } : {}),\n };\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-output.js","sourceRoot":"","sources":["../../src/application/agent-output.ts"],"names":[],"mappings":"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","sourcesContent":["import { observationDefaults } from \"../domain/observation.constants.ts\";\nimport { visitAgentEvent } from \"../domain/agent-events.ts\";\nimport type { AgentAdapter, Usage } from \"../domain/agent.types.ts\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport type { QuotaFault } from \"../domain/quota.types.ts\";\nimport { addUsage, usageDifference } from \"../domain/usage.ts\";\nimport { executionDefaults } from \"./execution.constants.ts\";\nimport type { AgentOutput, DispatchOptions } from \"./execution.types.ts\";\nimport { notify } from \"./observation.ts\";\n\nexport function agentOutput(\n agent: AgentAdapter,\n options: DispatchOptions<unknown>,\n markers: readonly string[],\n pass: number,\n): AgentOutput {\n const calls = new Map<string, string>();\n let pending = \"\",\n text = \"\",\n rawTail = \"\";\n let finalText: string | undefined,\n conversation: string | undefined,\n failure: string | undefined,\n quota: QuotaFault | undefined;\n let usage: Usage = { input: 0, cached: 0, output: 0 };\n let baseline: Usage | undefined = { input: 0, cached: 0, output: 0 };\n let reportedUsage = false,\n finalUsage = false;\n let completed = false,\n finished = false;\n const handlers: import(\"../domain/agent.types.ts\").AgentEventHandlers = {\n text: (event) => {\n text += event.text;\n },\n result: (event) => {\n finalText = event.text;\n },\n conversation: (event) => {\n conversation = event.id;\n },\n finished: () => {\n finished = true;\n },\n failure: (event) => {\n failure = event.message;\n },\n quota: (event) => {\n quota = Object.freeze({\n message: event.message,\n ...(event.resetAt === undefined ? {} : { resetAt: event.resetAt }),\n });\n },\n usage: (event) => recordUsage(event.tokens, event.cumulative),\n };\n function recordUsage(tokens: Usage, cumulative = false): void {\n reportedUsage = true;\n if (cumulative && (!baseline || baseline.complete === false)) {\n recordUsage({ input: 0, cached: 0, output: 0, complete: false });\n return;\n }\n if (cumulative && tokens.complete !== false) finalUsage = true;\n const current = cumulative ? usageDifference(tokens, baseline!) : tokens;\n const delta = cumulative ? usageDifference(current, usage) : current;\n usage = addUsage(usage, delta);\n notify(options.observe, {\n kind: \"usage\",\n tokens: delta,\n pass,\n at: new Date().toISOString(),\n });\n }\n function consume(line: string): void {\n const at = new Date().toISOString();\n if (oversized(line)) return;\n const events = agent.events(line);\n notify(options.observe, { kind: \"raw\", value: line, pass, at });\n for (const decoded of events) {\n if (decoded.kind === \"tool\" && decoded.callId) {\n if (calls.size >= observationDefaults.toolCallLimit)\n calls.delete(calls.keys().next().value!);\n calls.set(decoded.callId, decoded.name);\n }\n const event =\n decoded.kind === \"tool-result\" && !decoded.name\n ? { ...decoded, name: calls.get(decoded.callId) ?? decoded.callId }\n : decoded;\n if (event.kind === \"tool-result\") calls.delete(event.callId);\n visitAgentEvent(event, handlers);\n if (event.kind !== \"raw\" && event.kind !== \"usage\")\n notify(options.observe, { ...event, pass, at });\n }\n completed =\n (!agent.requiresFinishedEvent || finished) &&\n markers.some((marker) => (finalText ?? text).includes(marker));\n }\n function oversized(line: string): boolean {\n const bytes = Buffer.byteLength(line);\n if (bytes <= executionDefaults.eventBytes) return false;\n notify(options.observe, {\n kind: \"raw\",\n value: line.slice(0, observationDefaults.previewCharacters),\n bytes,\n truncated: true,\n pass,\n at: new Date().toISOString(),\n });\n throw new OutpostError(\"process\", \"Agent emitted an oversized event\", {\n stopReason: \"oversized-event\",\n });\n }\n return {\n get usage() {\n return usage;\n },\n get reportedUsage() {\n return reportedUsage;\n },\n get finalUsage() {\n return finalUsage;\n },\n recordUsage,\n setUsageBaseline(tokens) {\n baseline = tokens;\n if (!tokens || tokens.complete === false)\n recordUsage({ input: 0, cached: 0, output: 0, complete: false });\n },\n get failure() {\n return failure;\n },\n get quota() {\n return quota;\n },\n get completed() {\n return completed;\n },\n get conversation() {\n return conversation;\n },\n append(chunk) {\n rawTail = (rawTail + chunk).slice(-executionDefaults.rawTailBytes);\n pending += chunk;\n let end: number;\n while ((end = pending.indexOf(\"\\n\")) >= 0) {\n consume(pending.slice(0, end));\n pending = pending.slice(end + 1);\n }\n oversized(pending);\n },\n flush() {\n if (pending) consume(pending);\n pending = \"\";\n },\n result() {\n if (failure) throw new OutpostError(\"process\", failure, { conversation });\n if (agent.requiresFinishedEvent && !finished)\n throw new OutpostError(\n \"process\",\n \"Agent exited without a successful final event\",\n { conversation },\n );\n return {\n text: finalText ?? (text || rawTail),\n usage,\n ...(conversation ? { conversation } : {}),\n };\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CliAgent } from "../domain/agent.types.ts";
|
|
2
|
+
import type { AgentOutput } from "./execution.types.ts";
|
|
3
|
+
export declare function agentQuota(agent: CliAgent, output: AgentOutput): {
|
|
4
|
+
observe(line: string): void;
|
|
5
|
+
/** Reclassifies a failed agent process that reported a quota signal. */
|
|
6
|
+
classify(error: unknown): unknown;
|
|
7
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { OutpostError } from "../domain/errors.js";
|
|
2
|
+
export function agentQuota(agent, output) {
|
|
3
|
+
let stderr;
|
|
4
|
+
const recognized = (text) => text !== undefined && agent.quota?.(text) === true ? text : undefined;
|
|
5
|
+
function signal() {
|
|
6
|
+
const message = recognized(output.failure) ?? output.quota?.message ?? stderr;
|
|
7
|
+
if (message === undefined)
|
|
8
|
+
return undefined;
|
|
9
|
+
const resetAt = output.quota?.resetAt;
|
|
10
|
+
return { message, ...(resetAt === undefined ? {} : { resetAt }) };
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
observe(line) {
|
|
14
|
+
stderr ??= recognized(line.trim() || undefined);
|
|
15
|
+
},
|
|
16
|
+
/** Reclassifies a failed agent process that reported a quota signal. */
|
|
17
|
+
classify(error) {
|
|
18
|
+
const quota = signal();
|
|
19
|
+
if (!quota ||
|
|
20
|
+
!(error instanceof OutpostError) ||
|
|
21
|
+
error.code !== "process")
|
|
22
|
+
return error;
|
|
23
|
+
const classified = new OutpostError("quota", quota.message, {
|
|
24
|
+
...error.details,
|
|
25
|
+
agent: agent.name,
|
|
26
|
+
...(quota.resetAt === undefined ? {} : { resetAt: quota.resetAt }),
|
|
27
|
+
}, error);
|
|
28
|
+
classified.recovery = error.recovery;
|
|
29
|
+
return classified;
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=agent-quota.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-quota.js","sourceRoot":"","sources":["../../src/application/agent-quota.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAInD,MAAM,UAAU,UAAU,CAAC,KAAe,EAAE,MAAmB;IAC7D,IAAI,MAA0B,CAAC;IAC/B,MAAM,UAAU,GAAG,CAAC,IAAwB,EAAE,EAAE,CAC9C,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,SAAS,MAAM;QACb,MAAM,OAAO,GACX,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,OAAO,IAAI,MAAM,CAAC;QAChE,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC;QACtC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IACpE,CAAC;IACD,OAAO;QACL,OAAO,CAAC,IAAY;YAClB,MAAM,KAAK,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC,CAAC;QAClD,CAAC;QACD,wEAAwE;QACxE,QAAQ,CAAC,KAAc;YACrB,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC;YACvB,IACE,CAAC,KAAK;gBACN,CAAC,CAAC,KAAK,YAAY,YAAY,CAAC;gBAChC,KAAK,CAAC,IAAI,KAAK,SAAS;gBAExB,OAAO,KAAK,CAAC;YACf,MAAM,UAAU,GAAG,IAAI,YAAY,CACjC,OAAO,EACP,KAAK,CAAC,OAAO,EACb;gBACE,GAAG,KAAK,CAAC,OAAO;gBAChB,KAAK,EAAE,KAAK,CAAC,IAAI;gBACjB,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;aACnE,EACD,KAAK,CACN,CAAC;YACF,UAAU,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;YACrC,OAAO,UAAU,CAAC;QACpB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { CliAgent } from \"../domain/agent.types.ts\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport type { QuotaFault } from \"../domain/quota.types.ts\";\nimport type { AgentOutput } from \"./execution.types.ts\";\n\nexport function agentQuota(agent: CliAgent, output: AgentOutput) {\n let stderr: string | undefined;\n const recognized = (text: string | undefined) =>\n text !== undefined && agent.quota?.(text) === true ? text : undefined;\n function signal(): QuotaFault | undefined {\n const message =\n recognized(output.failure) ?? output.quota?.message ?? stderr;\n if (message === undefined) return undefined;\n const resetAt = output.quota?.resetAt;\n return { message, ...(resetAt === undefined ? {} : { resetAt }) };\n }\n return {\n observe(line: string): void {\n stderr ??= recognized(line.trim() || undefined);\n },\n /** Reclassifies a failed agent process that reported a quota signal. */\n classify(error: unknown): unknown {\n const quota = signal();\n if (\n !quota ||\n !(error instanceof OutpostError) ||\n error.code !== \"process\"\n )\n return error;\n const classified = new OutpostError(\n \"quota\",\n quota.message,\n {\n ...error.details,\n agent: agent.name,\n ...(quota.resetAt === undefined ? {} : { resetAt: quota.resetAt }),\n },\n error,\n );\n classified.recovery = error.recovery;\n return classified;\n },\n };\n}\n"]}
|
|
@@ -3,9 +3,11 @@ import { agentRequest } from "./agent-request.js";
|
|
|
3
3
|
import { boundedLines } from "./output-lines.js";
|
|
4
4
|
import { stopReason } from "./stop-reason.js";
|
|
5
5
|
import { customTurn } from "./custom-turn.js";
|
|
6
|
+
import { replayTurn } from "./replay-turn.js";
|
|
6
7
|
import { OutpostError } from "../domain/errors.js";
|
|
7
8
|
import { activityWatchdog } from "./activity-watchdog.js";
|
|
8
9
|
import { agentOutput } from "./agent-output.js";
|
|
10
|
+
import { agentQuota } from "./agent-quota.js";
|
|
9
11
|
import { agentConnectionFailurePattern, executionDefaults, } from "./execution.constants.js";
|
|
10
12
|
import { notify } from "./observation.js";
|
|
11
13
|
export async function turn(lease, agent, prompt, options, continuation, markers, pass, context) {
|
|
@@ -14,21 +16,27 @@ export async function turn(lease, agent, prompt, options, continuation, markers,
|
|
|
14
16
|
...context,
|
|
15
17
|
continuation,
|
|
16
18
|
});
|
|
19
|
+
if (agent.kind === "replay")
|
|
20
|
+
return replayTurn(lease, agent, prompt, options, pass);
|
|
17
21
|
const start = Date.now();
|
|
18
22
|
const controller = new AbortController();
|
|
19
23
|
const signal = options.signal
|
|
20
24
|
? AbortSignal.any([options.signal, controller.signal])
|
|
21
25
|
: controller.signal;
|
|
22
26
|
const output = agentOutput(agent, options, markers, pass);
|
|
27
|
+
const quota = agentQuota(agent, output);
|
|
23
28
|
const watchdog = activityWatchdog(controller, options, pass);
|
|
24
29
|
watchdog.refresh(false);
|
|
25
|
-
const stderr = boundedLines((text, truncated) =>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
const stderr = boundedLines((text, truncated) => {
|
|
31
|
+
quota.observe(text);
|
|
32
|
+
notify(options.observe, {
|
|
33
|
+
kind: "stderr",
|
|
34
|
+
text,
|
|
35
|
+
truncated,
|
|
36
|
+
pass,
|
|
37
|
+
at: new Date().toISOString(),
|
|
38
|
+
});
|
|
39
|
+
});
|
|
32
40
|
let status = 0;
|
|
33
41
|
let commandCompleted = false;
|
|
34
42
|
let preparedConversation;
|
|
@@ -106,7 +114,8 @@ export async function turn(lease, agent, prompt, options, continuation, markers,
|
|
|
106
114
|
diagnosed.recovery = error.recovery;
|
|
107
115
|
throw diagnosed;
|
|
108
116
|
}
|
|
109
|
-
|
|
117
|
+
stderr.flush();
|
|
118
|
+
throw quota.classify(error);
|
|
110
119
|
}
|
|
111
120
|
notify(options.warn, "Agent remained active after completion; its command was stopped and trailing output retained");
|
|
112
121
|
}
|
|
@@ -122,9 +131,16 @@ export async function turn(lease, agent, prompt, options, continuation, markers,
|
|
|
122
131
|
await collectAgentUsage(lease, agent, output, options, pass, commandCompleted);
|
|
123
132
|
}
|
|
124
133
|
options.signal?.throwIfAborted();
|
|
134
|
+
let outcome;
|
|
135
|
+
try {
|
|
136
|
+
outcome = output.result();
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
throw quota.classify(error);
|
|
140
|
+
}
|
|
125
141
|
return {
|
|
126
142
|
...(preparedConversation ? { conversation: preparedConversation } : {}),
|
|
127
|
-
...
|
|
143
|
+
...outcome,
|
|
128
144
|
status,
|
|
129
145
|
durationMs: Date.now() - start,
|
|
130
146
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-turn.js","sourceRoot":"","sources":["../../src/application/agent-turn.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n collectAgentUsage,\n prepareAgentUsage,\n warnUsage,\n} from \"./agent-usage.ts\";\nimport { agentRequest } from \"./agent-request.ts\";\nimport { boundedLines } from \"./output-lines.ts\";\nimport { stopReason } from \"./stop-reason.ts\";\nimport { customTurn } from \"./custom-turn.ts\";\nimport type { Agent } from \"../domain/agent.types.ts\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport { activityWatchdog } from \"./activity-watchdog.ts\";\nimport { agentOutput } from \"./agent-output.ts\";\nimport {\n agentConnectionFailurePattern,\n executionDefaults,\n} from \"./execution.constants.ts\";\nimport type { DispatchOptions, Turn, TurnContext } from \"./execution.types.ts\";\nimport { notify } from \"./observation.ts\";\n\nexport async function turn(\n lease: SandboxLease,\n agent: Agent,\n prompt: string,\n options: DispatchOptions<unknown>,\n continuation: DispatchOptions[\"continuation\"],\n markers: readonly string[],\n pass: number,\n context: TurnContext,\n): Promise<Turn> {\n if (agent.kind === \"custom\")\n return customTurn(lease, agent, prompt, options, pass, {\n ...context,\n continuation,\n });\n const start = Date.now();\n const controller = new AbortController();\n const signal = options.signal\n ? AbortSignal.any([options.signal, controller.signal])\n : controller.signal;\n const output = agentOutput(agent, options, markers, pass);\n const watchdog = activityWatchdog(controller, options, pass);\n watchdog.refresh(false);\n const stderr = boundedLines((text, truncated) =>\n notify(options.observe, {\n kind: \"stderr\",\n text,\n truncated,\n pass,\n at: new Date().toISOString(),\n }),\n );\n let status = 0;\n let commandCompleted = false;\n let preparedConversation: string | undefined;\n try {\n if (agent.usage === \"session\")\n warnUsage(\n options,\n pass,\n `${agent.name}: token usage is collected after the command exits; use budget.attempts and time limits to bound execution before the final counters arrive`,\n );\n if (agent.usage === \"unavailable\") {\n warnUsage(\n options,\n pass,\n `${agent.name}: token usage is unavailable; use budget.attempts and time limits`,\n );\n output.recordUsage({ input: 0, cached: 0, output: 0, complete: false });\n }\n await prepareAgentUsage(lease, agent, output, continuation, signal);\n signal.throwIfAborted();\n const command = await agentRequest(\n agent,\n {\n text: prompt,\n ...(continuation ? { continuation } : {}),\n },\n (command) =>\n lease.invoke({\n ...command,\n signal,\n deadlineMs: options.deadlineMs ?? executionDefaults.deadlineMs,\n }),\n (id) => {\n preparedConversation = id;\n notify(options.observe, {\n kind: \"conversation\",\n id,\n pass,\n at: new Date().toISOString(),\n });\n },\n );\n const result = await lease.invoke({\n ...command,\n signal,\n deadlineMs: options.deadlineMs ?? executionDefaults.deadlineMs,\n observe(channel, chunk) {\n if (channel === \"stdout\") {\n try {\n output.append(chunk);\n } catch (cause) {\n controller.abort(cause);\n }\n }\n if (channel === \"stderr\") stderr.append(chunk);\n watchdog.refresh(output.completed);\n },\n });\n commandCompleted = true;\n status = result.status;\n output.flush();\n if (status !== 0)\n throw new OutpostError(\"process\", `Agent exited with status ${status}`, {\n ...result,\n conversation: output.conversation ?? preparedConversation,\n });\n } catch (cause) {\n const reason = stopReason(options.signal, controller.signal.reason, cause);\n if (reason)\n notify(options.observe, {\n kind: \"stopped\",\n reason,\n pass,\n at: new Date().toISOString(),\n });\n options.signal?.throwIfAborted();\n if (controller.signal.reason !== \"completion\") {\n const error =\n controller.signal.reason instanceof OutpostError\n ? controller.signal.reason\n : cause;\n if (\n error instanceof OutpostError &&\n error.code === \"timeout\" &&\n output.failure &&\n agentConnectionFailurePattern.test(output.failure)\n ) {\n const diagnosed = new OutpostError(\n error.code,\n `${error.message}. The agent reported a connection failure. Check the model endpoint and network access.`,\n { ...error.details, agentDiagnostic: \"connection\" },\n error,\n );\n diagnosed.recovery = error.recovery;\n throw diagnosed;\n }\n throw error;\n }\n notify(\n options.warn,\n \"Agent remained active after completion; its command was stopped and trailing output retained\",\n );\n } finally {\n stderr.flush();\n watchdog.close();\n try {\n output.flush();\n } catch {\n commandCompleted = false;\n }\n await collectAgentUsage(\n lease,\n agent,\n output,\n options,\n pass,\n commandCompleted,\n );\n }\n options.signal?.throwIfAborted();\n return {\n ...(preparedConversation ? { conversation: preparedConversation } : {}),\n ...output.result(),\n status,\n durationMs: Date.now() - start,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-turn.js","sourceRoot":"","sources":["../../src/application/agent-turn.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n collectAgentUsage,\n prepareAgentUsage,\n warnUsage,\n} from \"./agent-usage.ts\";\nimport { agentRequest } from \"./agent-request.ts\";\nimport { boundedLines } from \"./output-lines.ts\";\nimport { stopReason } from \"./stop-reason.ts\";\nimport { customTurn } from \"./custom-turn.ts\";\nimport { replayTurn } from \"./replay-turn.ts\";\nimport type { Agent } from \"../domain/agent.types.ts\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport { activityWatchdog } from \"./activity-watchdog.ts\";\nimport { agentOutput } from \"./agent-output.ts\";\nimport { agentQuota } from \"./agent-quota.ts\";\nimport {\n agentConnectionFailurePattern,\n executionDefaults,\n} from \"./execution.constants.ts\";\nimport type { DispatchOptions, Turn, TurnContext } from \"./execution.types.ts\";\nimport { notify } from \"./observation.ts\";\n\nexport async function turn(\n lease: SandboxLease,\n agent: Agent,\n prompt: string,\n options: DispatchOptions<unknown>,\n continuation: DispatchOptions[\"continuation\"],\n markers: readonly string[],\n pass: number,\n context: TurnContext,\n): Promise<Turn> {\n if (agent.kind === \"custom\")\n return customTurn(lease, agent, prompt, options, pass, {\n ...context,\n continuation,\n });\n if (agent.kind === \"replay\")\n return replayTurn(lease, agent, prompt, options, pass);\n const start = Date.now();\n const controller = new AbortController();\n const signal = options.signal\n ? AbortSignal.any([options.signal, controller.signal])\n : controller.signal;\n const output = agentOutput(agent, options, markers, pass);\n const quota = agentQuota(agent, output);\n const watchdog = activityWatchdog(controller, options, pass);\n watchdog.refresh(false);\n const stderr = boundedLines((text, truncated) => {\n quota.observe(text);\n notify(options.observe, {\n kind: \"stderr\",\n text,\n truncated,\n pass,\n at: new Date().toISOString(),\n });\n });\n let status = 0;\n let commandCompleted = false;\n let preparedConversation: string | undefined;\n try {\n if (agent.usage === \"session\")\n warnUsage(\n options,\n pass,\n `${agent.name}: token usage is collected after the command exits; use budget.attempts and time limits to bound execution before the final counters arrive`,\n );\n if (agent.usage === \"unavailable\") {\n warnUsage(\n options,\n pass,\n `${agent.name}: token usage is unavailable; use budget.attempts and time limits`,\n );\n output.recordUsage({ input: 0, cached: 0, output: 0, complete: false });\n }\n await prepareAgentUsage(lease, agent, output, continuation, signal);\n signal.throwIfAborted();\n const command = await agentRequest(\n agent,\n {\n text: prompt,\n ...(continuation ? { continuation } : {}),\n },\n (command) =>\n lease.invoke({\n ...command,\n signal,\n deadlineMs: options.deadlineMs ?? executionDefaults.deadlineMs,\n }),\n (id) => {\n preparedConversation = id;\n notify(options.observe, {\n kind: \"conversation\",\n id,\n pass,\n at: new Date().toISOString(),\n });\n },\n );\n const result = await lease.invoke({\n ...command,\n signal,\n deadlineMs: options.deadlineMs ?? executionDefaults.deadlineMs,\n observe(channel, chunk) {\n if (channel === \"stdout\") {\n try {\n output.append(chunk);\n } catch (cause) {\n controller.abort(cause);\n }\n }\n if (channel === \"stderr\") stderr.append(chunk);\n watchdog.refresh(output.completed);\n },\n });\n commandCompleted = true;\n status = result.status;\n output.flush();\n if (status !== 0)\n throw new OutpostError(\"process\", `Agent exited with status ${status}`, {\n ...result,\n conversation: output.conversation ?? preparedConversation,\n });\n } catch (cause) {\n const reason = stopReason(options.signal, controller.signal.reason, cause);\n if (reason)\n notify(options.observe, {\n kind: \"stopped\",\n reason,\n pass,\n at: new Date().toISOString(),\n });\n options.signal?.throwIfAborted();\n if (controller.signal.reason !== \"completion\") {\n const error =\n controller.signal.reason instanceof OutpostError\n ? controller.signal.reason\n : cause;\n if (\n error instanceof OutpostError &&\n error.code === \"timeout\" &&\n output.failure &&\n agentConnectionFailurePattern.test(output.failure)\n ) {\n const diagnosed = new OutpostError(\n error.code,\n `${error.message}. The agent reported a connection failure. Check the model endpoint and network access.`,\n { ...error.details, agentDiagnostic: \"connection\" },\n error,\n );\n diagnosed.recovery = error.recovery;\n throw diagnosed;\n }\n stderr.flush();\n throw quota.classify(error);\n }\n notify(\n options.warn,\n \"Agent remained active after completion; its command was stopped and trailing output retained\",\n );\n } finally {\n stderr.flush();\n watchdog.close();\n try {\n output.flush();\n } catch {\n commandCompleted = false;\n }\n await collectAgentUsage(\n lease,\n agent,\n output,\n options,\n pass,\n commandCompleted,\n );\n }\n options.signal?.throwIfAborted();\n let outcome: ReturnType<typeof output.result>;\n try {\n outcome = output.result();\n } catch (error) {\n throw quota.classify(error);\n }\n return {\n ...(preparedConversation ? { conversation: preparedConversation } : {}),\n ...outcome,\n status,\n durationMs: Date.now() - start,\n };\n}\n"]}
|
|
@@ -93,7 +93,7 @@ export async function observeDispatch(options, action, repository = process.cwd(
|
|
|
93
93
|
pass: event.pass,
|
|
94
94
|
...(event.subagentId ? { subagentId: event.subagentId } : {}),
|
|
95
95
|
})
|
|
96
|
-
.emit(options.agent
|
|
96
|
+
.emit(agentSource(options.agent), event);
|
|
97
97
|
},
|
|
98
98
|
};
|
|
99
99
|
try {
|
|
@@ -141,6 +141,10 @@ export async function observeDispatch(options, action, repository = process.cwd(
|
|
|
141
141
|
? { commits: recovery.commits }
|
|
142
142
|
: {}),
|
|
143
143
|
usage,
|
|
144
|
+
error: {
|
|
145
|
+
...(error instanceof OutpostError ? { code: error.code } : {}),
|
|
146
|
+
message: error instanceof Error ? error.message : String(error),
|
|
147
|
+
},
|
|
144
148
|
});
|
|
145
149
|
try {
|
|
146
150
|
session?.finish({ status, usage });
|
|
@@ -160,6 +164,11 @@ export async function observeDispatch(options, action, repository = process.cwd(
|
|
|
160
164
|
active.delete(observation);
|
|
161
165
|
}
|
|
162
166
|
}
|
|
167
|
+
function agentSource(agent) {
|
|
168
|
+
if (agent?.kind === "replay")
|
|
169
|
+
return agent.source;
|
|
170
|
+
return agent?.kind === "custom" ? "harness" : "agent";
|
|
171
|
+
}
|
|
163
172
|
function isCommit(value) {
|
|
164
173
|
return (typeof value === "object" &&
|
|
165
174
|
value !== null &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch-observation.js","sourceRoot":"","sources":["../../src/application/dispatch-observation.ts"],"names":[],"mappings":"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","sourcesContent":["import { access } from \"node:fs/promises\";\nimport { randomUUID } from \"node:crypto\";\nimport { agentObservation } from \"../domain/agent-observation.ts\";\nimport type { Usage } from \"../domain/agent.types.ts\";\nimport type { DispatchTelemetrySession } from \"../domain/dispatch-telemetry.types.ts\";\nimport type { ObservationHub } from \"../domain/observation.types.ts\";\nimport { createObservationHub } from \"../domain/observation.ts\";\nimport {\n recordRecovery,\n recoveryDetails,\n OutpostError,\n} from \"../domain/errors.ts\";\nimport { addUsage } from \"../domain/usage.ts\";\nimport { journal } from \"../infrastructure/journal.ts\";\nimport type { Journal } from \"../infrastructure/journal.types.ts\";\nimport type { ObservedDispatchResult } from \"./dispatch-observation.types.ts\";\nimport type { DispatchOptions } from \"./execution.types.ts\";\n\nconst active = new WeakSet<ObservationHub>();\n\nexport async function observeDispatch<T, R extends ObservedDispatchResult>(\n options: DispatchOptions<T>,\n action: (options: DispatchOptions<T>) => Promise<R>,\n repository = process.cwd(),\n): Promise<R> {\n if (options.observation && active.has(options.observation))\n return action(options);\n const root = options.observation ?? createObservationHub();\n const failures: unknown[] = [];\n let log: Journal | undefined;\n let session: DispatchTelemetrySession | undefined;\n const initialized = (async () => {\n try {\n await access(repository);\n log = await journal(repository, options.logging, options.label, false);\n } catch (error) {\n failures.push(error);\n }\n })();\n try {\n session = options.telemetry?.startDispatch();\n } catch (error) {\n failures.push(error);\n }\n const observation = root.child({ dispatchId: randomUUID() }, [\n {\n async observe(value) {\n await initialized;\n await log?.record({\n ...value.event,\n seq: value.seq,\n at: value.at,\n source: value.source,\n scope: value.scope,\n });\n },\n async flush() {\n await initialized;\n await log?.close();\n },\n },\n {\n observe(value) {\n if (value.event.kind === \"warning\")\n return options.warn?.(value.event.message);\n },\n },\n {\n observe(value) {\n if (value.source !== \"agent\" && value.source !== \"harness\") return;\n const event = agentObservation(value);\n if (event) return options.observe?.(event);\n },\n async flush() {\n const observer = options.observe;\n if (\n observer &&\n \"flush\" in observer &&\n typeof observer.flush === \"function\"\n )\n await observer.flush();\n },\n },\n ]);\n active.add(observation);\n observation.emit(\"sandbox\", { kind: \"dispatch-start\" });\n const empty = (): Usage => ({ input: 0, cached: 0, output: 0 });\n let previous = empty(),\n current = empty();\n const { telemetry: _telemetry, ...settings } = options;\n const observed: DispatchOptions<T> = {\n ...settings,\n observation,\n warn(message) {\n observation.emit(\"agent\", { kind: \"warning\", message });\n },\n observe(event) {\n if (event.kind === \"phase\" && event.name === \"preparing prompt\") {\n previous = addUsage(previous, current);\n current = empty();\n }\n if (event.kind === \"usage\") current = addUsage(current, event.tokens);\n if (event.kind === \"summary\") current = event.tokens;\n observation\n .child({\n pass: event.pass,\n ...(event.subagentId ? { subagentId: event.subagentId } : {}),\n })\n .emit(options.agent?.kind === \"custom\" ? \"harness\" : \"agent\", event);\n },\n };\n try {\n const result = await action(observed);\n observation.emit(\"sandbox\", {\n kind: \"dispatch-finished\",\n status: \"done\",\n completed: result.completed,\n usage: result.usage,\n ...(result.branch ? { branch: result.branch } : {}),\n ...(result.commits ? { commits: result.commits } : {}),\n });\n try {\n session?.finish({\n status: \"done\",\n usage: result.usage,\n completed: result.completed,\n });\n } catch (error) {\n failures.push(error);\n }\n await finish();\n return {\n ...result,\n ...(log?.reference ? { logReference: log.reference } : {}),\n observerErrors: [...failures, ...observation.errors],\n };\n } catch (error) {\n const cancelled =\n options.signal?.aborted ||\n (error instanceof OutpostError && error.code === \"aborted\") ||\n (error instanceof Error && error.name === \"AbortError\");\n const status = cancelled ? \"cancelled\" : \"failed\";\n const usage = addUsage(previous, current);\n const recovery = recoveryDetails(error);\n observation.emit(\"sandbox\", {\n kind: \"dispatch-finished\",\n status,\n completed: false,\n ...(typeof recovery?.branch === \"string\"\n ? { branch: recovery.branch }\n : {}),\n ...(Array.isArray(recovery?.commits) && recovery.commits.every(isCommit)\n ? { commits: recovery.commits }\n : {}),\n usage,\n });\n try {\n session?.finish({ status, usage });\n } catch (failure) {\n failures.push(failure);\n }\n await finish();\n recordRecovery(error, {\n observerErrors: [...failures, ...observation.errors],\n ...(log?.reference ? { logReference: log.reference } : {}),\n });\n throw error;\n }\n async function finish(): Promise<void> {\n await observation.close();\n active.delete(observation);\n }\n}\n\nfunction isCommit(\n value: unknown,\n): value is import(\"../domain/workspace.types.ts\").Commit {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"oid\" in value &&\n typeof value.oid === \"string\" &&\n \"subject\" in value &&\n typeof value.subject === \"string\"\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dispatch-observation.js","sourceRoot":"","sources":["../../src/application/dispatch-observation.ts"],"names":[],"mappings":"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","sourcesContent":["import { access } from \"node:fs/promises\";\nimport { randomUUID } from \"node:crypto\";\nimport { agentObservation } from \"../domain/agent-observation.ts\";\nimport type { Agent, Usage } from \"../domain/agent.types.ts\";\nimport type { DispatchTelemetrySession } from \"../domain/dispatch-telemetry.types.ts\";\nimport type {\n ObservationHub,\n ObservationSource,\n} from \"../domain/observation.types.ts\";\nimport { createObservationHub } from \"../domain/observation.ts\";\nimport {\n recordRecovery,\n recoveryDetails,\n OutpostError,\n} from \"../domain/errors.ts\";\nimport { addUsage } from \"../domain/usage.ts\";\nimport { journal } from \"../infrastructure/journal.ts\";\nimport type { Journal } from \"../infrastructure/journal.types.ts\";\nimport type { ObservedDispatchResult } from \"./dispatch-observation.types.ts\";\nimport type { DispatchOptions } from \"./execution.types.ts\";\n\nconst active = new WeakSet<ObservationHub>();\n\nexport async function observeDispatch<T, R extends ObservedDispatchResult>(\n options: DispatchOptions<T>,\n action: (options: DispatchOptions<T>) => Promise<R>,\n repository = process.cwd(),\n): Promise<R> {\n if (options.observation && active.has(options.observation))\n return action(options);\n const root = options.observation ?? createObservationHub();\n const failures: unknown[] = [];\n let log: Journal | undefined;\n let session: DispatchTelemetrySession | undefined;\n const initialized = (async () => {\n try {\n await access(repository);\n log = await journal(repository, options.logging, options.label, false);\n } catch (error) {\n failures.push(error);\n }\n })();\n try {\n session = options.telemetry?.startDispatch();\n } catch (error) {\n failures.push(error);\n }\n const observation = root.child({ dispatchId: randomUUID() }, [\n {\n async observe(value) {\n await initialized;\n await log?.record({\n ...value.event,\n seq: value.seq,\n at: value.at,\n source: value.source,\n scope: value.scope,\n });\n },\n async flush() {\n await initialized;\n await log?.close();\n },\n },\n {\n observe(value) {\n if (value.event.kind === \"warning\")\n return options.warn?.(value.event.message);\n },\n },\n {\n observe(value) {\n if (value.source !== \"agent\" && value.source !== \"harness\") return;\n const event = agentObservation(value);\n if (event) return options.observe?.(event);\n },\n async flush() {\n const observer = options.observe;\n if (\n observer &&\n \"flush\" in observer &&\n typeof observer.flush === \"function\"\n )\n await observer.flush();\n },\n },\n ]);\n active.add(observation);\n observation.emit(\"sandbox\", { kind: \"dispatch-start\" });\n const empty = (): Usage => ({ input: 0, cached: 0, output: 0 });\n let previous = empty(),\n current = empty();\n const { telemetry: _telemetry, ...settings } = options;\n const observed: DispatchOptions<T> = {\n ...settings,\n observation,\n warn(message) {\n observation.emit(\"agent\", { kind: \"warning\", message });\n },\n observe(event) {\n if (event.kind === \"phase\" && event.name === \"preparing prompt\") {\n previous = addUsage(previous, current);\n current = empty();\n }\n if (event.kind === \"usage\") current = addUsage(current, event.tokens);\n if (event.kind === \"summary\") current = event.tokens;\n observation\n .child({\n pass: event.pass,\n ...(event.subagentId ? { subagentId: event.subagentId } : {}),\n })\n .emit(agentSource(options.agent), event);\n },\n };\n try {\n const result = await action(observed);\n observation.emit(\"sandbox\", {\n kind: \"dispatch-finished\",\n status: \"done\",\n completed: result.completed,\n usage: result.usage,\n ...(result.branch ? { branch: result.branch } : {}),\n ...(result.commits ? { commits: result.commits } : {}),\n });\n try {\n session?.finish({\n status: \"done\",\n usage: result.usage,\n completed: result.completed,\n });\n } catch (error) {\n failures.push(error);\n }\n await finish();\n return {\n ...result,\n ...(log?.reference ? { logReference: log.reference } : {}),\n observerErrors: [...failures, ...observation.errors],\n };\n } catch (error) {\n const cancelled =\n options.signal?.aborted ||\n (error instanceof OutpostError && error.code === \"aborted\") ||\n (error instanceof Error && error.name === \"AbortError\");\n const status = cancelled ? \"cancelled\" : \"failed\";\n const usage = addUsage(previous, current);\n const recovery = recoveryDetails(error);\n observation.emit(\"sandbox\", {\n kind: \"dispatch-finished\",\n status,\n completed: false,\n ...(typeof recovery?.branch === \"string\"\n ? { branch: recovery.branch }\n : {}),\n ...(Array.isArray(recovery?.commits) && recovery.commits.every(isCommit)\n ? { commits: recovery.commits }\n : {}),\n usage,\n error: {\n ...(error instanceof OutpostError ? { code: error.code } : {}),\n message: error instanceof Error ? error.message : String(error),\n },\n });\n try {\n session?.finish({ status, usage });\n } catch (failure) {\n failures.push(failure);\n }\n await finish();\n recordRecovery(error, {\n observerErrors: [...failures, ...observation.errors],\n ...(log?.reference ? { logReference: log.reference } : {}),\n });\n throw error;\n }\n async function finish(): Promise<void> {\n await observation.close();\n active.delete(observation);\n }\n}\n\nfunction agentSource(agent: Agent | undefined): ObservationSource {\n if (agent?.kind === \"replay\") return agent.source;\n return agent?.kind === \"custom\" ? \"harness\" : \"agent\";\n}\n\nfunction isCommit(\n value: unknown,\n): value is import(\"../domain/workspace.types.ts\").Commit {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"oid\" in value &&\n typeof value.oid === \"string\" &&\n \"subject\" in value &&\n typeof value.subject === \"string\"\n );\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { QuotaFault } from "../domain/quota.types.ts";
|
|
1
2
|
import type { ObservationHub } from "../domain/observation.types.ts";
|
|
2
3
|
import type { TransportReference } from "../domain/transport.types.ts";
|
|
3
4
|
import type { Agent, AgentObservation, Usage } from "../domain/agent.types.ts";
|
|
@@ -49,6 +50,7 @@ export interface AgentOutput {
|
|
|
49
50
|
recordUsage(tokens: Usage, cumulative?: boolean): void;
|
|
50
51
|
setUsageBaseline(tokens: Usage | undefined): void;
|
|
51
52
|
readonly failure: string | undefined;
|
|
53
|
+
readonly quota: QuotaFault | undefined;
|
|
52
54
|
readonly completed: boolean;
|
|
53
55
|
readonly conversation: string | undefined;
|
|
54
56
|
append(chunk: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution.types.js","sourceRoot":"","sources":["../../src/application/execution.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ObservationHub } from \"../domain/observation.types.ts\";\nimport type { TransportReference } from \"../domain/transport.types.ts\";\nimport type { Agent, AgentObservation, Usage } from \"../domain/agent.types.ts\";\nimport type { DispatchTelemetry } from \"../domain/dispatch-telemetry.types.ts\";\nimport type { Brief } from \"../domain/prompts.types.ts\";\nimport type { ResponseSpec } from \"../domain/response.types.ts\";\nimport type { Logging } from \"../infrastructure/journal.types.ts\";\n\nexport interface DispatchOptions<T = undefined> {\n readonly observation?: ObservationHub;\n readonly agent?: Agent;\n readonly logging?: Logging;\n readonly label?: string;\n readonly brief: Brief;\n readonly passes?: number;\n readonly until?: string | readonly string[];\n readonly idleMs?: number;\n readonly idleWarningMs?: number;\n readonly settleMs?: number;\n readonly deadlineMs?: number;\n readonly expansionMs?: number;\n readonly signal?: AbortSignal;\n readonly continuation?: { readonly id: string; readonly fork?: boolean };\n readonly response?: ResponseSpec<T>;\n readonly telemetry?: DispatchTelemetry;\n readonly observe?: (event: AgentObservation) => void;\n readonly warn?: (message: string) => void;\n readonly diagnostic?: (message: string) => void;\n}\n\nexport interface TurnContext {\n readonly repository: string;\n readonly repair: boolean;\n}\n\nexport interface Turn {\n readonly text: string;\n readonly status: number;\n readonly conversation?: string;\n readonly transcript?: string;\n readonly transcriptReference?: TransportReference;\n readonly usage: Usage;\n readonly durationMs: number;\n}\n\nexport interface AgentOutput {\n readonly usage: Usage;\n readonly reportedUsage: boolean;\n readonly finalUsage: boolean;\n recordUsage(tokens: Usage, cumulative?: boolean): void;\n setUsageBaseline(tokens: Usage | undefined): void;\n readonly failure: string | undefined;\n readonly completed: boolean;\n readonly conversation: string | undefined;\n append(chunk: string): void;\n flush(): void;\n result(): Pick<Turn, \"text\" | \"usage\" | \"conversation\">;\n}\n\nexport interface ActivityWatchdog {\n refresh(completed: boolean): void;\n hold(): () => void;\n close(): void;\n}\n\nexport interface Execution<T> {\n readonly text: string;\n readonly turns: readonly Turn[];\n readonly usage: Usage;\n readonly conversation?: string;\n readonly value: T;\n readonly completed: boolean;\n readonly completion?: string;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"execution.types.js","sourceRoot":"","sources":["../../src/application/execution.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { QuotaFault } from \"../domain/quota.types.ts\";\nimport type { ObservationHub } from \"../domain/observation.types.ts\";\nimport type { TransportReference } from \"../domain/transport.types.ts\";\nimport type { Agent, AgentObservation, Usage } from \"../domain/agent.types.ts\";\nimport type { DispatchTelemetry } from \"../domain/dispatch-telemetry.types.ts\";\nimport type { Brief } from \"../domain/prompts.types.ts\";\nimport type { ResponseSpec } from \"../domain/response.types.ts\";\nimport type { Logging } from \"../infrastructure/journal.types.ts\";\n\nexport interface DispatchOptions<T = undefined> {\n readonly observation?: ObservationHub;\n readonly agent?: Agent;\n readonly logging?: Logging;\n readonly label?: string;\n readonly brief: Brief;\n readonly passes?: number;\n readonly until?: string | readonly string[];\n readonly idleMs?: number;\n readonly idleWarningMs?: number;\n readonly settleMs?: number;\n readonly deadlineMs?: number;\n readonly expansionMs?: number;\n readonly signal?: AbortSignal;\n readonly continuation?: { readonly id: string; readonly fork?: boolean };\n readonly response?: ResponseSpec<T>;\n readonly telemetry?: DispatchTelemetry;\n readonly observe?: (event: AgentObservation) => void;\n readonly warn?: (message: string) => void;\n readonly diagnostic?: (message: string) => void;\n}\n\nexport interface TurnContext {\n readonly repository: string;\n readonly repair: boolean;\n}\n\nexport interface Turn {\n readonly text: string;\n readonly status: number;\n readonly conversation?: string;\n readonly transcript?: string;\n readonly transcriptReference?: TransportReference;\n readonly usage: Usage;\n readonly durationMs: number;\n}\n\nexport interface AgentOutput {\n readonly usage: Usage;\n readonly reportedUsage: boolean;\n readonly finalUsage: boolean;\n recordUsage(tokens: Usage, cumulative?: boolean): void;\n setUsageBaseline(tokens: Usage | undefined): void;\n readonly failure: string | undefined;\n readonly quota: QuotaFault | undefined;\n readonly completed: boolean;\n readonly conversation: string | undefined;\n append(chunk: string): void;\n flush(): void;\n result(): Pick<Turn, \"text\" | \"usage\" | \"conversation\">;\n}\n\nexport interface ActivityWatchdog {\n refresh(completed: boolean): void;\n hold(): () => void;\n close(): void;\n}\n\nexport interface Execution<T> {\n readonly text: string;\n readonly turns: readonly Turn[];\n readonly usage: Usage;\n readonly conversation?: string;\n readonly value: T;\n readonly completed: boolean;\n readonly completion?: string;\n}\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { TaskContext } from "../domain/workflow.types.ts";
|
|
2
|
+
import type { InteractiveAgentTaskOptions, InteractiveAgentState, InteractiveAgentTurnResult } from "./interactive-task.types.ts";
|
|
3
|
+
export declare function executeInteractiveTurn(options: InteractiveAgentTaskOptions, context: TaskContext, branch: string, previous: InteractiveAgentState | undefined): Promise<InteractiveAgentTurnResult>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { invariant } from "../domain/errors.js";
|
|
2
|
+
import { createSandbox } from "./sandbox.js";
|
|
3
|
+
import { openWorkspace } from "./workspace.js";
|
|
4
|
+
import { taskUsage } from "./task-usage.js";
|
|
5
|
+
import { interactiveTurnInstructions } from "./interactive-task.constants.js";
|
|
6
|
+
import { interactiveResponse } from "./interactive-task-protocol.js";
|
|
7
|
+
import { quotaResumeInstructions } from "./quota-resume.constants.js";
|
|
8
|
+
export async function executeInteractiveTurn(options, context, branch, previous) {
|
|
9
|
+
const interaction = context.interaction;
|
|
10
|
+
const workspace = await openWorkspace({
|
|
11
|
+
repository: options.repository,
|
|
12
|
+
branch: { mode: "named", name: branch },
|
|
13
|
+
signal: context.signal,
|
|
14
|
+
...(context.observation ? { observation: context.observation } : {}),
|
|
15
|
+
});
|
|
16
|
+
try {
|
|
17
|
+
if (previous)
|
|
18
|
+
invariant(previous.directory === workspace.directory, "Interactive workspace moved; recover it explicitly");
|
|
19
|
+
const state = previous ?? {
|
|
20
|
+
turns: 0,
|
|
21
|
+
branch,
|
|
22
|
+
directory: workspace.directory,
|
|
23
|
+
};
|
|
24
|
+
await interaction.save(state);
|
|
25
|
+
const sandbox = await createSandbox({
|
|
26
|
+
workspace,
|
|
27
|
+
signal: context.signal,
|
|
28
|
+
...(context.observation ? { observation: context.observation } : {}),
|
|
29
|
+
agent: options.agent,
|
|
30
|
+
includeUncommitted: true,
|
|
31
|
+
...(options.sandboxProvider
|
|
32
|
+
? { sandboxProvider: options.sandboxProvider }
|
|
33
|
+
: {}),
|
|
34
|
+
...(options.bootstrap !== undefined
|
|
35
|
+
? { bootstrap: options.bootstrap }
|
|
36
|
+
: {}),
|
|
37
|
+
...(options.conversationHome
|
|
38
|
+
? { conversationHome: options.conversationHome }
|
|
39
|
+
: {}),
|
|
40
|
+
});
|
|
41
|
+
try {
|
|
42
|
+
const usage = taskUsage(context, undefined);
|
|
43
|
+
const interrupted = context.quota?.conversation;
|
|
44
|
+
const conversation = interrupted ?? state.conversation;
|
|
45
|
+
const input = interrupted
|
|
46
|
+
? quotaResumeInstructions
|
|
47
|
+
: state.conversation
|
|
48
|
+
? `Human answer (JSON): ${JSON.stringify(interaction.answer.value)}`
|
|
49
|
+
: options.brief;
|
|
50
|
+
const result = await sandbox.dispatch({
|
|
51
|
+
brief: { text: `${input}\n\n${interactiveTurnInstructions}` },
|
|
52
|
+
response: interactiveResponse,
|
|
53
|
+
signal: context.signal,
|
|
54
|
+
...(context.observation ? { observation: context.observation } : {}),
|
|
55
|
+
observe: usage.observe,
|
|
56
|
+
...(conversation ? { continuation: { id: conversation } } : {}),
|
|
57
|
+
});
|
|
58
|
+
usage.reconcile(result.usage);
|
|
59
|
+
context.signal.throwIfAborted();
|
|
60
|
+
invariant(result.conversation && result.transcript, "Interactive turn did not capture a portable conversation");
|
|
61
|
+
const next = {
|
|
62
|
+
...state,
|
|
63
|
+
conversation: result.conversation,
|
|
64
|
+
turns: state.turns + 1,
|
|
65
|
+
};
|
|
66
|
+
return { next, value: result.value };
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
await sandbox.close({ preserve: true });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
await workspace.close({ preserve: true });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=interactive-task-execution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-task-execution.js","sourceRoot":"","sources":["../../src/application/interactive-task-execution.ts"],"names":[],"mappings":"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","sourcesContent":["import { invariant } from \"../domain/errors.ts\";\nimport type { TaskContext } from \"../domain/workflow.types.ts\";\nimport { createSandbox } from \"./sandbox.ts\";\nimport { openWorkspace } from \"./workspace.ts\";\nimport { taskUsage } from \"./task-usage.ts\";\nimport { interactiveTurnInstructions } from \"./interactive-task.constants.ts\";\nimport { interactiveResponse } from \"./interactive-task-protocol.ts\";\nimport { quotaResumeInstructions } from \"./quota-resume.constants.ts\";\nimport type {\n InteractiveAgentTaskOptions,\n InteractiveAgentState,\n InteractiveAgentTurnResult,\n} from \"./interactive-task.types.ts\";\n\nexport async function executeInteractiveTurn(\n options: InteractiveAgentTaskOptions,\n context: TaskContext,\n branch: string,\n previous: InteractiveAgentState | undefined,\n): Promise<InteractiveAgentTurnResult> {\n const interaction = context.interaction!;\n const workspace = await openWorkspace({\n repository: options.repository,\n branch: { mode: \"named\", name: branch },\n signal: context.signal,\n ...(context.observation ? { observation: context.observation } : {}),\n });\n try {\n if (previous)\n invariant(\n previous.directory === workspace.directory,\n \"Interactive workspace moved; recover it explicitly\",\n );\n const state: InteractiveAgentState = previous ?? {\n turns: 0,\n branch,\n directory: workspace.directory,\n };\n await interaction.save(state);\n const sandbox = await createSandbox({\n workspace,\n signal: context.signal,\n ...(context.observation ? { observation: context.observation } : {}),\n agent: options.agent,\n includeUncommitted: true,\n ...(options.sandboxProvider\n ? { sandboxProvider: options.sandboxProvider }\n : {}),\n ...(options.bootstrap !== undefined\n ? { bootstrap: options.bootstrap }\n : {}),\n ...(options.conversationHome\n ? { conversationHome: options.conversationHome }\n : {}),\n });\n try {\n const usage = taskUsage(context, undefined);\n const interrupted = context.quota?.conversation;\n const conversation = interrupted ?? state.conversation;\n const input = interrupted\n ? quotaResumeInstructions\n : state.conversation\n ? `Human answer (JSON): ${JSON.stringify(interaction.answer!.value)}`\n : options.brief;\n const result = await sandbox.dispatch({\n brief: { text: `${input}\\n\\n${interactiveTurnInstructions}` },\n response: interactiveResponse,\n signal: context.signal,\n ...(context.observation ? { observation: context.observation } : {}),\n observe: usage.observe,\n ...(conversation ? { continuation: { id: conversation } } : {}),\n });\n usage.reconcile(result.usage);\n context.signal.throwIfAborted();\n invariant(\n result.conversation && result.transcript,\n \"Interactive turn did not capture a portable conversation\",\n );\n const next = {\n ...state,\n conversation: result.conversation,\n turns: state.turns + 1,\n };\n return { next, value: result.value };\n } finally {\n await sandbox.close({ preserve: true });\n }\n } finally {\n await workspace.close({ preserve: true });\n }\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { WorkflowJson } from "../domain/workflow/checkpoint.types.ts";
|
|
2
|
+
import type { InteractiveAgentState, InteractiveAgentTurn } from "./interactive-task.types.ts";
|
|
3
|
+
export declare const interactiveResponse: import("../domain/response.types.ts").ResponseSpec<InteractiveAgentTurn>;
|
|
4
|
+
export declare function interactiveState(value: WorkflowJson | undefined): InteractiveAgentState | undefined;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { invariant } from "../domain/errors.js";
|
|
2
|
+
import { response } from "../domain/response.js";
|
|
3
|
+
import { checkpointValue } from "../domain/workflow/checkpoint-value.js";
|
|
4
|
+
import { inputObject, validateInputQuestion, } from "../domain/workflow/input-validation.js";
|
|
5
|
+
export const interactiveResponse = response.json({
|
|
6
|
+
tag: "interaction",
|
|
7
|
+
repairs: 1,
|
|
8
|
+
schema(value) {
|
|
9
|
+
invariant(inputObject(value), "Interactive response must be an object");
|
|
10
|
+
if (value.kind === "question") {
|
|
11
|
+
validateInputQuestion(value);
|
|
12
|
+
return {
|
|
13
|
+
kind: "question",
|
|
14
|
+
question: value.question,
|
|
15
|
+
...(value.choices ? { choices: value.choices } : {}),
|
|
16
|
+
...(value.allowFreeText !== undefined
|
|
17
|
+
? { allowFreeText: value.allowFreeText }
|
|
18
|
+
: {}),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
invariant(value.kind === "completed" && Object.hasOwn(value, "output"), "Expected a question or completed output");
|
|
22
|
+
const output = checkpointValue(value.output);
|
|
23
|
+
invariant(output.kind === "json", "Interactive output must be lossless JSON");
|
|
24
|
+
return { kind: "completed", output: output.value };
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
export function interactiveState(value) {
|
|
28
|
+
if (value === undefined)
|
|
29
|
+
return undefined;
|
|
30
|
+
assertState(value);
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
function assertState(value) {
|
|
34
|
+
invariant(inputObject(value) &&
|
|
35
|
+
typeof value.turns === "number" &&
|
|
36
|
+
Number.isSafeInteger(value.turns) &&
|
|
37
|
+
value.turns >= 0 &&
|
|
38
|
+
typeof value.branch === "string" &&
|
|
39
|
+
!!value.branch &&
|
|
40
|
+
typeof value.directory === "string" &&
|
|
41
|
+
!!value.directory &&
|
|
42
|
+
(value.conversation === undefined ||
|
|
43
|
+
(typeof value.conversation === "string" && !!value.conversation)) &&
|
|
44
|
+
(value.turns === 0 || !!value.conversation), "Invalid interactive agent checkpoint state");
|
|
45
|
+
if (value.completed === undefined)
|
|
46
|
+
return;
|
|
47
|
+
const completed = value.completed;
|
|
48
|
+
invariant(inputObject(completed) &&
|
|
49
|
+
Object.hasOwn(completed, "output") &&
|
|
50
|
+
completed.conversation === value.conversation &&
|
|
51
|
+
completed.branch === value.branch &&
|
|
52
|
+
completed.directory === value.directory &&
|
|
53
|
+
completed.turns === value.turns, "Invalid completed interactive agent checkpoint");
|
|
54
|
+
checkpointValue(completed.output);
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=interactive-task-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-task-protocol.js","sourceRoot":"","sources":["../../src/application/interactive-task-protocol.ts"],"names":[],"mappings":"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","sourcesContent":["import { invariant } from \"../domain/errors.ts\";\nimport { response } from \"../domain/response.ts\";\nimport { checkpointValue } from \"../domain/workflow/checkpoint-value.ts\";\nimport {\n inputObject,\n validateInputQuestion,\n} from \"../domain/workflow/input-validation.ts\";\nimport type { WorkflowJson } from \"../domain/workflow/checkpoint.types.ts\";\nimport type {\n InteractiveAgentState,\n InteractiveAgentTurn,\n} from \"./interactive-task.types.ts\";\n\nexport const interactiveResponse = response.json<InteractiveAgentTurn>({\n tag: \"interaction\",\n repairs: 1,\n schema(value) {\n invariant(inputObject(value), \"Interactive response must be an object\");\n if (value.kind === \"question\") {\n validateInputQuestion(value);\n return {\n kind: \"question\",\n question: value.question,\n ...(value.choices ? { choices: value.choices } : {}),\n ...(value.allowFreeText !== undefined\n ? { allowFreeText: value.allowFreeText }\n : {}),\n };\n }\n invariant(\n value.kind === \"completed\" && Object.hasOwn(value, \"output\"),\n \"Expected a question or completed output\",\n );\n const output = checkpointValue(value.output);\n invariant(\n output.kind === \"json\",\n \"Interactive output must be lossless JSON\",\n );\n return { kind: \"completed\", output: output.value };\n },\n});\n\nexport function interactiveState(\n value: WorkflowJson | undefined,\n): InteractiveAgentState | undefined {\n if (value === undefined) return undefined;\n assertState(value);\n return value;\n}\n\nfunction assertState(value: unknown): asserts value is InteractiveAgentState {\n invariant(\n inputObject(value) &&\n typeof value.turns === \"number\" &&\n Number.isSafeInteger(value.turns) &&\n value.turns >= 0 &&\n typeof value.branch === \"string\" &&\n !!value.branch &&\n typeof value.directory === \"string\" &&\n !!value.directory &&\n (value.conversation === undefined ||\n (typeof value.conversation === \"string\" && !!value.conversation)) &&\n (value.turns === 0 || !!value.conversation),\n \"Invalid interactive agent checkpoint state\",\n );\n if (value.completed === undefined) return;\n const completed = value.completed;\n invariant(\n inputObject(completed) &&\n Object.hasOwn(completed, \"output\") &&\n completed.conversation === value.conversation &&\n completed.branch === value.branch &&\n completed.directory === value.directory &&\n completed.turns === value.turns,\n \"Invalid completed interactive agent checkpoint\",\n );\n checkpointValue(completed.output);\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const interactiveTaskDefaults: {
|
|
2
|
+
readonly maxTurns: 12;
|
|
3
|
+
};
|
|
4
|
+
export declare const interactiveTurnInstructions = "This is a durable interactive task. End each turn with exactly one JSON response inside <interaction> and </interaction>.\nWhen human input is needed, return {\"kind\":\"question\",\"question\":\"Your question\",\"choices\":[\"Optional choice\"],\"allowFreeText\":true}. Omit choices for free text. Set allowFreeText to false only when choices are supplied and the user must choose one.\nWhen the entire task is complete, return {\"kind\":\"completed\",\"output\":<your JSON result>}.\nAsk one focused question at a time and adapt subsequent questions to the answers in this conversation. Do not invent a human answer. Do not wait for terminal input.\nThe sandbox is recreated between turns. Keep required project files in the repository. Do not switch branches, integrate or push changes. The workflow will retain the workspace.";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const interactiveTaskDefaults = { maxTurns: 12 };
|
|
2
|
+
export const interactiveTurnInstructions = `This is a durable interactive task. End each turn with exactly one JSON response inside <interaction> and </interaction>.
|
|
3
|
+
When human input is needed, return {"kind":"question","question":"Your question","choices":["Optional choice"],"allowFreeText":true}. Omit choices for free text. Set allowFreeText to false only when choices are supplied and the user must choose one.
|
|
4
|
+
When the entire task is complete, return {"kind":"completed","output":<your JSON result>}.
|
|
5
|
+
Ask one focused question at a time and adapt subsequent questions to the answers in this conversation. Do not invent a human answer. Do not wait for terminal input.
|
|
6
|
+
The sandbox is recreated between turns. Keep required project files in the repository. Do not switch branches, integrate or push changes. The workflow will retain the workspace.`;
|
|
7
|
+
//# sourceMappingURL=interactive-task.constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-task.constants.js","sourceRoot":"","sources":["../../src/application/interactive-task.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAW,CAAC;AAEjE,MAAM,CAAC,MAAM,2BAA2B,GAAG;;;;kLAIuI,CAAC","sourcesContent":["export const interactiveTaskDefaults = { maxTurns: 12 } as const;\n\nexport const interactiveTurnInstructions = `This is a durable interactive task. End each turn with exactly one JSON response inside <interaction> and </interaction>.\nWhen human input is needed, return {\"kind\":\"question\",\"question\":\"Your question\",\"choices\":[\"Optional choice\"],\"allowFreeText\":true}. Omit choices for free text. Set allowFreeText to false only when choices are supplied and the user must choose one.\nWhen the entire task is complete, return {\"kind\":\"completed\",\"output\":<your JSON result>}.\nAsk one focused question at a time and adapt subsequent questions to the answers in this conversation. Do not invent a human answer. Do not wait for terminal input.\nThe sandbox is recreated between turns. Keep required project files in the repository. Do not switch branches, integrate or push changes. The workflow will retain the workspace.`;\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { Task } from "../domain/workflow.types.ts";
|
|
2
|
+
import type { InteractiveAgentTaskOptions, InteractiveAgentResult } from "./interactive-task.types.ts";
|
|
3
|
+
export declare function interactiveAgentTask(options: InteractiveAgentTaskOptions): Task<InteractiveAgentResult>;
|