@elie-laloum/outpost 9.0.8 → 10.0.1
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 +29 -0
- package/README.md +1 -1
- package/SECURITY.md +1 -1
- package/dist/adapters/decisions/system-one-provider.constants.d.ts +2 -0
- package/dist/adapters/decisions/system-one-provider.constants.js +8 -0
- package/dist/adapters/decisions/system-one-provider.constants.js.map +1 -0
- package/dist/adapters/decisions/system-one-provider.d.ts +3 -0
- package/dist/adapters/decisions/system-one-provider.js +94 -0
- package/dist/adapters/decisions/system-one-provider.js.map +1 -0
- package/dist/adapters/decisions/system-one-provider.types.d.ts +6 -0
- package/dist/adapters/decisions/system-one-provider.types.js +2 -0
- package/dist/adapters/decisions/system-one-provider.types.js.map +1 -0
- package/dist/adapters/decisions/system-one-response.d.ts +2 -0
- package/dist/adapters/decisions/system-one-response.js +45 -0
- package/dist/adapters/decisions/system-one-response.js.map +1 -0
- package/dist/application/custom-turn.js +2 -0
- package/dist/application/custom-turn.js.map +1 -1
- package/dist/application/decision-task.d.ts +4 -0
- package/dist/application/decision-task.js +29 -0
- package/dist/application/decision-task.js.map +1 -0
- package/dist/application/decision.d.ts +4 -0
- package/dist/application/decision.js +101 -0
- package/dist/application/decision.js.map +1 -0
- package/dist/application/decision.types.d.ts +10 -0
- package/dist/application/decision.types.js +2 -0
- package/dist/application/decision.types.js.map +1 -0
- package/dist/application/dispatch-validation.js +3 -6
- package/dist/application/dispatch-validation.js.map +1 -1
- package/dist/application/execution.js +8 -17
- package/dist/application/execution.js.map +1 -1
- package/dist/application/harness-context.js +6 -0
- package/dist/application/harness-context.js.map +1 -1
- package/dist/application/harness-history.js +3 -0
- package/dist/application/harness-history.js.map +1 -1
- package/dist/application/harness-loop.js +8 -1
- package/dist/application/harness-loop.js.map +1 -1
- package/dist/application/harness-model-provider.js +0 -3
- package/dist/application/harness-model-provider.js.map +1 -1
- package/dist/application/harness-routing.d.ts +3 -0
- package/dist/application/harness-routing.js +88 -0
- package/dist/application/harness-routing.js.map +1 -0
- package/dist/application/harness-subagent.js +2 -0
- package/dist/application/harness-subagent.js.map +1 -1
- package/dist/application/harness.types.d.ts +4 -0
- package/dist/application/harness.types.js.map +1 -1
- package/dist/application/interactive-task-protocol.js +2 -0
- package/dist/application/interactive-task-protocol.js.map +1 -1
- package/dist/application/interactive-task.constants.d.ts +53 -0
- package/dist/application/interactive-task.constants.js +29 -0
- package/dist/application/interactive-task.constants.js.map +1 -1
- package/dist/application/replay-turn.js +19 -1
- package/dist/application/replay-turn.js.map +1 -1
- package/dist/application/steering-turns.js +12 -1
- package/dist/application/steering-turns.js.map +1 -1
- package/dist/application/workflow-job.js +4 -1
- package/dist/application/workflow-job.js.map +1 -1
- package/dist/domain/agent-observation.js +3 -0
- package/dist/domain/agent-observation.js.map +1 -1
- package/dist/domain/agent.types.d.ts +2 -1
- package/dist/domain/agent.types.js.map +1 -1
- package/dist/domain/decision-result.d.ts +6 -0
- package/dist/domain/decision-result.js +116 -0
- package/dist/domain/decision-result.js.map +1 -0
- package/dist/domain/decision.constants.d.ts +12 -0
- package/dist/domain/decision.constants.js +18 -0
- package/dist/domain/decision.constants.js.map +1 -0
- package/dist/domain/decision.d.ts +5 -0
- package/dist/domain/decision.js +75 -0
- package/dist/domain/decision.js.map +1 -0
- package/dist/domain/decision.types.d.ts +99 -0
- package/dist/domain/decision.types.js +2 -0
- package/dist/domain/decision.types.js.map +1 -0
- package/dist/domain/errors.types.d.ts +1 -1
- package/dist/domain/errors.types.js.map +1 -1
- package/dist/domain/harness-routing.constants.d.ts +2 -0
- package/dist/domain/harness-routing.constants.js +13 -0
- package/dist/domain/harness-routing.constants.js.map +1 -0
- package/dist/domain/harness-routing.d.ts +3 -0
- package/dist/domain/harness-routing.js +44 -0
- package/dist/domain/harness-routing.js.map +1 -0
- package/dist/domain/harness-routing.types.d.ts +45 -0
- package/dist/domain/harness-routing.types.js +2 -0
- package/dist/domain/harness-routing.types.js.map +1 -0
- package/dist/domain/harness.constants.js +1 -0
- package/dist/domain/harness.constants.js.map +1 -1
- package/dist/domain/harness.js +12 -0
- package/dist/domain/harness.js.map +1 -1
- package/dist/domain/harness.types.d.ts +3 -0
- package/dist/domain/harness.types.js.map +1 -1
- package/dist/domain/observation.types.d.ts +9 -2
- package/dist/domain/observation.types.js.map +1 -1
- package/dist/domain/replay.constants.d.ts +1 -0
- package/dist/domain/replay.constants.js +6 -0
- package/dist/domain/replay.constants.js.map +1 -1
- package/dist/domain/replay.js +61 -3
- package/dist/domain/replay.js.map +1 -1
- package/dist/domain/replay.types.d.ts +11 -0
- package/dist/domain/replay.types.js.map +1 -1
- package/dist/domain/response-instructions.d.ts +2 -0
- package/dist/domain/response-instructions.js +20 -0
- package/dist/domain/response-instructions.js.map +1 -0
- package/dist/domain/response-schema.d.ts +4 -0
- package/dist/domain/response-schema.js +46 -0
- package/dist/domain/response-schema.js.map +1 -0
- package/dist/domain/response.js +8 -3
- package/dist/domain/response.js.map +1 -1
- package/dist/domain/response.types.d.ts +10 -2
- package/dist/domain/response.types.js.map +1 -1
- package/dist/domain/standard-schema.constants.d.ts +1 -0
- package/dist/domain/standard-schema.constants.js +2 -0
- package/dist/domain/standard-schema.constants.js.map +1 -0
- package/dist/domain/standard-schema.js +1 -1
- package/dist/domain/standard-schema.js.map +1 -1
- package/dist/domain/tool.constants.d.ts +0 -1
- package/dist/domain/tool.constants.js +0 -1
- package/dist/domain/tool.constants.js.map +1 -1
- package/dist/domain/transcript.js +2 -1
- package/dist/domain/transcript.js.map +1 -1
- package/dist/domain/transcript.types.d.ts +5 -2
- package/dist/domain/transcript.types.js.map +1 -1
- package/dist/domain/workflow/failure.d.ts +2 -1
- package/dist/domain/workflow/failure.js +2 -0
- package/dist/domain/workflow/failure.js.map +1 -1
- package/dist/domain/workflow/gates.js +6 -1
- package/dist/domain/workflow/gates.js.map +1 -1
- package/dist/domain/workflow/loop-runner.js +8 -1
- package/dist/domain/workflow/loop-runner.js.map +1 -1
- package/dist/domain/workflow/task-runner.js +6 -2
- package/dist/domain/workflow/task-runner.js.map +1 -1
- package/dist/domain/workflow/termination.d.ts +3 -0
- package/dist/domain/workflow/termination.js +29 -0
- package/dist/domain/workflow/termination.js.map +1 -0
- package/dist/domain/workflow/workflow-scheduler.js +9 -18
- package/dist/domain/workflow/workflow-scheduler.js.map +1 -1
- package/dist/domain/workflow/workflow-state.js +6 -1
- package/dist/domain/workflow/workflow-state.js.map +1 -1
- package/dist/domain/workflow.d.ts +1 -1
- package/dist/domain/workflow.js.map +1 -1
- package/dist/domain/workflow.types.d.ts +5 -1
- package/dist/domain/workflow.types.js.map +1 -1
- package/dist/index.d.ts +11 -2
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/conversations/harness-transcript.js +24 -14
- package/dist/infrastructure/conversations/harness-transcript.js.map +1 -1
- package/dist/infrastructure/conversations/harness-transcript.types.d.ts +1 -0
- package/dist/infrastructure/conversations/harness-transcript.types.js.map +1 -1
- package/dist/infrastructure/journal.constants.js +2 -0
- package/dist/infrastructure/journal.constants.js.map +1 -1
- package/dist/providers/daytona.js +3 -0
- package/dist/providers/daytona.js.map +1 -1
- package/dist/providers/daytona.types.d.ts +1 -0
- package/dist/providers/daytona.types.js.map +1 -1
- package/dist/providers/vercel.js +3 -1
- package/dist/providers/vercel.js.map +1 -1
- package/dist/providers/vercel.types.d.ts +1 -0
- package/dist/providers/vercel.types.js.map +1 -1
- package/package.json +4 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch-validation.js","sourceRoot":"","sources":["../../src/application/dispatch-validation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dispatch-validation.js","sourceRoot":"","sources":["../../src/application/dispatch-validation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent } from \"../domain/agent.types.ts\";\nimport { invariant, positive } from \"../domain/errors.ts\";\nimport { validateBrief } from \"../domain/prompts.ts\";\nimport { responseInstructions } from \"../domain/response-instructions.ts\";\nimport { steeringChannel } from \"../domain/steering.ts\";\nimport { dispatchDeadlines, executionDefaults } from \"./execution.constants.ts\";\nimport type { DispatchOptions } from \"./execution.types.ts\";\n\nexport function validateDispatch(options: DispatchOptions<unknown>): void {\n options.signal?.throwIfAborted();\n if (options.steering) steeringChannel(options.steering);\n validateBrief(options.brief);\n if (options.response) responseInstructions(options.response);\n positive(options.passes ?? executionDefaults.passes, \"passes\");\n invariant(\n Number.isSafeInteger(options.passes ?? executionDefaults.passes),\n \"passes must be an integer\",\n );\n for (const key of dispatchDeadlines)\n if (options[key] !== undefined) positive(options[key], key);\n if (options.response || options.continuation)\n invariant(\n (options.passes ?? executionDefaults.passes) === 1,\n \"Structured responses and continuations require one pass\",\n );\n const markers =\n options.until === undefined\n ? []\n : typeof options.until === \"string\"\n ? [options.until]\n : options.until;\n invariant(\n markers.every((marker) => marker.length > 0),\n \"Completion markers cannot be empty\",\n );\n}\n\nexport async function preflightDispatch(\n options: DispatchOptions<unknown>,\n _repository: string,\n agent?: Agent,\n): Promise<void> {\n validateDispatch(options);\n if (options.steering && agent) validateSteering(agent);\n if (options.continuation)\n invariant(\n agent?.resumable !== false,\n `${agent?.name} does not support continuation or fork in Outpost`,\n );\n if (options.continuation?.fork)\n invariant(\n agent?.forkable !== false,\n `${agent?.name} does not support automated fork in Outpost`,\n );\n if (!options.response) return;\n if (options.response.repairs > 0)\n invariant(\n agent?.resumable ?? !!agent?.storage,\n \"Response repair requires an adapter that supports continuation\",\n );\n}\n\nfunction validateSteering(agent: Agent): void {\n invariant(\n agent.kind !== \"replay\",\n \"Replay agents reproduce a recording and cannot be steered\",\n );\n invariant(\n agent.kind === \"custom\" || agent.liveInput || agent.resumable,\n `${agent.name} cannot be steered: it accepts no live input and cannot resume its conversation`,\n );\n}\n"]}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { invariant } from "../domain/errors.js";
|
|
2
1
|
import { ResponseError } from "../domain/response.js";
|
|
3
2
|
import { addUsage } from "../domain/usage.js";
|
|
4
3
|
import { turn } from "./agent-turn.js";
|
|
@@ -36,23 +35,15 @@ export async function execute(workspace, lease, agent, host, options, afterTurn)
|
|
|
36
35
|
});
|
|
37
36
|
const prompt = repair ??
|
|
38
37
|
(await renderBrief(options.brief, workspace, lease, host, options));
|
|
39
|
-
if (options.response && !repair)
|
|
40
|
-
invariant(prompt.includes(`<${options.response.tag}>`), `Brief must request an opening <${options.response.tag}> tag`);
|
|
41
|
-
notify(options.observe, {
|
|
42
|
-
kind: "prompt",
|
|
43
|
-
text: prompt,
|
|
44
|
-
pass: index + 1,
|
|
45
|
-
at: new Date().toISOString(),
|
|
46
|
-
});
|
|
47
|
-
notify(options.observe, {
|
|
48
|
-
kind: "phase",
|
|
49
|
-
name: "running",
|
|
50
|
-
agent: agent.name,
|
|
51
|
-
branch: workspace.branch,
|
|
52
|
-
pass: index + 1,
|
|
53
|
-
at: new Date().toISOString(),
|
|
54
|
-
});
|
|
55
38
|
const steered = await steeringTurns(agent, options, prompt, continuation, index + 1, async (text, resumed) => {
|
|
39
|
+
notify(options.observe, {
|
|
40
|
+
kind: "phase",
|
|
41
|
+
name: "running",
|
|
42
|
+
agent: agent.name,
|
|
43
|
+
branch: workspace.branch,
|
|
44
|
+
pass: index + 1,
|
|
45
|
+
at: new Date().toISOString(),
|
|
46
|
+
});
|
|
56
47
|
const finished = await turn(lease, agent, text, options, resumed, markers, index + 1, { repository: workspace.repository, repair: repair !== undefined });
|
|
57
48
|
return afterTurn ? await afterTurn(finished) : finished;
|
|
58
49
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/application/execution.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent, Usage } from \"../domain/agent.types.ts\";\nimport { invariant } from \"../domain/errors.ts\";\nimport { ResponseError } from \"../domain/response.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport { addUsage } from \"../domain/usage.ts\";\nimport type { WorkspaceRecord } from \"../domain/workspace.types.ts\";\nimport { turn } from \"./agent-turn.ts\";\nimport { steeringTurns } from \"./steering-turns.ts\";\nimport { renderBrief } from \"./brief-renderer.ts\";\nimport { validateDispatch } from \"./dispatch-validation.ts\";\nimport { executionDefaults } from \"./execution.constants.ts\";\nimport type { DispatchOptions, Execution, Turn } from \"./execution.types.ts\";\nimport { notify } from \"./observation.ts\";\n\nexport { renderBrief } from \"./brief-renderer.ts\";\nexport { preflightDispatch, validateDispatch } from \"./dispatch-validation.ts\";\nexport type { DispatchOptions, Execution, Turn } from \"./execution.types.ts\";\nexport { notify } from \"./observation.ts\";\n\nexport async function execute<T>(\n workspace: WorkspaceRecord,\n lease: SandboxLease,\n agent: Agent,\n host: boolean,\n options: DispatchOptions<T>,\n afterTurn?: (turn: Turn) => Promise<Turn>,\n): Promise<Execution<T>> {\n validateDispatch(options);\n const markers =\n options.until === undefined\n ? [executionDefaults.completion]\n : typeof options.until === \"string\"\n ? [options.until]\n : options.until;\n const turns: Turn[] = [];\n let value: T = undefined as T,\n completed = false,\n continuation = options.continuation;\n let repair: string | undefined;\n const attempts = options.response\n ? 1 + options.response.repairs\n : (options.passes ?? executionDefaults.passes);\n for (let index = 0; index < attempts; index++) {\n options.signal?.throwIfAborted();\n notify(options.observe, {\n kind: \"phase\",\n name: \"preparing prompt\",\n agent: agent.name,\n branch: workspace.branch,\n directory: workspace.directory,\n pass: index + 1,\n at: new Date().toISOString(),\n });\n const prompt =\n repair ??\n (await renderBrief(options.brief, workspace, lease, host, options));\n if (options.response && !repair)\n invariant(\n prompt.includes(`<${options.response.tag}>`),\n `Brief must request an opening <${options.response.tag}> tag`,\n );\n notify(options.observe, {\n kind: \"prompt\",\n text: prompt,\n pass: index + 1,\n at: new Date().toISOString(),\n });\n notify(options.observe, {\n kind: \"phase\",\n name: \"running\",\n agent: agent.name,\n branch: workspace.branch,\n pass: index + 1,\n at: new Date().toISOString(),\n });\n const steered = await steeringTurns(\n agent,\n options,\n prompt,\n continuation,\n index + 1,\n async (text, resumed) => {\n const finished = await turn(\n lease,\n agent,\n text,\n options,\n resumed,\n markers,\n index + 1,\n { repository: workspace.repository, repair: repair !== undefined },\n );\n return afterTurn ? await afterTurn(finished) : finished;\n },\n );\n turns.push(...steered);\n const current = steered.at(-1)!;\n notify(options.observe, {\n kind: \"summary\",\n durationMs: steered.reduce((sum, item) => sum + item.durationMs, 0),\n status: current.status,\n tokens: steered.reduce((sum, item) => addUsage(sum, item.usage), {\n input: 0,\n cached: 0,\n output: 0,\n } as Usage),\n pass: index + 1,\n at: new Date().toISOString(),\n });\n completed = markers.some((marker) => current.text.includes(marker));\n if (options.response) {\n try {\n value = await options.response.read(current.text);\n completed = true;\n break;\n } catch (error) {\n if (!(error instanceof ResponseError)) throw error;\n error.recovery = {\n conversation: current.conversation,\n branch: workspace.branch,\n directory: workspace.directory,\n turns,\n };\n if (index + 1 >= attempts || !current.conversation) throw error;\n continuation = { id: current.conversation };\n repair = [\n `Correct the response inside <${options.response.tag}> and </${options.response.tag}>.`,\n `Validation failure: ${error.message}`,\n `Previous content: ${error.raw ?? \"No complete tagged response was returned.\"}`,\n `Cause: ${error.cause instanceof Error ? error.cause.message : (JSON.stringify(error.cause) ?? \"unspecified\")}`,\n `Further repair attempts after this one: ${attempts - index - 2}.`,\n \"Do not edit files, run commands or continue implementation. Only return the corrected response.\",\n ].join(\"\\n\");\n }\n }\n if (!options.response && completed) break;\n }\n const conversation = turns.at(-1)?.conversation;\n const completion = markers.find((marker) =>\n turns.at(-1)?.text.includes(marker),\n );\n return {\n text: turns.map((item) => item.text).join(\"\\n\"),\n turns,\n value,\n completed,\n ...(completion ? { completion } : {}),\n ...(conversation ? { conversation } : {}),\n usage: turns.reduce((sum, item) => addUsage(sum, item.usage), {\n input: 0,\n cached: 0,\n output: 0,\n } as Usage),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/application/execution.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent, Usage } from \"../domain/agent.types.ts\";\nimport { ResponseError } from \"../domain/response.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport { addUsage } from \"../domain/usage.ts\";\nimport type { WorkspaceRecord } from \"../domain/workspace.types.ts\";\nimport { turn } from \"./agent-turn.ts\";\nimport { steeringTurns } from \"./steering-turns.ts\";\nimport { renderBrief } from \"./brief-renderer.ts\";\nimport { validateDispatch } from \"./dispatch-validation.ts\";\nimport { executionDefaults } from \"./execution.constants.ts\";\nimport type { DispatchOptions, Execution, Turn } from \"./execution.types.ts\";\nimport { notify } from \"./observation.ts\";\n\nexport { renderBrief } from \"./brief-renderer.ts\";\nexport { preflightDispatch, validateDispatch } from \"./dispatch-validation.ts\";\nexport type { DispatchOptions, Execution, Turn } from \"./execution.types.ts\";\nexport { notify } from \"./observation.ts\";\n\nexport async function execute<T>(\n workspace: WorkspaceRecord,\n lease: SandboxLease,\n agent: Agent,\n host: boolean,\n options: DispatchOptions<T>,\n afterTurn?: (turn: Turn) => Promise<Turn>,\n): Promise<Execution<T>> {\n validateDispatch(options);\n const markers =\n options.until === undefined\n ? [executionDefaults.completion]\n : typeof options.until === \"string\"\n ? [options.until]\n : options.until;\n const turns: Turn[] = [];\n let value: T = undefined as T,\n completed = false,\n continuation = options.continuation;\n let repair: string | undefined;\n const attempts = options.response\n ? 1 + options.response.repairs\n : (options.passes ?? executionDefaults.passes);\n for (let index = 0; index < attempts; index++) {\n options.signal?.throwIfAborted();\n notify(options.observe, {\n kind: \"phase\",\n name: \"preparing prompt\",\n agent: agent.name,\n branch: workspace.branch,\n directory: workspace.directory,\n pass: index + 1,\n at: new Date().toISOString(),\n });\n const prompt =\n repair ??\n (await renderBrief(options.brief, workspace, lease, host, options));\n const steered = await steeringTurns(\n agent,\n options,\n prompt,\n continuation,\n index + 1,\n async (text, resumed) => {\n notify(options.observe, {\n kind: \"phase\",\n name: \"running\",\n agent: agent.name,\n branch: workspace.branch,\n pass: index + 1,\n at: new Date().toISOString(),\n });\n const finished = await turn(\n lease,\n agent,\n text,\n options,\n resumed,\n markers,\n index + 1,\n { repository: workspace.repository, repair: repair !== undefined },\n );\n return afterTurn ? await afterTurn(finished) : finished;\n },\n );\n turns.push(...steered);\n const current = steered.at(-1)!;\n notify(options.observe, {\n kind: \"summary\",\n durationMs: steered.reduce((sum, item) => sum + item.durationMs, 0),\n status: current.status,\n tokens: steered.reduce((sum, item) => addUsage(sum, item.usage), {\n input: 0,\n cached: 0,\n output: 0,\n } as Usage),\n pass: index + 1,\n at: new Date().toISOString(),\n });\n completed = markers.some((marker) => current.text.includes(marker));\n if (options.response) {\n try {\n value = await options.response.read(current.text);\n completed = true;\n break;\n } catch (error) {\n if (!(error instanceof ResponseError)) throw error;\n error.recovery = {\n conversation: current.conversation,\n branch: workspace.branch,\n directory: workspace.directory,\n turns,\n };\n if (index + 1 >= attempts || !current.conversation) throw error;\n continuation = { id: current.conversation };\n repair = [\n `Correct the response inside <${options.response.tag}> and </${options.response.tag}>.`,\n `Validation failure: ${error.message}`,\n `Previous content: ${error.raw ?? \"No complete tagged response was returned.\"}`,\n `Cause: ${error.cause instanceof Error ? error.cause.message : (JSON.stringify(error.cause) ?? \"unspecified\")}`,\n `Further repair attempts after this one: ${attempts - index - 2}.`,\n \"Do not edit files, run commands or continue implementation. Only return the corrected response.\",\n ].join(\"\\n\");\n }\n }\n if (!options.response && completed) break;\n }\n const conversation = turns.at(-1)?.conversation;\n const completion = markers.find((marker) =>\n turns.at(-1)?.text.includes(marker),\n );\n return {\n text: turns.map((item) => item.text).join(\"\\n\"),\n turns,\n value,\n completed,\n ...(completion ? { completion } : {}),\n ...(conversation ? { conversation } : {}),\n usage: turns.reduce((sum, item) => addUsage(sum, item.usage), {\n input: 0,\n cached: 0,\n output: 0,\n } as Usage),\n };\n}\n"]}
|
|
@@ -37,6 +37,12 @@ export async function compact(runtime, history, step) {
|
|
|
37
37
|
async function summarize(runtime, messages) {
|
|
38
38
|
const result = await runtime.modelProvider.request({
|
|
39
39
|
model: runtime.agent.model.name,
|
|
40
|
+
...(runtime.agent.model.reasoning === undefined
|
|
41
|
+
? {}
|
|
42
|
+
: { reasoning: runtime.agent.model.reasoning }),
|
|
43
|
+
...(runtime.agent.model.maxOutputTokens === undefined
|
|
44
|
+
? {}
|
|
45
|
+
: { maxOutputTokens: runtime.agent.model.maxOutputTokens }),
|
|
40
46
|
system: SUMMARY_INSTRUCTIONS,
|
|
41
47
|
prompt: messages.map(render).join("\n\n") || "(no earlier messages)",
|
|
42
48
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-context.js","sourceRoot":"","sources":["../../src/application/harness-context.ts"],"names":[],"mappings":"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","sourcesContent":["import { SUMMARY_INSTRUCTIONS } from \"../domain/context.constants.ts\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport { validateMessages } from \"../domain/model-messages.ts\";\nimport type { ModelContentBlock, ModelMessage } from \"../domain/model.types.ts\";\nimport type {\n BlockRenderers,\n HarnessHistory,\n HarnessRuntime,\n} from \"./harness.types.ts\";\n\nconst renderers: BlockRenderers = {\n text: (block) => block.text,\n \"tool-call\": (block) =>\n `[tool call ${block.name} ${JSON.stringify(block.input)}]`,\n \"tool-result\": (block) =>\n `[tool ${block.isError ? \"error\" : \"result\"}]\\n${block.content}`,\n reasoning: () => \"\",\n};\n\nexport async function compact(\n runtime: HarnessRuntime,\n history: HarnessHistory,\n step: number,\n): Promise<void> {\n const strategy = runtime.agent.harness.context;\n if (!strategy) return;\n const compacted = await strategy.compact({\n messages: history.messages,\n step,\n model: runtime.agent.model,\n signal: runtime.signal,\n summarize: (messages) => summarize(runtime, messages),\n });\n runtime.signal.throwIfAborted();\n if (compacted === undefined) return;\n validateMessages(compacted);\n const cleaned = compacted.map((message) => ({\n ...message,\n content: message.content.filter((block) => block.type !== \"reasoning\"),\n }));\n validateMessages(cleaned);\n await history.replace(cleaned);\n runtime.emit({\n kind: \"compaction\",\n strategy: strategy.name,\n messages: cleaned.length,\n });\n}\n\nasync function summarize(\n runtime: HarnessRuntime,\n messages: readonly ModelMessage[],\n): Promise<string> {\n const result = await runtime.modelProvider.request({\n model: runtime.agent.model.name,\n system: SUMMARY_INSTRUCTIONS,\n prompt: messages.map(render).join(\"\\n\\n\") || \"(no earlier messages)\",\n });\n if ((result.stopReason ?? \"end\") !== \"end\" || !result.text.trim())\n throw new OutpostError(\"response\", \"The model could not summarize history\");\n return result.text;\n}\n\nfunction render(message: ModelMessage): string {\n const body = message.content\n .map((block) =>\n (renderers[block.type] as (value: ModelContentBlock) => string)(block),\n )\n .filter(Boolean)\n .join(\"\\n\");\n return `${message.role === \"user\" ? \"User\" : \"Assistant\"}:\\n${body}`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"harness-context.js","sourceRoot":"","sources":["../../src/application/harness-context.ts"],"names":[],"mappings":"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","sourcesContent":["import { SUMMARY_INSTRUCTIONS } from \"../domain/context.constants.ts\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport { validateMessages } from \"../domain/model-messages.ts\";\nimport type { ModelContentBlock, ModelMessage } from \"../domain/model.types.ts\";\nimport type {\n BlockRenderers,\n HarnessHistory,\n HarnessRuntime,\n} from \"./harness.types.ts\";\n\nconst renderers: BlockRenderers = {\n text: (block) => block.text,\n \"tool-call\": (block) =>\n `[tool call ${block.name} ${JSON.stringify(block.input)}]`,\n \"tool-result\": (block) =>\n `[tool ${block.isError ? \"error\" : \"result\"}]\\n${block.content}`,\n reasoning: () => \"\",\n};\n\nexport async function compact(\n runtime: HarnessRuntime,\n history: HarnessHistory,\n step: number,\n): Promise<void> {\n const strategy = runtime.agent.harness.context;\n if (!strategy) return;\n const compacted = await strategy.compact({\n messages: history.messages,\n step,\n model: runtime.agent.model,\n signal: runtime.signal,\n summarize: (messages) => summarize(runtime, messages),\n });\n runtime.signal.throwIfAborted();\n if (compacted === undefined) return;\n validateMessages(compacted);\n const cleaned = compacted.map((message) => ({\n ...message,\n content: message.content.filter((block) => block.type !== \"reasoning\"),\n }));\n validateMessages(cleaned);\n await history.replace(cleaned);\n runtime.emit({\n kind: \"compaction\",\n strategy: strategy.name,\n messages: cleaned.length,\n });\n}\n\nasync function summarize(\n runtime: HarnessRuntime,\n messages: readonly ModelMessage[],\n): Promise<string> {\n const result = await runtime.modelProvider.request({\n model: runtime.agent.model.name,\n ...(runtime.agent.model.reasoning === undefined\n ? {}\n : { reasoning: runtime.agent.model.reasoning }),\n ...(runtime.agent.model.maxOutputTokens === undefined\n ? {}\n : { maxOutputTokens: runtime.agent.model.maxOutputTokens }),\n system: SUMMARY_INSTRUCTIONS,\n prompt: messages.map(render).join(\"\\n\\n\") || \"(no earlier messages)\",\n });\n if ((result.stopReason ?? \"end\") !== \"end\" || !result.text.trim())\n throw new OutpostError(\"response\", \"The model could not summarize history\");\n return result.text;\n}\n\nfunction render(message: ModelMessage): string {\n const body = message.content\n .map((block) =>\n (renderers[block.type] as (value: ModelContentBlock) => string)(block),\n )\n .filter(Boolean)\n .join(\"\\n\");\n return `${message.role === \"user\" ? \"User\" : \"Assistant\"}:\\n${body}`;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-history.js","sourceRoot":"","sources":["../../src/application/harness-history.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,cAAc,CAAC,UAA6B;IAC1D,IAAI,QAAQ,GAA4B,UAAU,EAAE,QAAQ,IAAI,EAAE,CAAC;IACnE,OAAO;QACL,IAAI,QAAQ;YACV,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,OAAO;YAClB,MAAM,UAAU,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;YACvD,QAAQ,GAAG,CAAC,GAAG,QAAQ,EAAE,OAAO,CAAC,CAAC;QACpC,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,IAAI;YAChB,MAAM,UAAU,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YACjE,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { ModelMessage } from \"../domain/model.types.ts\";\nimport type { TranscriptHandle } from \"../infrastructure/conversations/harness-transcript.types.ts\";\nimport type { HarnessHistory } from \"./harness.types.ts\";\n\nexport function harnessHistory(transcript?: TranscriptHandle): HarnessHistory {\n let messages: readonly ModelMessage[] = transcript?.messages ?? [];\n return {\n get messages() {\n return messages;\n },\n async append(message) {\n await transcript?.append({ type: \"message\", message });\n messages = [...messages, message];\n },\n async replace(next) {\n await transcript?.append({ type: \"compaction\", messages: next });\n messages = [...next];\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"harness-history.js","sourceRoot":"","sources":["../../src/application/harness-history.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,cAAc,CAAC,UAA6B;IAC1D,IAAI,QAAQ,GAA4B,UAAU,EAAE,QAAQ,IAAI,EAAE,CAAC;IACnE,OAAO;QACL,KAAK,CAAC,WAAW,CAAC,KAAK;YACrB,MAAM,UAAU,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;QAClE,CAAC;QACD,IAAI,QAAQ;YACV,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,OAAO;YAClB,MAAM,UAAU,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;YACvD,QAAQ,GAAG,CAAC,GAAG,QAAQ,EAAE,OAAO,CAAC,CAAC;QACpC,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,IAAI;YAChB,MAAM,UAAU,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;YACjE,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { ModelMessage } from \"../domain/model.types.ts\";\nimport type { TranscriptHandle } from \"../infrastructure/conversations/harness-transcript.types.ts\";\nimport type { HarnessHistory } from \"./harness.types.ts\";\n\nexport function harnessHistory(transcript?: TranscriptHandle): HarnessHistory {\n let messages: readonly ModelMessage[] = transcript?.messages ?? [];\n return {\n async recordRoute(event) {\n await transcript?.append({ type: \"model-selection\", ...event });\n },\n get messages() {\n return messages;\n },\n async append(message) {\n await transcript?.append({ type: \"message\", message });\n messages = [...messages, message];\n },\n async replace(next) {\n await transcript?.append({ type: \"compaction\", messages: next });\n messages = [...next];\n },\n };\n}\n"]}
|
|
@@ -3,6 +3,7 @@ import { loadedSkills } from "../domain/skill.js";
|
|
|
3
3
|
import { compact } from "./harness-context.js";
|
|
4
4
|
import { afterModel, beforeModel, sessionInstructions, stopRequest, } from "./harness-hooks.js";
|
|
5
5
|
import { executeToolCalls } from "./tool-execution.js";
|
|
6
|
+
import { routeHarnessModel } from "./harness-routing.js";
|
|
6
7
|
const stopHandlers = {
|
|
7
8
|
end: async (runtime, state, result, content) => {
|
|
8
9
|
const message = await stopRequest(runtime, result.text, state.step);
|
|
@@ -47,7 +48,7 @@ const stopHandlers = {
|
|
|
47
48
|
},
|
|
48
49
|
};
|
|
49
50
|
export async function harnessLoop(runtime, prompt, history) {
|
|
50
|
-
const { harness
|
|
51
|
+
const { harness } = runtime.agent;
|
|
51
52
|
const system = [
|
|
52
53
|
await instructions(runtime),
|
|
53
54
|
...(await sessionInstructions(runtime, prompt)),
|
|
@@ -77,9 +78,15 @@ export async function harnessLoop(runtime, prompt, history) {
|
|
|
77
78
|
runtime.emit({ kind: "skills-loaded", names: newlyLoaded });
|
|
78
79
|
runtime.emit({ kind: "step", index: step });
|
|
79
80
|
await compact(runtime, history, step);
|
|
81
|
+
const model = await routeHarnessModel(runtime, history, system, tools, step);
|
|
82
|
+
runtime = { ...runtime, agent: { ...runtime.agent, model } };
|
|
80
83
|
await beforeModel(runtime, history.messages, step);
|
|
81
84
|
const result = await requestModel(runtime, {
|
|
82
85
|
model: model.name,
|
|
86
|
+
...(model.reasoning === undefined ? {} : { reasoning: model.reasoning }),
|
|
87
|
+
...(model.maxOutputTokens === undefined
|
|
88
|
+
? {}
|
|
89
|
+
: { maxOutputTokens: model.maxOutputTokens }),
|
|
83
90
|
messages: history.messages,
|
|
84
91
|
...(system ? { system } : {}),
|
|
85
92
|
...(tools.length ? { tools } : {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-loop.js","sourceRoot":"","sources":["../../src/application/harness-loop.ts"],"names":[],"mappings":"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","sourcesContent":["import { OutpostError } from \"../domain/errors.ts\";\nimport type {\n ModelContentBlock,\n ModelRequest,\n ModelResult,\n ModelStopReason,\n ModelToolCallBlock,\n ModelToolSpec,\n} from \"../domain/model.types.ts\";\nimport { loadedSkills } from \"../domain/skill.ts\";\nimport type {\n HarnessHistory,\n HarnessRuntime,\n LoopState,\n StopHandler,\n} from \"./harness.types.ts\";\nimport { compact } from \"./harness-context.ts\";\nimport {\n afterModel,\n beforeModel,\n sessionInstructions,\n stopRequest,\n} from \"./harness-hooks.ts\";\nimport { executeToolCalls } from \"./tool-execution.ts\";\n\nconst stopHandlers: Readonly<Record<ModelStopReason, StopHandler>> = {\n end: async (runtime, state, result, content) => {\n const message = await stopRequest(runtime, result.text, state.step);\n await state.history.append({ role: \"assistant\", content });\n const instructions = steering(runtime);\n if (message === undefined && !instructions.length) return result.text;\n if (message !== undefined)\n runtime.emit({ kind: \"stop-prevented\", message });\n await state.history.append({\n role: \"user\",\n content: [\n ...(message === undefined\n ? []\n : [{ type: \"text\" as const, text: message }]),\n ...instructions,\n ],\n });\n return undefined;\n },\n \"max-tokens\": async (_runtime, state) => {\n throw new OutpostError(\n \"limit\",\n `Model output reached maxOutputTokens during step ${state.step}`,\n { limit: \"maxOutputTokens\", step: state.step },\n );\n },\n refusal: async (_runtime, state) => {\n throw new OutpostError(\"response\", \"The model refused to continue\", {\n step: state.step,\n });\n },\n \"tool-calls\": async (runtime, state, _result, content) => {\n const calls = content.filter(\n (block): block is ModelToolCallBlock => block.type === \"tool-call\",\n );\n state.toolCalls += calls.length;\n const { maxToolCalls } = runtime.agent.harness.limits;\n if (maxToolCalls !== undefined && state.toolCalls > maxToolCalls)\n throw limit(\n \"maxToolCalls\",\n `Harness exceeded ${maxToolCalls} tool calls`,\n );\n await state.history.append({ role: \"assistant\", content });\n const results = await executeToolCalls(\n runtime,\n calls,\n state.step,\n loadedSkills(state.history.messages),\n );\n await state.history.append({\n role: \"user\",\n content: [...results, ...steering(runtime)],\n });\n return undefined;\n },\n};\n\nexport async function harnessLoop(\n runtime: HarnessRuntime,\n prompt: string,\n history: HarnessHistory,\n): Promise<string> {\n const { harness, model } = runtime.agent;\n const system = [\n await instructions(runtime),\n ...(await sessionInstructions(runtime, prompt)),\n ]\n .filter((text) => text.trim())\n .join(\"\\n\\n\");\n const tools: ModelToolSpec[] = runtime.tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n }));\n await history.append({\n role: \"user\",\n content: [{ type: \"text\", text: prompt }, ...steering(runtime)],\n });\n let toolCalls = 0;\n const announcedSkills = new Set<string>();\n for (let step = 1; ; step++) {\n runtime.signal.throwIfAborted();\n if (step > harness.limits.maxSteps)\n throw limit(\n \"maxSteps\",\n `Harness reached ${harness.limits.maxSteps} steps without a final answer`,\n );\n runtime.budget.check();\n const newlyLoaded = [...loadedSkills(history.messages)].filter(\n (name) => !announcedSkills.has(name),\n );\n for (const name of newlyLoaded) announcedSkills.add(name);\n if (newlyLoaded.length)\n runtime.emit({ kind: \"skills-loaded\", names: newlyLoaded });\n runtime.emit({ kind: \"step\", index: step });\n await compact(runtime, history, step);\n await beforeModel(runtime, history.messages, step);\n const result = await requestModel(runtime, {\n model: model.name,\n messages: history.messages,\n ...(system ? { system } : {}),\n ...(tools.length ? { tools } : {}),\n ...(harness.cache ? { cache: true } : {}),\n });\n await afterModel(runtime, result, step);\n const content: readonly ModelContentBlock[] = result.content ?? [\n { type: \"text\", text: result.text },\n ];\n for (const block of content) {\n if (block.type === \"text\" && block.text)\n runtime.emit({ kind: \"text\", text: block.text });\n if (block.type === \"reasoning\" && block.text)\n runtime.emit({ kind: \"reasoning\", text: block.text });\n }\n const state: LoopState = { history, step, toolCalls };\n const reason = result.stopReason ?? inferredStop(content);\n const answer = await stopHandlers[reason](runtime, state, result, content);\n toolCalls = state.toolCalls;\n runtime.budget.check();\n if (answer !== undefined) return answer;\n }\n}\n\nasync function instructions(runtime: HarnessRuntime): Promise<string> {\n const texts = await Promise.all(\n runtime.agent.harness.instructions.map((entry) =>\n entry.resolve({\n sandbox: runtime.sandbox,\n signal: runtime.signal,\n model: runtime.agent.model,\n ...(runtime.mcp ? { mcp: runtime.mcp } : {}),\n }),\n ),\n );\n runtime.signal.throwIfAborted();\n runtime.emit({\n kind: \"instructions-loaded\",\n count: texts.filter((text) => text.trim()).length,\n });\n return texts.filter((text) => text.trim()).join(\"\\n\\n\");\n}\n\nfunction steering(runtime: HarnessRuntime): ModelContentBlock[] {\n const texts = runtime.steering?.take(runtime.subagentId) ?? [];\n for (const text of texts)\n runtime.emit({ kind: \"steer\", text, mode: \"injected\" });\n return texts.map((text) => ({ type: \"text\", text }));\n}\n\nfunction inferredStop(content: readonly ModelContentBlock[]): ModelStopReason {\n return content.some((block) => block.type === \"tool-call\")\n ? \"tool-calls\"\n : \"end\";\n}\n\nfunction limit(name: string, message: string): OutpostError {\n return new OutpostError(\"limit\", message, { limit: name });\n}\n\nasync function requestModel(\n runtime: HarnessRuntime,\n request: ModelRequest,\n): Promise<ModelResult> {\n const provider = runtime.modelProvider;\n if (runtime.verbose) runtime.emit({ kind: \"model-request\", request });\n try {\n const result = await receive();\n if (runtime.verbose)\n runtime.emit({ kind: \"model-response\", response: result });\n return result;\n } catch (error) {\n runtime.emit({\n kind: \"model-error\",\n message: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n async function receive(): Promise<ModelResult> {\n if (!provider.stream) return provider.request(request);\n let result: ModelResult | undefined;\n for await (const event of provider.stream(request)) {\n if (event.type === \"text-delta\")\n runtime.emit({ kind: \"text-delta\", text: event.text });\n if (event.type === \"reasoning\")\n runtime.emit({ kind: \"reasoning\", text: event.text });\n if (event.type === \"retry\")\n runtime.emit({\n kind: \"model-retry\",\n attempt: event.attempt,\n ...(event.message ? { message: event.message } : {}),\n });\n if (event.type === \"result\") result = event.result;\n }\n if (!result)\n throw new OutpostError(\"response\", \"Model stream ended without a result\");\n return result;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"harness-loop.js","sourceRoot":"","sources":["../../src/application/harness-loop.ts"],"names":[],"mappings":"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","sourcesContent":["import { OutpostError } from \"../domain/errors.ts\";\nimport type {\n ModelContentBlock,\n ModelRequest,\n ModelResult,\n ModelStopReason,\n ModelToolCallBlock,\n ModelToolSpec,\n} from \"../domain/model.types.ts\";\nimport { loadedSkills } from \"../domain/skill.ts\";\nimport type {\n HarnessHistory,\n HarnessRuntime,\n LoopState,\n StopHandler,\n} from \"./harness.types.ts\";\nimport { compact } from \"./harness-context.ts\";\nimport {\n afterModel,\n beforeModel,\n sessionInstructions,\n stopRequest,\n} from \"./harness-hooks.ts\";\nimport { executeToolCalls } from \"./tool-execution.ts\";\nimport { routeHarnessModel } from \"./harness-routing.ts\";\n\nconst stopHandlers: Readonly<Record<ModelStopReason, StopHandler>> = {\n end: async (runtime, state, result, content) => {\n const message = await stopRequest(runtime, result.text, state.step);\n await state.history.append({ role: \"assistant\", content });\n const instructions = steering(runtime);\n if (message === undefined && !instructions.length) return result.text;\n if (message !== undefined)\n runtime.emit({ kind: \"stop-prevented\", message });\n await state.history.append({\n role: \"user\",\n content: [\n ...(message === undefined\n ? []\n : [{ type: \"text\" as const, text: message }]),\n ...instructions,\n ],\n });\n return undefined;\n },\n \"max-tokens\": async (_runtime, state) => {\n throw new OutpostError(\n \"limit\",\n `Model output reached maxOutputTokens during step ${state.step}`,\n { limit: \"maxOutputTokens\", step: state.step },\n );\n },\n refusal: async (_runtime, state) => {\n throw new OutpostError(\"response\", \"The model refused to continue\", {\n step: state.step,\n });\n },\n \"tool-calls\": async (runtime, state, _result, content) => {\n const calls = content.filter(\n (block): block is ModelToolCallBlock => block.type === \"tool-call\",\n );\n state.toolCalls += calls.length;\n const { maxToolCalls } = runtime.agent.harness.limits;\n if (maxToolCalls !== undefined && state.toolCalls > maxToolCalls)\n throw limit(\n \"maxToolCalls\",\n `Harness exceeded ${maxToolCalls} tool calls`,\n );\n await state.history.append({ role: \"assistant\", content });\n const results = await executeToolCalls(\n runtime,\n calls,\n state.step,\n loadedSkills(state.history.messages),\n );\n await state.history.append({\n role: \"user\",\n content: [...results, ...steering(runtime)],\n });\n return undefined;\n },\n};\n\nexport async function harnessLoop(\n runtime: HarnessRuntime,\n prompt: string,\n history: HarnessHistory,\n): Promise<string> {\n const { harness } = runtime.agent;\n const system = [\n await instructions(runtime),\n ...(await sessionInstructions(runtime, prompt)),\n ]\n .filter((text) => text.trim())\n .join(\"\\n\\n\");\n const tools: ModelToolSpec[] = runtime.tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n }));\n await history.append({\n role: \"user\",\n content: [{ type: \"text\", text: prompt }, ...steering(runtime)],\n });\n let toolCalls = 0;\n const announcedSkills = new Set<string>();\n for (let step = 1; ; step++) {\n runtime.signal.throwIfAborted();\n if (step > harness.limits.maxSteps)\n throw limit(\n \"maxSteps\",\n `Harness reached ${harness.limits.maxSteps} steps without a final answer`,\n );\n runtime.budget.check();\n const newlyLoaded = [...loadedSkills(history.messages)].filter(\n (name) => !announcedSkills.has(name),\n );\n for (const name of newlyLoaded) announcedSkills.add(name);\n if (newlyLoaded.length)\n runtime.emit({ kind: \"skills-loaded\", names: newlyLoaded });\n runtime.emit({ kind: \"step\", index: step });\n await compact(runtime, history, step);\n const model = await routeHarnessModel(\n runtime,\n history,\n system,\n tools,\n step,\n );\n runtime = { ...runtime, agent: { ...runtime.agent, model } };\n await beforeModel(runtime, history.messages, step);\n const result = await requestModel(runtime, {\n model: model.name,\n ...(model.reasoning === undefined ? {} : { reasoning: model.reasoning }),\n ...(model.maxOutputTokens === undefined\n ? {}\n : { maxOutputTokens: model.maxOutputTokens }),\n messages: history.messages,\n ...(system ? { system } : {}),\n ...(tools.length ? { tools } : {}),\n ...(harness.cache ? { cache: true } : {}),\n });\n await afterModel(runtime, result, step);\n const content: readonly ModelContentBlock[] = result.content ?? [\n { type: \"text\", text: result.text },\n ];\n for (const block of content) {\n if (block.type === \"text\" && block.text)\n runtime.emit({ kind: \"text\", text: block.text });\n if (block.type === \"reasoning\" && block.text)\n runtime.emit({ kind: \"reasoning\", text: block.text });\n }\n const state: LoopState = { history, step, toolCalls };\n const reason = result.stopReason ?? inferredStop(content);\n const answer = await stopHandlers[reason](runtime, state, result, content);\n toolCalls = state.toolCalls;\n runtime.budget.check();\n if (answer !== undefined) return answer;\n }\n}\n\nasync function instructions(runtime: HarnessRuntime): Promise<string> {\n const texts = await Promise.all(\n runtime.agent.harness.instructions.map((entry) =>\n entry.resolve({\n sandbox: runtime.sandbox,\n signal: runtime.signal,\n model: runtime.agent.model,\n ...(runtime.mcp ? { mcp: runtime.mcp } : {}),\n }),\n ),\n );\n runtime.signal.throwIfAborted();\n runtime.emit({\n kind: \"instructions-loaded\",\n count: texts.filter((text) => text.trim()).length,\n });\n return texts.filter((text) => text.trim()).join(\"\\n\\n\");\n}\n\nfunction steering(runtime: HarnessRuntime): ModelContentBlock[] {\n const texts = runtime.steering?.take(runtime.subagentId) ?? [];\n for (const text of texts)\n runtime.emit({ kind: \"steer\", text, mode: \"injected\" });\n return texts.map((text) => ({ type: \"text\", text }));\n}\n\nfunction inferredStop(content: readonly ModelContentBlock[]): ModelStopReason {\n return content.some((block) => block.type === \"tool-call\")\n ? \"tool-calls\"\n : \"end\";\n}\n\nfunction limit(name: string, message: string): OutpostError {\n return new OutpostError(\"limit\", message, { limit: name });\n}\n\nasync function requestModel(\n runtime: HarnessRuntime,\n request: ModelRequest,\n): Promise<ModelResult> {\n const provider = runtime.modelProvider;\n if (runtime.verbose) runtime.emit({ kind: \"model-request\", request });\n try {\n const result = await receive();\n if (runtime.verbose)\n runtime.emit({ kind: \"model-response\", response: result });\n return result;\n } catch (error) {\n runtime.emit({\n kind: \"model-error\",\n message: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n async function receive(): Promise<ModelResult> {\n if (!provider.stream) return provider.request(request);\n let result: ModelResult | undefined;\n for await (const event of provider.stream(request)) {\n if (event.type === \"text-delta\")\n runtime.emit({ kind: \"text-delta\", text: event.text });\n if (event.type === \"reasoning\")\n runtime.emit({ kind: \"reasoning\", text: event.text });\n if (event.type === \"retry\")\n runtime.emit({\n kind: \"model-retry\",\n attempt: event.attempt,\n ...(event.message ? { message: event.message } : {}),\n });\n if (event.type === \"result\") result = event.result;\n }\n if (!result)\n throw new OutpostError(\"response\", \"Model stream ended without a result\");\n return result;\n }\n}\n"]}
|
|
@@ -5,10 +5,7 @@ export function harnessModelProvider(scope) {
|
|
|
5
5
|
const scoped = (request) => {
|
|
6
6
|
signal.throwIfAborted();
|
|
7
7
|
budget.check();
|
|
8
|
-
const { reasoning, maxOutputTokens } = agent.model;
|
|
9
8
|
return {
|
|
10
|
-
...(reasoning === undefined ? {} : { reasoning }),
|
|
11
|
-
...(maxOutputTokens === undefined ? {} : { maxOutputTokens }),
|
|
12
9
|
...request,
|
|
13
10
|
signal,
|
|
14
11
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-model-provider.js","sourceRoot":"","sources":["../../src/application/harness-model-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAShD,MAAM,UAAU,oBAAoB,CAAC,KAAwB;IAC3D,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAC/C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;IAC7C,MAAM,MAAM,GAAG,CAAC,OAAqB,EAAgB,EAAE;QACrD,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,
|
|
1
|
+
{"version":3,"file":"harness-model-provider.js","sourceRoot":"","sources":["../../src/application/harness-model-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAShD,MAAM,UAAU,oBAAoB,CAAC,KAAwB;IAC3D,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAC/C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;IAC7C,MAAM,MAAM,GAAG,CAAC,OAAqB,EAAgB,EAAE;QACrD,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,OAAO;YACL,GAAG,OAAO;YACV,MAAM;SACP,CAAC;IACJ,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,CAAC,MAAmB,EAAe,EAAE;QACnD,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,SAAS,CACP,MAAM,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EACzC,iCAAiC,CAClC,CAAC;QACF,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACtB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IACF,KAAK,SAAS,CAAC,CAAC,MAAM,CACpB,OAAqB;QAErB,IAAI,MAAmB,CAAC;QACxB,KAAK,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC;YACH,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;gBAC5D,MAAM,CAAC,cAAc,EAAE,CAAC;gBACxB,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC5B,SAAS,CAAC,CAAC,QAAQ,EAAE,4CAA4C,CAAC,CAAC;oBACnE,QAAQ,GAAG,IAAI,CAAC;oBAChB,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;oBACxD,SAAS;gBACX,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,MAAM,EAAE,CAAC;QACX,CAAC;IACH,CAAC;IACD,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CACnB,KAAK,CACH,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAChC,OAAO,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CACjD,CACF;KACJ,CAAC;AACJ,CAAC","sourcesContent":["import { invariant } from \"../domain/errors.ts\";\nimport type {\n ModelProvider,\n ModelRequest,\n ModelResult,\n ModelStreamEvent,\n} from \"../domain/model.types.ts\";\nimport type { HarnessModelScope } from \"./harness-model-provider.types.ts\";\n\nexport function harnessModelProvider(scope: HarnessModelScope): ModelProvider {\n const { agent, signal, budget, track } = scope;\n const provider = agent.harness.modelProvider;\n const scoped = (request: ModelRequest): ModelRequest => {\n signal.throwIfAborted();\n budget.check();\n return {\n ...request,\n signal,\n };\n };\n const account = (result: ModelResult): ModelResult => {\n signal.throwIfAborted();\n invariant(\n result && typeof result.text === \"string\",\n \"Model provider must return text\",\n );\n scope.account(result);\n budget.account(result);\n return result;\n };\n async function* stream(\n request: ModelRequest,\n ): AsyncGenerator<ModelStreamEvent> {\n let finish!: () => void;\n track(new Promise<void>((resolve) => (finish = resolve)));\n try {\n let received = false;\n for await (const event of provider.stream!(scoped(request))) {\n signal.throwIfAborted();\n if (event.type === \"result\") {\n invariant(!received, \"Model stream returned more than one result\");\n received = true;\n yield { type: \"result\", result: account(event.result) };\n continue;\n }\n yield event;\n }\n } finally {\n finish();\n }\n }\n return {\n name: provider.name,\n ...(provider.stream ? { stream } : {}),\n request: (request) =>\n track(\n Promise.resolve().then(async () =>\n account(await provider.request(scoped(request))),\n ),\n ),\n };\n}\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { AgentModel, ModelToolSpec } from "../domain/model.types.ts";
|
|
2
|
+
import type { HarnessHistory, HarnessRuntime } from "./harness.types.ts";
|
|
3
|
+
export declare function routeHarnessModel(runtime: HarnessRuntime, history: HarnessHistory, system: string, tools: readonly ModelToolSpec[], step: number): Promise<AgentModel>;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { OutpostError } from "../domain/errors.js";
|
|
2
|
+
import { unavailableFault } from "../domain/unavailable.js";
|
|
3
|
+
import { executeDecision } from "./decision.js";
|
|
4
|
+
import { checkpointValue } from "../domain/workflow/checkpoint-value.js";
|
|
5
|
+
import { invariant } from "../domain/errors.js";
|
|
6
|
+
function routingState(context) {
|
|
7
|
+
const state = checkpointValue({
|
|
8
|
+
system: context.system,
|
|
9
|
+
step: context.step,
|
|
10
|
+
model: context.model,
|
|
11
|
+
tools: context.tools,
|
|
12
|
+
messages: context.messages.map((message) => ({
|
|
13
|
+
role: message.role,
|
|
14
|
+
content: message.content.filter((block) => block.type !== "reasoning"),
|
|
15
|
+
})),
|
|
16
|
+
});
|
|
17
|
+
invariant(state.kind === "json" &&
|
|
18
|
+
state.value !== null &&
|
|
19
|
+
typeof state.value === "object", "Routing state must be a JSON object");
|
|
20
|
+
return state.value;
|
|
21
|
+
}
|
|
22
|
+
export async function routeHarnessModel(runtime, history, system, tools, step) {
|
|
23
|
+
const routing = runtime.agent.harness.routing;
|
|
24
|
+
if (!routing)
|
|
25
|
+
return runtime.agent.model;
|
|
26
|
+
const context = {
|
|
27
|
+
system,
|
|
28
|
+
tools,
|
|
29
|
+
messages: history.messages,
|
|
30
|
+
step,
|
|
31
|
+
model: runtime.agent.model,
|
|
32
|
+
signal: runtime.signal,
|
|
33
|
+
};
|
|
34
|
+
const state = routing.state
|
|
35
|
+
? await routing.state(context)
|
|
36
|
+
: routingState(context);
|
|
37
|
+
runtime.signal.throwIfAborted();
|
|
38
|
+
runtime.budget.check();
|
|
39
|
+
let choice = routing.fallback;
|
|
40
|
+
let reason = "unavailable";
|
|
41
|
+
let confidence;
|
|
42
|
+
try {
|
|
43
|
+
const result = await runtime.modelScope.track(executeDecision({
|
|
44
|
+
provider: routing.provider,
|
|
45
|
+
model: routing.model,
|
|
46
|
+
decision: routing.decision,
|
|
47
|
+
state,
|
|
48
|
+
signal: runtime.signal,
|
|
49
|
+
...(runtime.observation ? { observation: runtime.observation } : {}),
|
|
50
|
+
}, {
|
|
51
|
+
account(usage) {
|
|
52
|
+
const receipt = { text: "", usage };
|
|
53
|
+
runtime.modelScope.account(receipt, runtime.subagentId);
|
|
54
|
+
runtime.budget.account(receipt);
|
|
55
|
+
},
|
|
56
|
+
}));
|
|
57
|
+
const answer = result.answers[routing.question];
|
|
58
|
+
if (!answer || answer.type !== "choice")
|
|
59
|
+
throw new OutpostError("response", "Routing response must contain a choice");
|
|
60
|
+
confidence = answer.confidence;
|
|
61
|
+
reason = confidence < routing.minConfidence ? "confidence" : "selected";
|
|
62
|
+
choice = reason === "confidence" ? routing.fallback : answer.choice;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
runtime.signal.throwIfAborted();
|
|
66
|
+
const recoverable = error instanceof OutpostError &&
|
|
67
|
+
(error.code === "timeout" ||
|
|
68
|
+
(error.code === "provider" && unavailableFault(error) !== undefined));
|
|
69
|
+
if (routing.onError === "fail" || !recoverable)
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
runtime.budget.check();
|
|
73
|
+
const model = routing.models[choice];
|
|
74
|
+
if (!model)
|
|
75
|
+
throw new OutpostError("response", "Routing selected an undeclared model");
|
|
76
|
+
const event = {
|
|
77
|
+
kind: "model-route",
|
|
78
|
+
step,
|
|
79
|
+
choice,
|
|
80
|
+
model,
|
|
81
|
+
reason,
|
|
82
|
+
...(confidence === undefined ? {} : { confidence }),
|
|
83
|
+
};
|
|
84
|
+
await history.recordRoute?.(event);
|
|
85
|
+
runtime.emit(event);
|
|
86
|
+
return model;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=harness-routing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-routing.js","sourceRoot":"","sources":["../../src/application/harness-routing.ts"],"names":[],"mappings":"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","sourcesContent":["import { OutpostError } from \"../domain/errors.ts\";\nimport { unavailableFault } from \"../domain/unavailable.ts\";\nimport type { AgentModel, ModelToolSpec } from \"../domain/model.types.ts\";\nimport type { DecisionState } from \"../domain/decision.types.ts\";\nimport type { ModelRouteEvent } from \"../domain/harness-routing.types.ts\";\nimport type { HarnessHistory, HarnessRuntime } from \"./harness.types.ts\";\nimport { executeDecision } from \"./decision.ts\";\nimport { checkpointValue } from \"../domain/workflow/checkpoint-value.ts\";\nimport { invariant } from \"../domain/errors.ts\";\nimport type { HarnessModelRoutingContext } from \"../domain/harness-routing.types.ts\";\n\nfunction routingState(context: HarnessModelRoutingContext): DecisionState {\n const state = checkpointValue({\n system: context.system,\n step: context.step,\n model: context.model,\n tools: context.tools,\n messages: context.messages.map((message) => ({\n role: message.role,\n content: message.content.filter((block) => block.type !== \"reasoning\"),\n })),\n });\n invariant(\n state.kind === \"json\" &&\n state.value !== null &&\n typeof state.value === \"object\",\n \"Routing state must be a JSON object\",\n );\n return state.value;\n}\n\nexport async function routeHarnessModel(\n runtime: HarnessRuntime,\n history: HarnessHistory,\n system: string,\n tools: readonly ModelToolSpec[],\n step: number,\n): Promise<AgentModel> {\n const routing = runtime.agent.harness.routing;\n if (!routing) return runtime.agent.model;\n const context = {\n system,\n tools,\n messages: history.messages,\n step,\n model: runtime.agent.model,\n signal: runtime.signal,\n };\n const state = routing.state\n ? await routing.state(context)\n : routingState(context);\n runtime.signal.throwIfAborted();\n runtime.budget.check();\n let choice = routing.fallback;\n let reason: ModelRouteEvent[\"reason\"] = \"unavailable\";\n let confidence: number | undefined;\n try {\n const result = await runtime.modelScope.track(\n executeDecision(\n {\n provider: routing.provider,\n model: routing.model,\n decision: routing.decision,\n state,\n signal: runtime.signal,\n ...(runtime.observation ? { observation: runtime.observation } : {}),\n },\n {\n account(usage) {\n const receipt = { text: \"\", usage };\n runtime.modelScope.account(receipt, runtime.subagentId);\n runtime.budget.account(receipt);\n },\n },\n ),\n );\n const answer = result.answers[routing.question];\n if (!answer || answer.type !== \"choice\")\n throw new OutpostError(\n \"response\",\n \"Routing response must contain a choice\",\n );\n confidence = answer.confidence;\n reason = confidence < routing.minConfidence ? \"confidence\" : \"selected\";\n choice = reason === \"confidence\" ? routing.fallback : answer.choice;\n } catch (error) {\n runtime.signal.throwIfAborted();\n const recoverable =\n error instanceof OutpostError &&\n (error.code === \"timeout\" ||\n (error.code === \"provider\" && unavailableFault(error) !== undefined));\n if (routing.onError === \"fail\" || !recoverable) throw error;\n }\n runtime.budget.check();\n const model = routing.models[choice];\n if (!model)\n throw new OutpostError(\"response\", \"Routing selected an undeclared model\");\n const event: ModelRouteEvent = {\n kind: \"model-route\",\n step,\n choice,\n model,\n reason,\n ...(confidence === undefined ? {} : { confidence }),\n };\n await history.recordRoute?.(event);\n runtime.emit(event);\n return model;\n}\n"]}
|
|
@@ -38,6 +38,7 @@ export async function runSubagent(runtime, tool, input, context) {
|
|
|
38
38
|
repository: runtime.repository,
|
|
39
39
|
store,
|
|
40
40
|
model: agent.model.name,
|
|
41
|
+
routed: Boolean(agent.harness.routing),
|
|
41
42
|
...(runtime.conversation
|
|
42
43
|
? { parentConversation: runtime.conversation }
|
|
43
44
|
: {}),
|
|
@@ -48,6 +49,7 @@ export async function runSubagent(runtime, tool, input, context) {
|
|
|
48
49
|
text = await withMcpTools(agent.harness, context.sandbox, context.signal, agent.harness.tools, (tools, mcp) => harnessLoop({
|
|
49
50
|
...runtime,
|
|
50
51
|
agent,
|
|
52
|
+
observation: runtime.observation?.child({ subagentId: id }),
|
|
51
53
|
mcp,
|
|
52
54
|
budget,
|
|
53
55
|
depth,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-subagent.js","sourceRoot":"","sources":["../../src/application/harness-subagent.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport { OutpostError, recordRecovery } from \"../domain/errors.ts\";\nimport { MAX_DELEGATION_DEPTH } from \"../domain/subagent.constants.ts\";\nimport type { HarnessSubagent } from \"../domain/subagent.types.ts\";\nimport type { HarnessToolContext } from \"../domain/tool.types.ts\";\nimport { openTranscript } from \"../infrastructure/conversations/harness-transcript.ts\";\nimport type { TranscriptHandle } from \"../infrastructure/conversations/harness-transcript.types.ts\";\nimport { storageFor } from \"./agent-storage.ts\";\nimport { harnessBudget } from \"./harness-budget.ts\";\nimport { harnessHistory } from \"./harness-history.ts\";\nimport { harnessLoop } from \"./harness-loop.ts\";\nimport { withMcpTools } from \"./harness-mcp.ts\";\nimport { harnessModelProvider } from \"./harness-model-provider.ts\";\nimport type { HarnessRuntime } from \"./harness.types.ts\";\n\nexport async function runSubagent(\n runtime: HarnessRuntime,\n tool: HarnessSubagent,\n input: unknown,\n context: HarnessToolContext,\n): Promise<string> {\n const validated = await tool.validate(input);\n if (\"issues\" in validated)\n throw new OutpostError(\"configuration\", validated.issues);\n if (runtime.depth >= runtime.maxDepth)\n throw new OutpostError(\n \"limit\",\n \"Harness reached its delegation depth limit\",\n { limit: \"maxDelegationDepth\" },\n );\n runtime.budget.check();\n const agent = tool.subagent;\n const budget = harnessBudget(agent.harness.limits, runtime.budget);\n const id = randomUUID();\n const depth = runtime.depth + 1;\n const store = storageFor(agent);\n let transcript: TranscriptHandle | undefined;\n let failure: unknown;\n let text = \"\";\n const lifecycle = (status: \"started\" | \"finished\" | \"failed\") =>\n runtime.emit({\n kind: \"subagent\",\n id,\n callId: context.callId,\n name: tool.name,\n status,\n ...(transcript ? { conversation: transcript.id } : {}),\n });\n try {\n transcript = store\n ? await openTranscript({\n repository: runtime.repository,\n store,\n model: agent.model.name,\n ...(runtime.conversation\n ? { parentConversation: runtime.conversation }\n : {}),\n parentCallId: context.callId,\n })\n : undefined;\n lifecycle(\"started\");\n text = await withMcpTools(\n agent.harness,\n context.sandbox,\n context.signal,\n agent.harness.tools,\n (tools, mcp) =>\n harnessLoop(\n {\n ...runtime,\n agent,\n mcp,\n budget,\n depth,\n maxDepth: Math.min(\n runtime.maxDepth,\n depth +\n (agent.harness.limits.maxDelegationDepth ??\n MAX_DELEGATION_DEPTH),\n ),\n conversation: transcript?.id,\n subagentId: id,\n tools,\n permissions: [\n ...runtime.permissions,\n ...(agent.harness.permissions ? [agent.harness.permissions] : []),\n ],\n sandbox: context.sandbox,\n signal: context.signal,\n modelProvider: harnessModelProvider({\n agent,\n signal: context.signal,\n budget,\n ...runtime.modelScope,\n account: (result) => runtime.modelScope.account(result, id),\n }),\n emit: (event) => {\n context.signal.throwIfAborted();\n runtime.emit({ ...event, subagentId: event.subagentId ?? id });\n },\n },\n validated.value.prompt,\n harnessHistory(transcript),\n ),\n );\n context.signal.throwIfAborted();\n } catch (error) {\n failure = error;\n }\n runtime.steering?.finish(id);\n try {\n if (transcript && store)\n await store.capture(transcript.id, {\n repository: runtime.repository,\n sandbox: context.sandbox,\n staging: join(\n runtime.repository,\n \".outpost\",\n \"conversations\",\n \"harness\",\n ),\n });\n } catch (error) {\n if (failure)\n recordRecovery(failure, {\n subagentCaptureError: error,\n conversation: transcript?.id,\n });\n failure ??= error;\n } finally {\n await transcript?.close();\n }\n if (failure) {\n if (!runtime.signal.aborted) lifecycle(\"failed\");\n throw failure;\n }\n context.signal.throwIfAborted();\n lifecycle(\"finished\");\n return JSON.stringify({\n text,\n ...(transcript ? { conversation: transcript.id } : {}),\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"harness-subagent.js","sourceRoot":"","sources":["../../src/application/harness-subagent.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport { OutpostError, recordRecovery } from \"../domain/errors.ts\";\nimport { MAX_DELEGATION_DEPTH } from \"../domain/subagent.constants.ts\";\nimport type { HarnessSubagent } from \"../domain/subagent.types.ts\";\nimport type { HarnessToolContext } from \"../domain/tool.types.ts\";\nimport { openTranscript } from \"../infrastructure/conversations/harness-transcript.ts\";\nimport type { TranscriptHandle } from \"../infrastructure/conversations/harness-transcript.types.ts\";\nimport { storageFor } from \"./agent-storage.ts\";\nimport { harnessBudget } from \"./harness-budget.ts\";\nimport { harnessHistory } from \"./harness-history.ts\";\nimport { harnessLoop } from \"./harness-loop.ts\";\nimport { withMcpTools } from \"./harness-mcp.ts\";\nimport { harnessModelProvider } from \"./harness-model-provider.ts\";\nimport type { HarnessRuntime } from \"./harness.types.ts\";\n\nexport async function runSubagent(\n runtime: HarnessRuntime,\n tool: HarnessSubagent,\n input: unknown,\n context: HarnessToolContext,\n): Promise<string> {\n const validated = await tool.validate(input);\n if (\"issues\" in validated)\n throw new OutpostError(\"configuration\", validated.issues);\n if (runtime.depth >= runtime.maxDepth)\n throw new OutpostError(\n \"limit\",\n \"Harness reached its delegation depth limit\",\n { limit: \"maxDelegationDepth\" },\n );\n runtime.budget.check();\n const agent = tool.subagent;\n const budget = harnessBudget(agent.harness.limits, runtime.budget);\n const id = randomUUID();\n const depth = runtime.depth + 1;\n const store = storageFor(agent);\n let transcript: TranscriptHandle | undefined;\n let failure: unknown;\n let text = \"\";\n const lifecycle = (status: \"started\" | \"finished\" | \"failed\") =>\n runtime.emit({\n kind: \"subagent\",\n id,\n callId: context.callId,\n name: tool.name,\n status,\n ...(transcript ? { conversation: transcript.id } : {}),\n });\n try {\n transcript = store\n ? await openTranscript({\n repository: runtime.repository,\n store,\n model: agent.model.name,\n routed: Boolean(agent.harness.routing),\n ...(runtime.conversation\n ? { parentConversation: runtime.conversation }\n : {}),\n parentCallId: context.callId,\n })\n : undefined;\n lifecycle(\"started\");\n text = await withMcpTools(\n agent.harness,\n context.sandbox,\n context.signal,\n agent.harness.tools,\n (tools, mcp) =>\n harnessLoop(\n {\n ...runtime,\n agent,\n observation: runtime.observation?.child({ subagentId: id }),\n mcp,\n budget,\n depth,\n maxDepth: Math.min(\n runtime.maxDepth,\n depth +\n (agent.harness.limits.maxDelegationDepth ??\n MAX_DELEGATION_DEPTH),\n ),\n conversation: transcript?.id,\n subagentId: id,\n tools,\n permissions: [\n ...runtime.permissions,\n ...(agent.harness.permissions ? [agent.harness.permissions] : []),\n ],\n sandbox: context.sandbox,\n signal: context.signal,\n modelProvider: harnessModelProvider({\n agent,\n signal: context.signal,\n budget,\n ...runtime.modelScope,\n account: (result) => runtime.modelScope.account(result, id),\n }),\n emit: (event) => {\n context.signal.throwIfAborted();\n runtime.emit({ ...event, subagentId: event.subagentId ?? id });\n },\n },\n validated.value.prompt,\n harnessHistory(transcript),\n ),\n );\n context.signal.throwIfAborted();\n } catch (error) {\n failure = error;\n }\n runtime.steering?.finish(id);\n try {\n if (transcript && store)\n await store.capture(transcript.id, {\n repository: runtime.repository,\n sandbox: context.sandbox,\n staging: join(\n runtime.repository,\n \".outpost\",\n \"conversations\",\n \"harness\",\n ),\n });\n } catch (error) {\n if (failure)\n recordRecovery(failure, {\n subagentCaptureError: error,\n conversation: transcript?.id,\n });\n failure ??= error;\n } finally {\n await transcript?.close();\n }\n if (failure) {\n if (!runtime.signal.aborted) lifecycle(\"failed\");\n throw failure;\n }\n context.signal.throwIfAborted();\n lifecycle(\"finished\");\n return JSON.stringify({\n text,\n ...(transcript ? { conversation: transcript.id } : {}),\n });\n}\n"]}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { HarnessMcpContext } from "../domain/harness.types.ts";
|
|
2
|
+
import type { ObservationHub } from "../domain/observation.types.ts";
|
|
3
|
+
import type { ModelRouteEvent } from "../domain/harness-routing.types.ts";
|
|
2
4
|
import type { HarnessBudget } from "./harness-budget.types.ts";
|
|
3
5
|
import type { HarnessPermissions } from "../domain/permissions.types.ts";
|
|
4
6
|
import type { HarnessModelScope } from "./harness-model-provider.types.ts";
|
|
@@ -8,6 +10,7 @@ import type { SandboxLease } from "../domain/sandbox.types.ts";
|
|
|
8
10
|
import type { HarnessTool } from "../domain/tool.types.ts";
|
|
9
11
|
import type { DispatchOptions, TurnContext } from "./execution.types.ts";
|
|
10
12
|
export interface HarnessRuntime {
|
|
13
|
+
readonly observation?: ObservationHub | undefined;
|
|
11
14
|
readonly verbose?: boolean;
|
|
12
15
|
readonly repository: string;
|
|
13
16
|
readonly conversation?: string | undefined;
|
|
@@ -49,6 +52,7 @@ export interface ToolOutcome {
|
|
|
49
52
|
readonly isError: boolean;
|
|
50
53
|
}
|
|
51
54
|
export interface HarnessHistory {
|
|
55
|
+
recordRoute?(event: ModelRouteEvent): Promise<void>;
|
|
52
56
|
readonly messages: readonly ModelMessage[];
|
|
53
57
|
append(message: ModelMessage): Promise<void>;
|
|
54
58
|
replace(messages: readonly ModelMessage[]): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness.types.js","sourceRoot":"","sources":["../../src/application/harness.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { HarnessMcpContext } from \"../domain/harness.types.ts\";\nimport type { HarnessBudget } from \"./harness-budget.types.ts\";\nimport type { HarnessPermissions } from \"../domain/permissions.types.ts\";\nimport type { HarnessModelScope } from \"./harness-model-provider.types.ts\";\nimport type { AgentEvent, CustomAgent } from \"../domain/agent.types.ts\";\nimport type {\n ModelContentBlock,\n ModelMessage,\n ModelProvider,\n ModelResult,\n ModelToolCallBlock,\n} from \"../domain/model.types.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport type { HarnessTool } from \"../domain/tool.types.ts\";\nimport type { DispatchOptions, TurnContext } from \"./execution.types.ts\";\n\nexport interface HarnessRuntime {\n readonly verbose?: boolean;\n readonly repository: string;\n readonly conversation?: string | undefined;\n readonly budget: HarnessBudget;\n readonly permissions: readonly HarnessPermissions[];\n readonly depth: number;\n readonly maxDepth: number;\n readonly modelScope: Pick<HarnessModelScope, \"track\" | \"account\">;\n readonly agent: CustomAgent;\n readonly tools: readonly HarnessTool[];\n readonly modelProvider: ModelProvider;\n readonly sandbox: SandboxLease;\n readonly mcp?: HarnessMcpContext | undefined;\n readonly signal: AbortSignal;\n /** Run id of the built-in subagent this loop runs, absent for the main loop. */\n readonly subagentId?: string | undefined;\n /** Steering intake shared with subagents so the active loop receives instructions. */\n readonly steering?: HarnessSteering | undefined;\n emit(event: AgentEvent): void;\n hold(): () => void;\n}\n\nexport interface HarnessSteering {\n /** Delivers and returns the instructions for the main loop or the given subagent. */\n take(subagent: string | undefined): readonly string[];\n /** Rejects instructions still addressed to a subagent run that ended. */\n finish(subagent: string): void;\n}\n\nexport interface ToolCallBatch {\n readonly concurrent: boolean;\n readonly calls: readonly PreparedCall[];\n}\n\nexport type ValidatedInput =\n { readonly value: unknown } | { readonly outcome: ToolOutcome };\n\nexport interface ToolOutcome {\n readonly content: string;\n readonly isError: boolean;\n}\n\nexport interface HarnessHistory {\n readonly messages: readonly ModelMessage[];\n append(message: ModelMessage): Promise<void>;\n replace(messages: readonly ModelMessage[]): Promise<void>;\n}\n\nexport interface CustomTurnContext extends TurnContext {\n readonly continuation?: DispatchOptions[\"continuation\"];\n}\n\nexport interface LoopState {\n readonly history: HarnessHistory;\n readonly step: number;\n toolCalls: number;\n}\n\nexport type StopHandler = (\n runtime: HarnessRuntime,\n state: LoopState,\n result: ModelResult,\n content: readonly ModelContentBlock[],\n) => Promise<string | undefined>;\n\nexport interface PreparedCall {\n readonly call: ModelToolCallBlock;\n readonly tool?: HarnessTool;\n readonly input?: unknown;\n readonly outcome?: ToolOutcome;\n}\n\nexport interface ToolDenial {\n readonly deny: string;\n}\n\nexport type BlockRenderers = {\n readonly [Type in ModelContentBlock[\"type\"]]: (\n block: Extract<ModelContentBlock, { type: Type }>,\n ) => string;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"harness.types.js","sourceRoot":"","sources":["../../src/application/harness.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { HarnessMcpContext } from \"../domain/harness.types.ts\";\nimport type { ObservationHub } from \"../domain/observation.types.ts\";\nimport type { ModelRouteEvent } from \"../domain/harness-routing.types.ts\";\nimport type { HarnessBudget } from \"./harness-budget.types.ts\";\nimport type { HarnessPermissions } from \"../domain/permissions.types.ts\";\nimport type { HarnessModelScope } from \"./harness-model-provider.types.ts\";\nimport type { AgentEvent, CustomAgent } from \"../domain/agent.types.ts\";\nimport type {\n ModelContentBlock,\n ModelMessage,\n ModelProvider,\n ModelResult,\n ModelToolCallBlock,\n} from \"../domain/model.types.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport type { HarnessTool } from \"../domain/tool.types.ts\";\nimport type { DispatchOptions, TurnContext } from \"./execution.types.ts\";\n\nexport interface HarnessRuntime {\n readonly observation?: ObservationHub | undefined;\n readonly verbose?: boolean;\n readonly repository: string;\n readonly conversation?: string | undefined;\n readonly budget: HarnessBudget;\n readonly permissions: readonly HarnessPermissions[];\n readonly depth: number;\n readonly maxDepth: number;\n readonly modelScope: Pick<HarnessModelScope, \"track\" | \"account\">;\n readonly agent: CustomAgent;\n readonly tools: readonly HarnessTool[];\n readonly modelProvider: ModelProvider;\n readonly sandbox: SandboxLease;\n readonly mcp?: HarnessMcpContext | undefined;\n readonly signal: AbortSignal;\n /** Run id of the built-in subagent this loop runs, absent for the main loop. */\n readonly subagentId?: string | undefined;\n /** Steering intake shared with subagents so the active loop receives instructions. */\n readonly steering?: HarnessSteering | undefined;\n emit(event: AgentEvent): void;\n hold(): () => void;\n}\n\nexport interface HarnessSteering {\n /** Delivers and returns the instructions for the main loop or the given subagent. */\n take(subagent: string | undefined): readonly string[];\n /** Rejects instructions still addressed to a subagent run that ended. */\n finish(subagent: string): void;\n}\n\nexport interface ToolCallBatch {\n readonly concurrent: boolean;\n readonly calls: readonly PreparedCall[];\n}\n\nexport type ValidatedInput =\n { readonly value: unknown } | { readonly outcome: ToolOutcome };\n\nexport interface ToolOutcome {\n readonly content: string;\n readonly isError: boolean;\n}\n\nexport interface HarnessHistory {\n recordRoute?(event: ModelRouteEvent): Promise<void>;\n readonly messages: readonly ModelMessage[];\n append(message: ModelMessage): Promise<void>;\n replace(messages: readonly ModelMessage[]): Promise<void>;\n}\n\nexport interface CustomTurnContext extends TurnContext {\n readonly continuation?: DispatchOptions[\"continuation\"];\n}\n\nexport interface LoopState {\n readonly history: HarnessHistory;\n readonly step: number;\n toolCalls: number;\n}\n\nexport type StopHandler = (\n runtime: HarnessRuntime,\n state: LoopState,\n result: ModelResult,\n content: readonly ModelContentBlock[],\n) => Promise<string | undefined>;\n\nexport interface PreparedCall {\n readonly call: ModelToolCallBlock;\n readonly tool?: HarnessTool;\n readonly input?: unknown;\n readonly outcome?: ToolOutcome;\n}\n\nexport interface ToolDenial {\n readonly deny: string;\n}\n\nexport type BlockRenderers = {\n readonly [Type in ModelContentBlock[\"type\"]]: (\n block: Extract<ModelContentBlock, { type: Type }>,\n ) => string;\n};\n"]}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { invariant } from "../domain/errors.js";
|
|
2
2
|
import { defineJsonResponse } from "../domain/response.js";
|
|
3
|
+
import { interactiveResponseSchema } from "./interactive-task.constants.js";
|
|
3
4
|
import { checkpointValue } from "../domain/workflow/checkpoint-value.js";
|
|
4
5
|
import { inputObject, validateInputQuestion, } from "../domain/workflow/input-validation.js";
|
|
5
6
|
export const interactiveResponse = defineJsonResponse({
|
|
6
7
|
tag: "interaction",
|
|
8
|
+
jsonSchema: interactiveResponseSchema,
|
|
7
9
|
repairs: 1,
|
|
8
10
|
schema(value) {
|
|
9
11
|
invariant(inputObject(value), "Interactive response must be an object");
|
|
@@ -1 +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 { defineJsonResponse } 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 = defineJsonResponse<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"]}
|
|
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 { defineJsonResponse } from \"../domain/response.ts\";\nimport { interactiveResponseSchema } from \"./interactive-task.constants.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 = defineJsonResponse<InteractiveAgentTurn>({\n tag: \"interaction\",\n jsonSchema: interactiveResponseSchema,\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"]}
|