@elie-laloum/outpost 9.0.8 → 9.1.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 +16 -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/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/replay-turn.js +19 -1
- package/dist/application/replay-turn.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/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 +5 -0
- package/dist/domain/replay.constants.js.map +1 -1
- package/dist/domain/replay.js +57 -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/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/index.d.ts +10 -1
- 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/package.json +1 -1
|
@@ -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":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AASnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAOlD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EACL,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,YAAY,GAAmD;IACnE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;QAC7C,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3D,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,YAAY,CAAC,MAAM;YAAE,OAAO,MAAM,CAAC,IAAI,CAAC;QACtE,IAAI,OAAO,KAAK,SAAS;YACvB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC,CAAC;QACpD,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YACzB,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE;gBACP,GAAG,CAAC,OAAO,KAAK,SAAS;oBACvB,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;gBAC/C,GAAG,YAAY;aAChB;SACF,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QACtC,MAAM,IAAI,YAAY,CACpB,OAAO,EACP,oDAAoD,KAAK,CAAC,IAAI,EAAE,EAChE,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAC/C,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QACjC,MAAM,IAAI,YAAY,CAAC,UAAU,EAAE,+BAA+B,EAAE;YAClE,IAAI,EAAE,KAAK,CAAC,IAAI;SACjB,CAAC,CAAC;IACL,CAAC;IACD,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;QACvD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAC1B,CAAC,KAAK,EAA+B,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,CACnE,CAAC;QACF,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC;QAChC,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QACtD,IAAI,YAAY,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,GAAG,YAAY;YAC9D,MAAM,KAAK,CACT,cAAc,EACd,oBAAoB,YAAY,aAAa,CAC9C,CAAC;QACJ,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,MAAM,gBAAgB,CACpC,OAAO,EACP,KAAK,EACL,KAAK,CAAC,IAAI,EACV,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CACrC,CAAC;QACF,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YACzB,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;SAC5C,CAAC,CAAC;QACH,OAAO,SAAS,CAAC;IACnB,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAuB,EACvB,MAAc,EACd,OAAuB;IAEvB,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;IAClC,MAAM,MAAM,GAAG;QACb,MAAM,YAAY,CAAC,OAAO,CAAC;QAC3B,GAAG,CAAC,MAAM,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;KAChD;SACE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC7B,IAAI,CAAC,MAAM,CAAC,CAAC;IAChB,MAAM,KAAK,GAAoB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1D,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,CAAC,CAAC,CAAC;IACJ,MAAM,OAAO,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;KAChE,CAAC,CAAC;IACH,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAC1C,KAAK,IAAI,IAAI,GAAG,CAAC,GAAI,IAAI,EAAE,EAAE,CAAC;QAC5B,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QAChC,IAAI,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ;YAChC,MAAM,KAAK,CACT,UAAU,EACV,mBAAmB,OAAO,CAAC,MAAM,CAAC,QAAQ,+BAA+B,CAC1E,CAAC;QACJ,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAC5D,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CACrC,CAAC;QACF,KAAK,MAAM,IAAI,IAAI,WAAW;YAAE,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1D,IAAI,WAAW,CAAC,MAAM;YACpB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,MAAM,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,MAAM,iBAAiB,CACnC,OAAO,EACP,OAAO,EACP,MAAM,EACN,KAAK,EACL,IAAI,CACL,CAAC;QACF,OAAO,GAAG,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;QAC7D,MAAM,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE;YACzC,KAAK,EAAE,KAAK,CAAC,IAAI;YACjB,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;YACxE,GAAG,CAAC,KAAK,CAAC,eAAe,KAAK,SAAS;gBACrC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,CAAC,eAAe,EAAE,CAAC;YAC/C,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7B,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1C,CAAC,CAAC;QACH,MAAM,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QACxC,MAAM,OAAO,GAAiC,MAAM,CAAC,OAAO,IAAI;YAC9D,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE;SACpC,CAAC;QACF,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI;gBACrC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YACnD,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI;gBAC1C,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,KAAK,GAAc,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAC3E,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,OAAuB;IACjD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAC7B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAC/C,KAAK,CAAC,OAAO,CAAC;QACZ,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK;QAC1B,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7C,CAAC,CACH,CACF,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC;QACX,IAAI,EAAE,qBAAqB;QAC3B,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM;KAClD,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,QAAQ,CAAC,OAAuB;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAC/D,KAAK,MAAM,IAAI,IAAI,KAAK;QACtB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAC1D,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,YAAY,CAAC,OAAqC;IACzD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC;QACxD,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,KAAK,CAAC;AACZ,CAAC;AAED,SAAS,KAAK,CAAC,IAAY,EAAE,OAAe;IAC1C,OAAO,IAAI,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,OAAuB,EACvB,OAAqB;IAErB,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC;IACvC,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,CAAC;IACtE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,OAAO;YACjB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAChE,CAAC,CAAC;QACH,MAAM,KAAK,CAAC;IACd,CAAC;IACD,KAAK,UAAU,OAAO;QACpB,IAAI,CAAC,QAAQ,CAAC,MAAM;YAAE,OAAO,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACvD,IAAI,MAA+B,CAAC;QACpC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACnD,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;gBAC7B,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YACzD,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW;gBAC5B,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YACxD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;gBACxB,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,aAAa;oBACnB,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACrD,CAAC,CAAC;YACL,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QACrD,CAAC;QACD,IAAI,CAAC,MAAM;YACT,MAAM,IAAI,YAAY,CAAC,UAAU,EAAE,qCAAqC,CAAC,CAAC;QAC5E,OAAO,MAAM,CAAC;IAChB,CAAC;AACH,CAAC","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":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAK5D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGhD,SAAS,YAAY,CAAC,OAAmC;IACvD,MAAM,KAAK,GAAG,eAAe,CAAC;QAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC3C,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC;SACvE,CAAC,CAAC;KACJ,CAAC,CAAC;IACH,SAAS,CACP,KAAK,CAAC,IAAI,KAAK,MAAM;QACnB,KAAK,CAAC,KAAK,KAAK,IAAI;QACpB,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,EACjC,qCAAqC,CACtC,CAAC;IACF,OAAO,KAAK,CAAC,KAAK,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAuB,EACvB,OAAuB,EACvB,MAAc,EACd,KAA+B,EAC/B,IAAY;IAEZ,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;IAC9C,IAAI,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;IACzC,MAAM,OAAO,GAAG;QACd,MAAM;QACN,KAAK;QACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,IAAI;QACJ,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK;QAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC;IACF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK;QACzB,CAAC,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;QAC9B,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC1B,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;IAChC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,IAAI,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAC9B,IAAI,MAAM,GAA8B,aAAa,CAAC;IACtD,IAAI,UAA8B,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,KAAK,CAC3C,eAAe,CACb;YACE,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,KAAK;YACL,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE,EACD;YACE,OAAO,CAAC,KAAK;gBACX,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;gBACpC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;gBACxD,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAClC,CAAC;SACF,CACF,CACF,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ;YACrC,MAAM,IAAI,YAAY,CACpB,UAAU,EACV,wCAAwC,CACzC,CAAC;QACJ,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QAC/B,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC;QACxE,MAAM,GAAG,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;IACtE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QAChC,MAAM,WAAW,GACf,KAAK,YAAY,YAAY;YAC7B,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;gBACvB,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,gBAAgB,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC;QAC1E,IAAI,OAAO,CAAC,OAAO,KAAK,MAAM,IAAI,CAAC,WAAW;YAAE,MAAM,KAAK,CAAC;IAC9D,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,KAAK;QACR,MAAM,IAAI,YAAY,CAAC,UAAU,EAAE,sCAAsC,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAoB;QAC7B,IAAI,EAAE,aAAa;QACnB,IAAI;QACJ,MAAM;QACN,KAAK;QACL,MAAM;QACN,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC;KACpD,CAAC;IACF,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpB,OAAO,KAAK,CAAC;AACf,CAAC","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"]}
|
|
@@ -28,10 +28,28 @@ export async function replayTurn(lease, agent, prompt, options, pass) {
|
|
|
28
28
|
diverge({ kind: "prompt", expected: recorded.prompt, actual: prompt });
|
|
29
29
|
let handedOver = { input: 0, cached: 0, output: 0 };
|
|
30
30
|
for (;;) {
|
|
31
|
-
|
|
31
|
+
const decisions = recorded.decisionEvents ?? [];
|
|
32
|
+
let position = 0;
|
|
33
|
+
const emitDecisions = (before) => {
|
|
34
|
+
while (decisions[position]?.before === before) {
|
|
35
|
+
options.signal?.throwIfAborted();
|
|
36
|
+
const decision = decisions[position++];
|
|
37
|
+
if (decision.event.kind !== "decision" && !options.observation?.verbose)
|
|
38
|
+
continue;
|
|
39
|
+
options.observation
|
|
40
|
+
?.child({
|
|
41
|
+
pass,
|
|
42
|
+
...(decision.subagentId ? { subagentId: decision.subagentId } : {}),
|
|
43
|
+
})
|
|
44
|
+
.emit("decision", decision.event);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
for (const [index, event] of recorded.events.entries()) {
|
|
48
|
+
emitDecisions(index);
|
|
32
49
|
options.signal?.throwIfAborted();
|
|
33
50
|
notify(options.observe, { ...event, pass, at: new Date().toISOString() });
|
|
34
51
|
}
|
|
52
|
+
emitDecisions(recorded.events.length);
|
|
35
53
|
if (recorded.changes)
|
|
36
54
|
await replayWorkspace(lease, recorded.changes, {
|
|
37
55
|
...(options.signal ? { signal: options.signal } : {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replay-turn.js","sourceRoot":"","sources":["../../src/application/replay-turn.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAMvD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAmB,EACnB,KAAkB,EAClB,MAAc,EACd,OAAiC,EACjC,IAAY;IAEZ,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,OAAO,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,GAAG,EAAE;QAChB,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI;YACP,MAAM,IAAI,gBAAgB,CAAC;gBACzB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;aAC7B,CAAC,CAAC;QACL,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IACF,IAAI,QAAQ,GAAG,IAAI,EAAE,CAAC;IACtB,IAAI,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC;IACvD,MAAM,OAAO,GAAG,CACd,OAA8C,EAC9C,KAAK,GAAG,KAAK,EACP,EAAE;QACR,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACtE,IAAI,KAAK,IAAI,KAAK,CAAC,UAAU,KAAK,MAAM;YAAE,MAAM,UAAU,CAAC;QAC3D,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC,CAAC;IACF,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM;QAC5B,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACzE,IAAI,UAAU,GAAU,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAC3D,SAAS,CAAC;QACR,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"replay-turn.js","sourceRoot":"","sources":["../../src/application/replay-turn.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Usage } from \"../domain/agent.types.ts\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport { ReplayDivergence } from \"../domain/replay.ts\";\nimport type {\n ReplayAgent,\n ReplayDivergenceDetails,\n} from \"../domain/replay.types.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport { addUsage } from \"../domain/usage.ts\";\nimport { executionDefaults } from \"./execution.constants.ts\";\nimport type { DispatchOptions, Turn } from \"./execution.types.ts\";\nimport { notify } from \"./observation.ts\";\nimport { replayWorkspace } from \"./replay-workspace.ts\";\n\nexport async function replayTurn(\n lease: SandboxLease,\n agent: ReplayAgent,\n prompt: string,\n options: DispatchOptions<unknown>,\n pass: number,\n): Promise<Turn> {\n const start = Date.now();\n options.signal?.throwIfAborted();\n const next = () => {\n const turn = agent.nextTurn();\n if (!turn)\n throw new ReplayDivergence({\n kind: \"exhausted\",\n turn: agent.turns.length + 1,\n });\n return turn;\n };\n let recorded = next();\n let number = agent.turns.length - agent.remainingTurns;\n const diverge = (\n details: Omit<ReplayDivergenceDetails, \"turn\">,\n fatal = false,\n ): void => {\n const divergence = new ReplayDivergence({ ...details, turn: number });\n if (fatal || agent.divergence === \"fail\") throw divergence;\n notify(options.warn, divergence.message);\n };\n if (recorded.prompt !== prompt)\n diverge({ kind: \"prompt\", expected: recorded.prompt, actual: prompt });\n let handedOver: Usage = { input: 0, cached: 0, output: 0 };\n for (;;) {\n const decisions = recorded.decisionEvents ?? [];\n let position = 0;\n const emitDecisions = (before: number) => {\n while (decisions[position]?.before === before) {\n options.signal?.throwIfAborted();\n const decision = decisions[position++]!;\n if (decision.event.kind !== \"decision\" && !options.observation?.verbose)\n continue;\n options.observation\n ?.child({\n pass,\n ...(decision.subagentId ? { subagentId: decision.subagentId } : {}),\n })\n .emit(\"decision\", decision.event);\n }\n };\n for (const [index, event] of recorded.events.entries()) {\n emitDecisions(index);\n options.signal?.throwIfAborted();\n notify(options.observe, { ...event, pass, at: new Date().toISOString() });\n }\n emitDecisions(recorded.events.length);\n if (recorded.changes)\n await replayWorkspace(lease, recorded.changes, {\n ...(options.signal ? { signal: options.signal } : {}),\n deadlineMs: options.deadlineMs ?? executionDefaults.deadlineMs,\n diverge,\n });\n options.signal?.throwIfAborted();\n if (!recorded.handover) break;\n handedOver = addUsage(handedOver, recorded.usage);\n notify(options.observe, {\n ...recorded.handover,\n pass,\n at: new Date().toISOString(),\n });\n // The next candidate restarted from the original brief, which this replayed turn may not carry.\n recorded = next();\n number = agent.turns.length - agent.remainingTurns;\n }\n if (recorded.failure)\n throw new OutpostError(recorded.failure.code, recorded.failure.message, {\n replayed: true,\n });\n return {\n text: recorded.text,\n usage: addUsage(handedOver, recorded.usage),\n status: 0,\n durationMs: Date.now() - start,\n ...(recorded.interrupted ? { interrupted: \"steering\" as const } : {}),\n ...(recorded.conversation ? { conversation: recorded.conversation } : {}),\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-observation.js","sourceRoot":"","sources":["../../src/domain/agent-observation.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,YAAY,CAAC,KAAuB;IAClD,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,UAAU,CAAC;QAChB,KAAK,WAAW,CAAC;QACjB,KAAK,gBAAgB,CAAC;QACtB,KAAK,mBAAmB,CAAC;QACzB,KAAK,mBAAmB,CAAC;QACzB,KAAK,gBAAgB,CAAC;QACtB,KAAK,WAAW,CAAC;QACjB,KAAK,OAAO;YACV,OAAO,KAAK,CAAC;QACf;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,KAAkB;IAElB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACjD,OAAO;QACL,GAAG,KAAK,CAAC,KAAK;QACd,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;QAC3B,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC;AACJ,CAAC","sourcesContent":["import type { AgentEvent, AgentObservation } from \"./agent.types.ts\";\nimport type { Observation, ObservationEvent } from \"./observation.types.ts\";\n\nexport function isAgentEvent(event: ObservationEvent): event is AgentEvent {\n switch (event.kind) {\n case \"workflow\":\n case \"operation\":\n case \"dispatch-start\":\n case \"dispatch-finished\":\n case \"workspace-commits\":\n case \"command-output\":\n case \"candidate\":\n case \"queue\":\n return false;\n default:\n return true;\n }\n}\n\nexport function agentObservation(\n value: Observation,\n): AgentObservation | undefined {\n if (!isAgentEvent(value.event)) return undefined;\n return {\n ...value.event,\n pass: value.scope.pass ?? 1,\n at: value.at,\n seq: value.seq,\n source: value.source,\n scope: value.scope,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-observation.js","sourceRoot":"","sources":["../../src/domain/agent-observation.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,YAAY,CAAC,KAAuB;IAClD,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,UAAU,CAAC;QAChB,KAAK,kBAAkB,CAAC;QACxB,KAAK,mBAAmB,CAAC;QACzB,KAAK,UAAU,CAAC;QAChB,KAAK,WAAW,CAAC;QACjB,KAAK,gBAAgB,CAAC;QACtB,KAAK,mBAAmB,CAAC;QACzB,KAAK,mBAAmB,CAAC;QACzB,KAAK,gBAAgB,CAAC;QACtB,KAAK,WAAW,CAAC;QACjB,KAAK,OAAO;YACV,OAAO,KAAK,CAAC;QACf;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,KAAkB;IAElB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACjD,OAAO;QACL,GAAG,KAAK,CAAC,KAAK;QACd,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;QAC3B,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC;AACJ,CAAC","sourcesContent":["import type { AgentEvent, AgentObservation } from \"./agent.types.ts\";\nimport type { Observation, ObservationEvent } from \"./observation.types.ts\";\n\nexport function isAgentEvent(event: ObservationEvent): event is AgentEvent {\n switch (event.kind) {\n case \"decision\":\n case \"decision-request\":\n case \"decision-response\":\n case \"workflow\":\n case \"operation\":\n case \"dispatch-start\":\n case \"dispatch-finished\":\n case \"workspace-commits\":\n case \"command-output\":\n case \"candidate\":\n case \"queue\":\n return false;\n default:\n return true;\n }\n}\n\nexport function agentObservation(\n value: Observation,\n): AgentObservation | undefined {\n if (!isAgentEvent(value.event)) return undefined;\n return {\n ...value.event,\n pass: value.scope.pass ?? 1,\n at: value.at,\n seq: value.seq,\n source: value.source,\n scope: value.scope,\n };\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Harness } from "./harness.types.ts";
|
|
2
|
+
import type { ModelRouteEvent } from "./harness-routing.types.ts";
|
|
2
3
|
import type { AgentModel, ModelSpec } from "./model.types.ts";
|
|
3
4
|
import type { Command, CommandResult, Variables } from "./command.types.ts";
|
|
4
5
|
import type { ConversationStore } from "./conversation.types.ts";
|
|
@@ -15,7 +16,7 @@ export interface Usage {
|
|
|
15
16
|
export type AgentEvent = AgentEventDetails & {
|
|
16
17
|
readonly subagentId?: string;
|
|
17
18
|
};
|
|
18
|
-
export type AgentEventDetails = {
|
|
19
|
+
export type AgentEventDetails = ModelRouteEvent | {
|
|
19
20
|
readonly kind: "subagent";
|
|
20
21
|
readonly id: string;
|
|
21
22
|
readonly callId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.types.js","sourceRoot":"","sources":["../../src/domain/agent.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Harness } from \"./harness.types.ts\";\nimport type { AgentModel, ModelSpec } from \"./model.types.ts\";\nimport type { Command, CommandResult, Variables } from \"./command.types.ts\";\nimport type { ConversationStore } from \"./conversation.types.ts\";\nimport type { ReplayAgent } from \"./replay.types.ts\";\nimport type { SteeringMode } from \"./steering.types.ts\";\nimport type {\n FallbackCandidate,\n FallbackTrigger,\n} from \"./fallback-agent.types.ts\";\n\nexport interface Usage {\n readonly complete?: boolean;\n readonly input: number;\n readonly cached: number;\n readonly cacheCreated?: number;\n readonly output: number;\n}\n\nexport type AgentEvent = AgentEventDetails & {\n readonly subagentId?: string;\n};\n\nexport type AgentEventDetails =\n | {\n readonly kind: \"subagent\";\n readonly id: string;\n readonly callId: string;\n readonly name: string;\n readonly status: \"started\" | \"finished\" | \"failed\";\n readonly conversation?: string;\n }\n | {\n readonly kind: \"message-usage\";\n readonly tokens: Usage;\n readonly messageId?: string;\n readonly parentCallId?: string;\n }\n | {\n readonly kind: \"stderr\";\n readonly text: string;\n readonly truncated?: boolean;\n }\n | {\n readonly kind: \"stopped\";\n readonly reason:\n | \"completion\"\n | \"idle-timeout\"\n | \"deadline\"\n | \"aborted\"\n | \"oversized-event\"\n | \"steered\";\n }\n | {\n readonly kind: \"steer\";\n readonly text: string;\n readonly mode: SteeringMode;\n }\n | {\n readonly kind: \"reasoning\";\n readonly text: string;\n readonly parentCallId?: string;\n }\n | {\n readonly kind: \"file-change\";\n readonly changes: unknown;\n readonly callId?: string;\n }\n | { readonly kind: \"model-request\"; readonly request: unknown }\n | { readonly kind: \"model-response\"; readonly response: unknown }\n | {\n readonly kind: \"model-retry\";\n readonly attempt: number;\n readonly message?: string;\n }\n | { readonly kind: \"model-error\"; readonly message: string }\n | { readonly kind: \"hook\"; readonly phase: string; readonly changed: boolean }\n | { readonly kind: \"instructions-loaded\"; readonly count: number }\n | { readonly kind: \"skills-loaded\"; readonly names: readonly string[] }\n | {\n readonly kind: \"tool-output\";\n readonly callId: string;\n readonly channel: \"stdout\" | \"stderr\";\n readonly text: string;\n }\n | {\n readonly kind: \"phase\";\n readonly name: string;\n readonly agent?: string;\n readonly branch?: string;\n readonly directory?: string;\n }\n | {\n readonly kind: \"summary\";\n readonly durationMs: number;\n readonly status: number;\n readonly tokens: Usage;\n }\n | { readonly kind: \"warning\"; readonly message: string }\n | { readonly kind: \"text\"; readonly text: string }\n | { readonly kind: \"text-delta\"; readonly text: string }\n | { readonly kind: \"result\"; readonly text: string }\n | { readonly kind: \"prompt\"; readonly text: string }\n | {\n readonly kind: \"tool\";\n readonly name: string;\n readonly input: unknown;\n readonly callId?: string;\n readonly parentCallId?: string;\n }\n | {\n readonly kind: \"tool-result\";\n readonly callId: string;\n readonly name: string;\n readonly isError: boolean;\n readonly preview: string;\n readonly characters: number;\n readonly parentCallId?: string;\n }\n | { readonly kind: \"step\"; readonly index: number }\n | {\n readonly kind: \"tool-denied\";\n readonly callId: string;\n readonly name: string;\n readonly reason: string;\n }\n | { readonly kind: \"stop-prevented\"; readonly message: string }\n | {\n readonly kind: \"compaction\";\n readonly strategy: string;\n readonly messages: number;\n }\n | { readonly kind: \"conversation\"; readonly id: string }\n | {\n readonly kind: \"usage\";\n readonly tokens: Usage;\n readonly cumulative?: boolean;\n }\n | { readonly kind: \"failure\"; readonly message: string }\n | {\n readonly kind: \"quota\";\n readonly message: string;\n readonly resetAt?: string;\n }\n | {\n readonly kind: \"fallback\";\n readonly from: FallbackCandidate;\n readonly to: FallbackCandidate;\n readonly failure: FallbackTrigger;\n readonly message: string;\n readonly resetAt?: string;\n }\n | { readonly kind: \"finished\" }\n | {\n readonly kind: \"raw\";\n readonly value: unknown;\n readonly bytes?: number;\n readonly truncated?: boolean;\n };\n\nexport type AgentObservation = AgentEvent & {\n readonly pass: number;\n readonly at: string;\n readonly seq?: number;\n readonly source?: import(\"./observation.types.ts\").ObservationSource;\n readonly scope?: import(\"./observation.types.ts\").ObservationScope;\n};\n\nexport type AgentEventHandlers = {\n readonly [Kind in AgentEvent[\"kind\"]]?: (\n event: Extract<AgentEvent, { kind: Kind }>,\n ) => void;\n};\n\nexport interface AgentInput {\n readonly text?: string;\n readonly interactive?: boolean;\n /** Requests the liveInput protocol: stdin carries the encoded prompt and stays open. */\n readonly liveInput?: boolean;\n readonly continuation?: { readonly id: string; readonly fork?: boolean };\n}\n\nexport interface AgentFeatures {\n readonly name: string;\n readonly bootstrap?: string;\n readonly requiresFinishedEvent?: boolean;\n readonly usage?: \"events\" | \"session\" | \"unavailable\";\n readonly variables?: Variables;\n readonly storage?: ConversationStore;\n readonly capture?: boolean;\n readonly resumable?: boolean;\n readonly forkable?: boolean;\n transcriptUsage?(text: string): Usage | undefined;\n}\n\nexport interface AgentAdapter extends AgentFeatures {\n fork?(\n id: string,\n invoke: (command: Command) => Promise<CommandResult>,\n ): Promise<string>;\n credentials?(variables: Variables): CredentialPlan;\n /** Plans CLI configuration merged into the agent home; throws when a referenced variable is missing. */\n configuration?(variables: Variables): AgentConfiguration;\n request(input: AgentInput): Command;\n events(line: string): readonly AgentEvent[];\n /** Recognizes a usage-limit or rate-limit message in failure or stderr text. */\n quota?(text: string): boolean;\n /** Recognizes a terminal service outage or connection failure in failure or stderr text. */\n unavailable?(text: string): boolean;\n usageCommand?(conversation: string): Command | undefined;\n usageResult?(text: string): Usage | undefined;\n /** Protocol for adding user messages to a running turn through live stdin. */\n readonly liveInput?: AgentLiveInput;\n}\n\nexport interface AgentLiveInput {\n /** Starts the protocol state of one turn requested with input. */\n open(input: AgentInput): AgentLiveSession;\n}\n\nexport interface AgentLiveSession {\n /** Encodes one user message for stdin, or returns \"\" when the session sends it later. */\n encode(text: string): string;\n /** Reads one output line: user messages it confirms and protocol replies to write. */\n read(line: string): AgentLiveRead;\n}\n\nexport interface AgentLiveRead {\n readonly consumed: number;\n readonly replies: readonly string[];\n}\n\nexport interface RequiredAgent {\n readonly agent: Agent;\n}\n\nexport interface CliHarness {\n readonly kind: \"cli\";\n bind(model?: AgentModel): AgentAdapter;\n}\n\nexport type AgentHarness = CliHarness | Harness;\n\nexport interface CliAgent extends AgentAdapter {\n readonly kind: \"cli\";\n readonly harness: CliHarness;\n readonly model?: AgentModel;\n}\n\nexport interface CustomAgent extends AgentFeatures {\n readonly resumable: boolean;\n readonly capture: boolean;\n readonly kind: \"custom\";\n readonly harness: Harness;\n readonly model: AgentModel;\n}\n\nexport type Agent = CliAgent | CustomAgent | ReplayAgent;\n\nexport interface CliAgentOptions {\n readonly harness: CliHarness;\n readonly model?: ModelSpec;\n}\nexport interface CustomAgentOptions {\n readonly harness: Harness;\n readonly model: ModelSpec;\n}\nexport type AgentOptions = CliAgentOptions | CustomAgentOptions;\n\nexport type AccountCredential =\n | { readonly file: string }\n | { readonly key: string }\n | { readonly variable: string };\n\nexport type UsageCredential =\n { readonly key: string } | { readonly variable: string };\n\nexport type AgentAuthentication =\n | \"account\"\n | \"usage\"\n | { readonly account: AccountCredential }\n | { readonly usage: UsageCredential };\n\nexport interface HostCredentialPath {\n readonly path: string;\n readonly home?: { readonly variable: string; readonly path: string };\n}\n\nexport interface HostCredential {\n readonly source: HostCredentialPath;\n readonly destination:\n { readonly file: string } | { readonly variable: string };\n readonly login: string;\n readonly alternative?: string;\n select?(content: string): string;\n}\n\nexport interface GeneratedCredential {\n readonly path: string;\n readonly content: string;\n}\n\nexport interface ConfigurationFile {\n readonly path: string;\n readonly section?: string;\n readonly entries: Readonly<Record<string, unknown>>;\n}\n\nexport interface HostConfiguration {\n readonly source: HostCredentialPath;\n readonly path: string;\n readonly section?: string;\n readonly optional?: boolean;\n readonly login: string;\n select(content: string): Readonly<Record<string, unknown>>;\n}\n\nexport interface AgentConfiguration {\n readonly files: readonly ConfigurationFile[];\n readonly host?: readonly HostConfiguration[];\n}\n\nexport interface CredentialPlan {\n readonly variables: Variables;\n readonly host: readonly HostCredential[];\n readonly files: readonly GeneratedCredential[];\n readonly commands: readonly Command[];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent.types.js","sourceRoot":"","sources":["../../src/domain/agent.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Harness } from \"./harness.types.ts\";\nimport type { ModelRouteEvent } from \"./harness-routing.types.ts\";\nimport type { AgentModel, ModelSpec } from \"./model.types.ts\";\nimport type { Command, CommandResult, Variables } from \"./command.types.ts\";\nimport type { ConversationStore } from \"./conversation.types.ts\";\nimport type { ReplayAgent } from \"./replay.types.ts\";\nimport type { SteeringMode } from \"./steering.types.ts\";\nimport type {\n FallbackCandidate,\n FallbackTrigger,\n} from \"./fallback-agent.types.ts\";\n\nexport interface Usage {\n readonly complete?: boolean;\n readonly input: number;\n readonly cached: number;\n readonly cacheCreated?: number;\n readonly output: number;\n}\n\nexport type AgentEvent = AgentEventDetails & {\n readonly subagentId?: string;\n};\n\nexport type AgentEventDetails =\n | ModelRouteEvent\n | {\n readonly kind: \"subagent\";\n readonly id: string;\n readonly callId: string;\n readonly name: string;\n readonly status: \"started\" | \"finished\" | \"failed\";\n readonly conversation?: string;\n }\n | {\n readonly kind: \"message-usage\";\n readonly tokens: Usage;\n readonly messageId?: string;\n readonly parentCallId?: string;\n }\n | {\n readonly kind: \"stderr\";\n readonly text: string;\n readonly truncated?: boolean;\n }\n | {\n readonly kind: \"stopped\";\n readonly reason:\n | \"completion\"\n | \"idle-timeout\"\n | \"deadline\"\n | \"aborted\"\n | \"oversized-event\"\n | \"steered\";\n }\n | {\n readonly kind: \"steer\";\n readonly text: string;\n readonly mode: SteeringMode;\n }\n | {\n readonly kind: \"reasoning\";\n readonly text: string;\n readonly parentCallId?: string;\n }\n | {\n readonly kind: \"file-change\";\n readonly changes: unknown;\n readonly callId?: string;\n }\n | { readonly kind: \"model-request\"; readonly request: unknown }\n | { readonly kind: \"model-response\"; readonly response: unknown }\n | {\n readonly kind: \"model-retry\";\n readonly attempt: number;\n readonly message?: string;\n }\n | { readonly kind: \"model-error\"; readonly message: string }\n | { readonly kind: \"hook\"; readonly phase: string; readonly changed: boolean }\n | { readonly kind: \"instructions-loaded\"; readonly count: number }\n | { readonly kind: \"skills-loaded\"; readonly names: readonly string[] }\n | {\n readonly kind: \"tool-output\";\n readonly callId: string;\n readonly channel: \"stdout\" | \"stderr\";\n readonly text: string;\n }\n | {\n readonly kind: \"phase\";\n readonly name: string;\n readonly agent?: string;\n readonly branch?: string;\n readonly directory?: string;\n }\n | {\n readonly kind: \"summary\";\n readonly durationMs: number;\n readonly status: number;\n readonly tokens: Usage;\n }\n | { readonly kind: \"warning\"; readonly message: string }\n | { readonly kind: \"text\"; readonly text: string }\n | { readonly kind: \"text-delta\"; readonly text: string }\n | { readonly kind: \"result\"; readonly text: string }\n | { readonly kind: \"prompt\"; readonly text: string }\n | {\n readonly kind: \"tool\";\n readonly name: string;\n readonly input: unknown;\n readonly callId?: string;\n readonly parentCallId?: string;\n }\n | {\n readonly kind: \"tool-result\";\n readonly callId: string;\n readonly name: string;\n readonly isError: boolean;\n readonly preview: string;\n readonly characters: number;\n readonly parentCallId?: string;\n }\n | { readonly kind: \"step\"; readonly index: number }\n | {\n readonly kind: \"tool-denied\";\n readonly callId: string;\n readonly name: string;\n readonly reason: string;\n }\n | { readonly kind: \"stop-prevented\"; readonly message: string }\n | {\n readonly kind: \"compaction\";\n readonly strategy: string;\n readonly messages: number;\n }\n | { readonly kind: \"conversation\"; readonly id: string }\n | {\n readonly kind: \"usage\";\n readonly tokens: Usage;\n readonly cumulative?: boolean;\n }\n | { readonly kind: \"failure\"; readonly message: string }\n | {\n readonly kind: \"quota\";\n readonly message: string;\n readonly resetAt?: string;\n }\n | {\n readonly kind: \"fallback\";\n readonly from: FallbackCandidate;\n readonly to: FallbackCandidate;\n readonly failure: FallbackTrigger;\n readonly message: string;\n readonly resetAt?: string;\n }\n | { readonly kind: \"finished\" }\n | {\n readonly kind: \"raw\";\n readonly value: unknown;\n readonly bytes?: number;\n readonly truncated?: boolean;\n };\n\nexport type AgentObservation = AgentEvent & {\n readonly pass: number;\n readonly at: string;\n readonly seq?: number;\n readonly source?: import(\"./observation.types.ts\").ObservationSource;\n readonly scope?: import(\"./observation.types.ts\").ObservationScope;\n};\n\nexport type AgentEventHandlers = {\n readonly [Kind in AgentEvent[\"kind\"]]?: (\n event: Extract<AgentEvent, { kind: Kind }>,\n ) => void;\n};\n\nexport interface AgentInput {\n readonly text?: string;\n readonly interactive?: boolean;\n /** Requests the liveInput protocol: stdin carries the encoded prompt and stays open. */\n readonly liveInput?: boolean;\n readonly continuation?: { readonly id: string; readonly fork?: boolean };\n}\n\nexport interface AgentFeatures {\n readonly name: string;\n readonly bootstrap?: string;\n readonly requiresFinishedEvent?: boolean;\n readonly usage?: \"events\" | \"session\" | \"unavailable\";\n readonly variables?: Variables;\n readonly storage?: ConversationStore;\n readonly capture?: boolean;\n readonly resumable?: boolean;\n readonly forkable?: boolean;\n transcriptUsage?(text: string): Usage | undefined;\n}\n\nexport interface AgentAdapter extends AgentFeatures {\n fork?(\n id: string,\n invoke: (command: Command) => Promise<CommandResult>,\n ): Promise<string>;\n credentials?(variables: Variables): CredentialPlan;\n /** Plans CLI configuration merged into the agent home; throws when a referenced variable is missing. */\n configuration?(variables: Variables): AgentConfiguration;\n request(input: AgentInput): Command;\n events(line: string): readonly AgentEvent[];\n /** Recognizes a usage-limit or rate-limit message in failure or stderr text. */\n quota?(text: string): boolean;\n /** Recognizes a terminal service outage or connection failure in failure or stderr text. */\n unavailable?(text: string): boolean;\n usageCommand?(conversation: string): Command | undefined;\n usageResult?(text: string): Usage | undefined;\n /** Protocol for adding user messages to a running turn through live stdin. */\n readonly liveInput?: AgentLiveInput;\n}\n\nexport interface AgentLiveInput {\n /** Starts the protocol state of one turn requested with input. */\n open(input: AgentInput): AgentLiveSession;\n}\n\nexport interface AgentLiveSession {\n /** Encodes one user message for stdin, or returns \"\" when the session sends it later. */\n encode(text: string): string;\n /** Reads one output line: user messages it confirms and protocol replies to write. */\n read(line: string): AgentLiveRead;\n}\n\nexport interface AgentLiveRead {\n readonly consumed: number;\n readonly replies: readonly string[];\n}\n\nexport interface RequiredAgent {\n readonly agent: Agent;\n}\n\nexport interface CliHarness {\n readonly kind: \"cli\";\n bind(model?: AgentModel): AgentAdapter;\n}\n\nexport type AgentHarness = CliHarness | Harness;\n\nexport interface CliAgent extends AgentAdapter {\n readonly kind: \"cli\";\n readonly harness: CliHarness;\n readonly model?: AgentModel;\n}\n\nexport interface CustomAgent extends AgentFeatures {\n readonly resumable: boolean;\n readonly capture: boolean;\n readonly kind: \"custom\";\n readonly harness: Harness;\n readonly model: AgentModel;\n}\n\nexport type Agent = CliAgent | CustomAgent | ReplayAgent;\n\nexport interface CliAgentOptions {\n readonly harness: CliHarness;\n readonly model?: ModelSpec;\n}\nexport interface CustomAgentOptions {\n readonly harness: Harness;\n readonly model: ModelSpec;\n}\nexport type AgentOptions = CliAgentOptions | CustomAgentOptions;\n\nexport type AccountCredential =\n | { readonly file: string }\n | { readonly key: string }\n | { readonly variable: string };\n\nexport type UsageCredential =\n { readonly key: string } | { readonly variable: string };\n\nexport type AgentAuthentication =\n | \"account\"\n | \"usage\"\n | { readonly account: AccountCredential }\n | { readonly usage: UsageCredential };\n\nexport interface HostCredentialPath {\n readonly path: string;\n readonly home?: { readonly variable: string; readonly path: string };\n}\n\nexport interface HostCredential {\n readonly source: HostCredentialPath;\n readonly destination:\n { readonly file: string } | { readonly variable: string };\n readonly login: string;\n readonly alternative?: string;\n select?(content: string): string;\n}\n\nexport interface GeneratedCredential {\n readonly path: string;\n readonly content: string;\n}\n\nexport interface ConfigurationFile {\n readonly path: string;\n readonly section?: string;\n readonly entries: Readonly<Record<string, unknown>>;\n}\n\nexport interface HostConfiguration {\n readonly source: HostCredentialPath;\n readonly path: string;\n readonly section?: string;\n readonly optional?: boolean;\n readonly login: string;\n select(content: string): Readonly<Record<string, unknown>>;\n}\n\nexport interface AgentConfiguration {\n readonly files: readonly ConfigurationFile[];\n readonly host?: readonly HostConfiguration[];\n}\n\nexport interface CredentialPlan {\n readonly variables: Variables;\n readonly host: readonly HostCredential[];\n readonly files: readonly GeneratedCredential[];\n readonly commands: readonly Command[];\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Usage } from "./agent.types.ts";
|
|
2
|
+
import type { DecisionAnswers, DecisionProviderResult, DecisionQuestions } from "./decision.types.ts";
|
|
3
|
+
export declare function requireDecisionResponse(condition: unknown): asserts condition;
|
|
4
|
+
export declare function decisionObject(value: unknown): Record<string, unknown>;
|
|
5
|
+
export declare function decisionUsage(usage: Usage | undefined): Usage;
|
|
6
|
+
export declare function decisionAnswers<Q extends DecisionQuestions>(questions: Q, result: DecisionProviderResult): DecisionAnswers<Q>;
|