@elie-laloum/outpost 5.0.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +54 -0
- package/README.md +11 -11
- package/SECURITY.md +10 -0
- package/dist/adapters/agents/antigravity-adapter.d.ts +3 -0
- package/dist/adapters/agents/antigravity-adapter.js +41 -0
- package/dist/adapters/agents/antigravity-adapter.js.map +1 -0
- package/dist/adapters/agents/antigravity-authentication.d.ts +2 -0
- package/dist/adapters/agents/antigravity-authentication.js +27 -0
- package/dist/adapters/agents/antigravity-authentication.js.map +1 -0
- package/dist/adapters/agents/antigravity-diagnostics.d.ts +1 -0
- package/dist/adapters/agents/antigravity-diagnostics.js +6 -0
- package/dist/adapters/agents/antigravity-diagnostics.js.map +1 -0
- package/dist/adapters/agents/antigravity-events.d.ts +2 -0
- package/dist/adapters/agents/antigravity-events.js +75 -0
- package/dist/adapters/agents/antigravity-events.js.map +1 -0
- package/dist/adapters/agents/antigravity-request.d.ts +5 -0
- package/dist/adapters/agents/antigravity-request.js +37 -0
- package/dist/adapters/agents/antigravity-request.js.map +1 -0
- package/dist/adapters/agents/antigravity.constants.d.ts +3 -0
- package/dist/adapters/agents/antigravity.constants.js +4 -0
- package/dist/adapters/agents/antigravity.constants.js.map +1 -0
- package/dist/adapters/agents/{gemini.types.d.ts → antigravity.types.d.ts} +2 -2
- package/dist/adapters/agents/antigravity.types.js +2 -0
- package/dist/adapters/agents/antigravity.types.js.map +1 -0
- package/dist/adapters/agents/authentication.constants.d.ts +19 -9
- package/dist/adapters/agents/authentication.constants.js +12 -9
- package/dist/adapters/agents/authentication.constants.js.map +1 -1
- package/dist/adapters/agents/authentication.d.ts +11 -2
- package/dist/adapters/agents/authentication.js +70 -47
- package/dist/adapters/agents/authentication.js.map +1 -1
- package/dist/adapters/agents/authentication.types.d.ts +20 -0
- package/dist/adapters/agents/authentication.types.js +2 -0
- package/dist/adapters/agents/authentication.types.js.map +1 -0
- package/dist/adapters/agents/claude-adapter.js +4 -2
- package/dist/adapters/agents/claude-adapter.js.map +1 -1
- package/dist/adapters/agents/claude-authentication.d.ts +2 -0
- package/dist/adapters/agents/claude-authentication.js +34 -0
- package/dist/adapters/agents/claude-authentication.js.map +1 -0
- package/dist/adapters/agents/claude-events.js +52 -9
- package/dist/adapters/agents/claude-events.js.map +1 -1
- package/dist/adapters/agents/claude-request.js +2 -0
- package/dist/adapters/agents/claude-request.js.map +1 -1
- package/dist/adapters/agents/cli-diagnostics.constants.d.ts +6 -6
- package/dist/adapters/agents/cli-diagnostics.constants.js +6 -6
- package/dist/adapters/agents/cli-diagnostics.constants.js.map +1 -1
- package/dist/adapters/agents/cli-diagnostics.d.ts +1 -0
- package/dist/adapters/agents/cli-diagnostics.js +18 -0
- package/dist/adapters/agents/cli-diagnostics.js.map +1 -1
- package/dist/adapters/agents/codex-adapter.js +4 -2
- package/dist/adapters/agents/codex-adapter.js.map +1 -1
- package/dist/adapters/agents/codex-authentication.d.ts +3 -0
- package/dist/adapters/agents/codex-authentication.js +47 -0
- package/dist/adapters/agents/codex-authentication.js.map +1 -0
- package/dist/adapters/agents/codex-events.js +28 -2
- package/dist/adapters/agents/codex-events.js.map +1 -1
- package/dist/adapters/agents/copilot-adapter.d.ts +3 -0
- package/dist/adapters/agents/copilot-adapter.js +45 -0
- package/dist/adapters/agents/copilot-adapter.js.map +1 -0
- package/dist/adapters/agents/copilot-authentication.d.ts +2 -0
- package/dist/adapters/agents/copilot-authentication.js +46 -0
- package/dist/adapters/agents/copilot-authentication.js.map +1 -0
- package/dist/adapters/agents/copilot-diagnostics.d.ts +1 -0
- package/dist/adapters/agents/copilot-diagnostics.js +6 -0
- package/dist/adapters/agents/copilot-diagnostics.js.map +1 -0
- package/dist/adapters/agents/copilot-events.d.ts +2 -0
- package/dist/adapters/agents/copilot-events.js +66 -0
- package/dist/adapters/agents/copilot-events.js.map +1 -0
- package/dist/adapters/agents/copilot-request.d.ts +5 -0
- package/dist/adapters/agents/copilot-request.js +24 -0
- package/dist/adapters/agents/copilot-request.js.map +1 -0
- package/dist/adapters/agents/copilot-usage.d.ts +3 -0
- package/dist/adapters/agents/copilot-usage.js +19 -0
- package/dist/adapters/agents/copilot-usage.js.map +1 -0
- package/dist/adapters/agents/copilot.types.d.ts +6 -0
- package/dist/adapters/agents/copilot.types.js +2 -0
- package/dist/adapters/agents/copilot.types.js.map +1 -0
- package/dist/adapters/agents/event-decoder.d.ts +2 -2
- package/dist/adapters/agents/event-decoder.js +6 -5
- package/dist/adapters/agents/event-decoder.js.map +1 -1
- package/dist/adapters/agents/kimi-adapter.d.ts +3 -0
- package/dist/adapters/agents/kimi-adapter.js +51 -0
- package/dist/adapters/agents/kimi-adapter.js.map +1 -0
- package/dist/adapters/agents/kimi-authentication.d.ts +3 -0
- package/dist/adapters/agents/kimi-authentication.js +63 -0
- package/dist/adapters/agents/kimi-authentication.js.map +1 -0
- package/dist/adapters/agents/kimi-diagnostics.d.ts +2 -0
- package/dist/adapters/agents/kimi-diagnostics.js +14 -0
- package/dist/adapters/agents/kimi-diagnostics.js.map +1 -0
- package/dist/adapters/agents/kimi-events.d.ts +2 -0
- package/dist/adapters/agents/kimi-events.js +55 -0
- package/dist/adapters/agents/kimi-events.js.map +1 -0
- package/dist/adapters/agents/kimi-fork.d.ts +2 -0
- package/dist/adapters/agents/kimi-fork.js +11 -0
- package/dist/adapters/agents/kimi-fork.js.map +1 -0
- package/dist/adapters/agents/{gemini-request.d.ts → kimi-request.d.ts} +2 -2
- package/dist/adapters/agents/kimi-request.js +33 -0
- package/dist/adapters/agents/kimi-request.js.map +1 -0
- package/dist/adapters/agents/kimi-usage.d.ts +2 -0
- package/dist/adapters/agents/kimi-usage.js +7 -0
- package/dist/adapters/agents/kimi-usage.js.map +1 -0
- package/dist/adapters/agents/kimi.constants.d.ts +13 -0
- package/dist/adapters/agents/kimi.constants.js +14 -0
- package/dist/adapters/agents/kimi.constants.js.map +1 -0
- package/dist/adapters/agents/kimi.types.d.ts +7 -0
- package/dist/adapters/agents/kimi.types.js +2 -0
- package/dist/adapters/agents/kimi.types.js.map +1 -0
- package/dist/adapters/agents/model-support.constants.d.ts +3 -1
- package/dist/adapters/agents/model-support.constants.js +12 -2
- package/dist/adapters/agents/model-support.constants.js.map +1 -1
- package/dist/adapters/agents/protocol-fixtures.constants.d.ts +2 -2
- package/dist/adapters/agents/protocol-fixtures.constants.js +131 -9
- package/dist/adapters/agents/protocol-fixtures.constants.js.map +1 -1
- package/dist/adapters/agents/protocol-fixtures.types.d.ts +1 -0
- package/dist/adapters/agents/protocol-fixtures.types.js.map +1 -1
- package/dist/adapters/agents/protocol.d.ts +1 -0
- package/dist/adapters/agents/protocol.js +9 -0
- package/dist/adapters/agents/protocol.js.map +1 -1
- package/dist/adapters/agents/session-usage.constants.d.ts +10 -0
- package/dist/adapters/agents/session-usage.constants.js +110 -0
- package/dist/adapters/agents/session-usage.constants.js.map +1 -0
- package/dist/adapters/agents/session-usage.d.ts +5 -0
- package/dist/adapters/agents/session-usage.js +45 -0
- package/dist/adapters/agents/session-usage.js.map +1 -0
- package/dist/adapters/agents/settings.types.d.ts +1 -0
- package/dist/adapters/agents/settings.types.js.map +1 -1
- package/dist/adapters/agents/tool-result.d.ts +2 -0
- package/dist/adapters/agents/tool-result.js +17 -0
- package/dist/adapters/agents/tool-result.js.map +1 -0
- package/dist/adapters/models/anthropic-response.js +3 -0
- package/dist/adapters/models/anthropic-response.js.map +1 -1
- package/dist/adapters/models/http-provider.js +6 -1
- package/dist/adapters/models/http-provider.js.map +1 -1
- package/dist/adapters/models/openai-responses.js +10 -0
- package/dist/adapters/models/openai-responses.js.map +1 -1
- package/dist/adapters/models/retry-after.d.ts +1 -0
- package/dist/adapters/models/retry-after.js +16 -0
- package/dist/adapters/models/retry-after.js.map +1 -0
- package/dist/application/activity-watchdog.js +1 -2
- package/dist/application/activity-watchdog.js.map +1 -1
- package/dist/application/agent-authentication.d.ts +4 -0
- package/dist/application/agent-authentication.js +32 -0
- package/dist/application/agent-authentication.js.map +1 -0
- package/dist/application/agent-bootstrap.constants.d.ts +2 -5
- package/dist/application/agent-bootstrap.constants.js +27 -4
- package/dist/application/agent-bootstrap.constants.js.map +1 -1
- package/dist/application/agent-bootstrap.js +39 -12
- package/dist/application/agent-bootstrap.js.map +1 -1
- package/dist/application/agent-bootstrap.types.d.ts +19 -0
- package/dist/application/agent-bootstrap.types.js +2 -0
- package/dist/application/agent-bootstrap.types.js.map +1 -0
- package/dist/application/agent-output.js +74 -8
- package/dist/application/agent-output.js.map +1 -1
- package/dist/application/agent-request.d.ts +3 -0
- package/dist/application/agent-request.js +11 -0
- package/dist/application/agent-request.js.map +1 -0
- package/dist/application/agent-turn.js +74 -6
- package/dist/application/agent-turn.js.map +1 -1
- package/dist/application/agent-usage.d.ts +6 -0
- package/dist/application/agent-usage.js +57 -0
- package/dist/application/agent-usage.js.map +1 -0
- package/dist/application/attach.js +2 -0
- package/dist/application/attach.js.map +1 -1
- package/dist/application/credential-installer.constants.d.ts +1 -0
- package/dist/application/credential-installer.constants.js +22 -0
- package/dist/application/credential-installer.constants.js.map +1 -0
- package/dist/application/custom-turn.js +44 -49
- package/dist/application/custom-turn.js.map +1 -1
- package/dist/application/dispatch-observation.d.ts +1 -1
- package/dist/application/dispatch-observation.js +141 -21
- package/dist/application/dispatch-observation.js.map +1 -1
- package/dist/application/dispatch-observation.types.d.ts +2 -0
- package/dist/application/dispatch-observation.types.js.map +1 -1
- package/dist/application/dispatch-validation.js +2 -0
- package/dist/application/dispatch-validation.js.map +1 -1
- package/dist/application/dispatch.js +1 -1
- package/dist/application/dispatch.js.map +1 -1
- package/dist/application/doctor-agent.constants.d.ts +2 -8
- package/dist/application/doctor-agent.constants.js +43 -6
- package/dist/application/doctor-agent.constants.js.map +1 -1
- package/dist/application/doctor-agent.d.ts +2 -1
- package/dist/application/doctor-agent.js +15 -3
- package/dist/application/doctor-agent.js.map +1 -1
- package/dist/application/doctor-image.js +4 -6
- package/dist/application/doctor-image.js.map +1 -1
- package/dist/application/doctor-protocol.js +6 -11
- package/dist/application/doctor-protocol.js.map +1 -1
- package/dist/application/doctor-protocol.types.d.ts +1 -1
- package/dist/application/doctor-protocol.types.js.map +1 -1
- package/dist/application/doctor-sandbox.js +2 -5
- package/dist/application/doctor-sandbox.js.map +1 -1
- package/dist/application/doctor.js +28 -10
- package/dist/application/doctor.js.map +1 -1
- package/dist/application/doctor.types.d.ts +10 -1
- package/dist/application/doctor.types.js.map +1 -1
- package/dist/application/execution.constants.d.ts +2 -0
- package/dist/application/execution.constants.js +2 -0
- package/dist/application/execution.constants.js.map +1 -1
- package/dist/application/execution.types.d.ts +8 -0
- package/dist/application/execution.types.js.map +1 -1
- package/dist/application/harness-budget.d.ts +3 -0
- package/dist/application/harness-budget.js +42 -0
- package/dist/application/harness-budget.js.map +1 -0
- package/dist/application/harness-budget.types.d.ts +5 -0
- package/dist/application/harness-budget.types.js +2 -0
- package/dist/application/harness-budget.types.js.map +1 -0
- package/dist/application/harness-hooks.js +34 -3
- package/dist/application/harness-hooks.js.map +1 -1
- package/dist/application/harness-loop.js +52 -24
- package/dist/application/harness-loop.js.map +1 -1
- package/dist/application/harness-model-provider.d.ts +3 -0
- package/dist/application/harness-model-provider.js +49 -0
- package/dist/application/harness-model-provider.js.map +1 -0
- package/dist/application/harness-model-provider.types.d.ts +10 -0
- package/dist/application/harness-model-provider.types.js +2 -0
- package/dist/application/harness-model-provider.types.js.map +1 -0
- package/dist/application/harness-subagent.d.ts +4 -0
- package/dist/application/harness-subagent.js +110 -0
- package/dist/application/harness-subagent.js.map +1 -0
- package/dist/application/harness.types.d.ts +11 -0
- package/dist/application/harness.types.js.map +1 -1
- package/dist/application/lifecycle-hooks.d.ts +1 -1
- package/dist/application/lifecycle-hooks.js +5 -4
- package/dist/application/lifecycle-hooks.js.map +1 -1
- package/dist/application/observed-lease.d.ts +3 -0
- package/dist/application/observed-lease.js +26 -0
- package/dist/application/observed-lease.js.map +1 -0
- package/dist/application/outpost.types.d.ts +3 -1
- package/dist/application/outpost.types.js.map +1 -1
- package/dist/application/output-lines.d.ts +4 -0
- package/dist/application/output-lines.js +28 -0
- package/dist/application/output-lines.js.map +1 -0
- package/dist/application/queue-worker.js +1 -1
- package/dist/application/queue-worker.js.map +1 -1
- package/dist/application/queue-worker.types.d.ts +1 -0
- package/dist/application/queue-worker.types.js.map +1 -1
- package/dist/application/queued-task.js +24 -5
- package/dist/application/queued-task.js.map +1 -1
- package/dist/application/recovery-archive.d.ts +3 -2
- package/dist/application/recovery-archive.js +9 -2
- package/dist/application/recovery-archive.js.map +1 -1
- package/dist/application/recovery-restore.d.ts +3 -2
- package/dist/application/recovery-restore.js +9 -2
- package/dist/application/recovery-restore.js.map +1 -1
- package/dist/application/recovery-retention.d.ts +3 -2
- package/dist/application/recovery-retention.js +74 -26
- package/dist/application/recovery-retention.js.map +1 -1
- package/dist/application/remote-workspace.js +5 -4
- package/dist/application/remote-workspace.js.map +1 -1
- package/dist/application/remote-workspace.types.d.ts +1 -0
- package/dist/application/remote-workspace.types.js.map +1 -1
- package/dist/application/sandbox-agents.js +19 -19
- package/dist/application/sandbox-agents.js.map +1 -1
- package/dist/application/sandbox-attach.js +12 -3
- package/dist/application/sandbox-attach.js.map +1 -1
- package/dist/application/sandbox-dispatch.js +13 -27
- package/dist/application/sandbox-dispatch.js.map +1 -1
- package/dist/application/sandbox-provision.js +15 -9
- package/dist/application/sandbox-provision.js.map +1 -1
- package/dist/application/sandbox-session.types.d.ts +7 -2
- package/dist/application/sandbox-session.types.js.map +1 -1
- package/dist/application/sandbox.js +13 -6
- package/dist/application/sandbox.js.map +1 -1
- package/dist/application/speculation-checkpoint.d.ts +6 -0
- package/dist/application/speculation-checkpoint.js +206 -0
- package/dist/application/speculation-checkpoint.js.map +1 -0
- package/dist/application/speculation-checkpoint.types.d.ts +24 -0
- package/dist/application/speculation-checkpoint.types.js +2 -0
- package/dist/application/speculation-checkpoint.types.js.map +1 -0
- package/dist/application/speculation-integration.constants.d.ts +4 -0
- package/dist/application/speculation-integration.constants.js +5 -0
- package/dist/application/speculation-integration.constants.js.map +1 -0
- package/dist/application/speculation-integration.d.ts +2 -0
- package/dist/application/speculation-integration.js +67 -0
- package/dist/application/speculation-integration.js.map +1 -0
- package/dist/application/speculation-resume.d.ts +4 -0
- package/dist/application/speculation-resume.js +71 -0
- package/dist/application/speculation-resume.js.map +1 -0
- package/dist/application/speculation-run.d.ts +4 -0
- package/dist/application/speculation-run.js +320 -0
- package/dist/application/speculation-run.js.map +1 -0
- package/dist/application/speculation-timeout.d.ts +1 -0
- package/dist/application/speculation-timeout.js +15 -0
- package/dist/application/speculation-timeout.js.map +1 -0
- package/dist/application/speculation.constants.d.ts +1 -0
- package/dist/application/speculation.constants.js +5 -1
- package/dist/application/speculation.constants.js.map +1 -1
- package/dist/application/speculation.js +41 -149
- package/dist/application/speculation.js.map +1 -1
- package/dist/application/speculation.types.d.ts +23 -0
- package/dist/application/speculation.types.js.map +1 -1
- package/dist/application/startup-recovery.js +14 -1
- package/dist/application/startup-recovery.js.map +1 -1
- package/dist/application/startup-recovery.types.d.ts +1 -0
- package/dist/application/startup-recovery.types.js.map +1 -1
- package/dist/application/stop-reason.d.ts +2 -0
- package/dist/application/stop-reason.js +21 -0
- package/dist/application/stop-reason.js.map +1 -0
- package/dist/application/stop-reason.types.d.ts +4 -0
- package/dist/application/stop-reason.types.js +2 -0
- package/dist/application/stop-reason.types.js.map +1 -0
- package/dist/application/storage-reservation.js +9 -2
- package/dist/application/storage-reservation.js.map +1 -1
- package/dist/application/task-observation.d.ts +3 -0
- package/dist/application/task-observation.js +22 -0
- package/dist/application/task-observation.js.map +1 -0
- package/dist/application/task-usage.js +5 -12
- package/dist/application/task-usage.js.map +1 -1
- package/dist/application/tasks.js +41 -16
- package/dist/application/tasks.js.map +1 -1
- package/dist/application/tool-execution.js +42 -19
- package/dist/application/tool-execution.js.map +1 -1
- package/dist/application/workspace.js +6 -4
- package/dist/application/workspace.js.map +1 -1
- package/dist/cli/doctor-command.js +6 -2
- package/dist/cli/doctor-command.js.map +1 -1
- package/dist/cli/init-authentication.d.ts +4 -1
- package/dist/cli/init-authentication.js +28 -33
- package/dist/cli/init-authentication.js.map +1 -1
- package/dist/cli/init-command.js +3 -3
- package/dist/cli/init-command.js.map +1 -1
- package/dist/cli/main.constants.d.ts +50 -13
- package/dist/cli/main.constants.js +70 -8
- package/dist/cli/main.constants.js.map +1 -1
- package/dist/cli/main.js +2 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/scaffold-files.js +1 -1
- package/dist/cli/scaffold-files.js.map +1 -1
- package/dist/cli/scaffold-validation.js +29 -22
- package/dist/cli/scaffold-validation.js.map +1 -1
- package/dist/cli/scaffold.constants.d.ts +0 -1
- package/dist/cli/scaffold.constants.js +6 -2
- package/dist/cli/scaffold.constants.js.map +1 -1
- package/dist/cli/scaffold.types.d.ts +8 -2
- package/dist/cli/scaffold.types.js.map +1 -1
- package/dist/cli/starters.js +1 -3
- package/dist/cli/starters.js.map +1 -1
- package/dist/domain/agent-observation.d.ts +4 -0
- package/dist/domain/agent-observation.js +27 -0
- package/dist/domain/agent-observation.js.map +1 -0
- package/dist/domain/agent.types.d.ts +122 -14
- package/dist/domain/agent.types.js.map +1 -1
- package/dist/domain/authentication.constants.d.ts +3 -0
- package/dist/domain/authentication.constants.js +11 -0
- package/dist/domain/authentication.constants.js.map +1 -0
- package/dist/domain/authentication.d.ts +3 -0
- package/dist/domain/authentication.js +22 -0
- package/dist/domain/authentication.js.map +1 -0
- package/dist/domain/authentication.types.d.ts +5 -0
- package/dist/domain/authentication.types.js +2 -0
- package/dist/domain/authentication.types.js.map +1 -0
- package/dist/domain/harness.d.ts +2 -2
- package/dist/domain/harness.js +6 -0
- package/dist/domain/harness.js.map +1 -1
- package/dist/domain/harness.types.d.ts +4 -3
- package/dist/domain/harness.types.js.map +1 -1
- package/dist/domain/model.types.d.ts +8 -0
- package/dist/domain/model.types.js.map +1 -1
- package/dist/domain/observation.constants.d.ts +8 -0
- package/dist/domain/observation.constants.js +9 -0
- package/dist/domain/observation.constants.js.map +1 -0
- package/dist/domain/observation.d.ts +2 -0
- package/dist/domain/observation.js +190 -0
- package/dist/domain/observation.js.map +1 -0
- package/dist/domain/observation.types.d.ts +84 -0
- package/dist/domain/observation.types.js +2 -0
- package/dist/domain/observation.types.js.map +1 -0
- package/dist/domain/observed-operation.d.ts +2 -0
- package/dist/domain/observed-operation.js +30 -0
- package/dist/domain/observed-operation.js.map +1 -0
- package/dist/domain/sandbox.types.d.ts +2 -0
- package/dist/domain/sandbox.types.js.map +1 -1
- package/dist/domain/subagent.constants.d.ts +13 -0
- package/dist/domain/subagent.constants.js +9 -0
- package/dist/domain/subagent.constants.js.map +1 -0
- package/dist/domain/subagent.d.ts +4 -0
- package/dist/domain/subagent.js +28 -0
- package/dist/domain/subagent.js.map +1 -0
- package/dist/domain/subagent.types.d.ts +13 -0
- package/dist/domain/subagent.types.js +2 -0
- package/dist/domain/subagent.types.js.map +1 -0
- package/dist/domain/transcript.types.d.ts +2 -0
- package/dist/domain/transcript.types.js.map +1 -1
- package/dist/domain/usage.d.ts +1 -0
- package/dist/domain/usage.js +16 -0
- package/dist/domain/usage.js.map +1 -1
- package/dist/domain/workflow/budget.d.ts +7 -3
- package/dist/domain/workflow/budget.js +26 -0
- package/dist/domain/workflow/budget.js.map +1 -1
- package/dist/domain/workflow/budget.types.d.ts +1 -1
- package/dist/domain/workflow/budget.types.js.map +1 -1
- package/dist/domain/workflow/checkpoint-validation.js +7 -1
- package/dist/domain/workflow/checkpoint-validation.js.map +1 -1
- package/dist/domain/workflow/checkpoint.js +3 -0
- package/dist/domain/workflow/checkpoint.js.map +1 -1
- package/dist/domain/workflow/gate-validation.js +14 -1
- package/dist/domain/workflow/gate-validation.js.map +1 -1
- package/dist/domain/workflow/gates.d.ts +1 -1
- package/dist/domain/workflow/gates.js +52 -4
- package/dist/domain/workflow/gates.js.map +1 -1
- package/dist/domain/workflow/gates.types.d.ts +15 -1
- package/dist/domain/workflow/gates.types.js.map +1 -1
- package/dist/domain/workflow/idempotency.d.ts +1 -0
- package/dist/domain/workflow/idempotency.js +7 -0
- package/dist/domain/workflow/idempotency.js.map +1 -0
- package/dist/domain/workflow/retry.constants.d.ts +2 -0
- package/dist/domain/workflow/retry.constants.js +3 -0
- package/dist/domain/workflow/retry.constants.js.map +1 -0
- package/dist/domain/workflow/retry.d.ts +4 -0
- package/dist/domain/workflow/retry.js +49 -0
- package/dist/domain/workflow/retry.js.map +1 -0
- package/dist/domain/workflow/task-runner.js +9 -5
- package/dist/domain/workflow/task-runner.js.map +1 -1
- package/dist/domain/workflow/task.js +6 -6
- package/dist/domain/workflow/task.js.map +1 -1
- package/dist/domain/workflow/workflow-scheduler.js +110 -72
- package/dist/domain/workflow/workflow-scheduler.js.map +1 -1
- package/dist/domain/workflow/workflow-state.js +28 -12
- package/dist/domain/workflow/workflow-state.js.map +1 -1
- package/dist/domain/workflow.d.ts +1 -1
- package/dist/domain/workflow.js +1 -1
- package/dist/domain/workflow.js.map +1 -1
- package/dist/domain/workflow.types.d.ts +13 -2
- package/dist/domain/workflow.types.js.map +1 -1
- package/dist/index.d.ts +16 -11
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/conversations/capture.js +10 -0
- package/dist/infrastructure/conversations/capture.js.map +1 -1
- package/dist/infrastructure/conversations/harness-transcript.js +6 -0
- package/dist/infrastructure/conversations/harness-transcript.js.map +1 -1
- package/dist/infrastructure/conversations/harness-transcript.types.d.ts +2 -0
- package/dist/infrastructure/conversations/harness-transcript.types.js.map +1 -1
- package/dist/infrastructure/conversations/layout.js +2 -0
- package/dist/infrastructure/conversations/layout.js.map +1 -1
- package/dist/infrastructure/conversations/locate.js +7 -1
- package/dist/infrastructure/conversations/locate.js.map +1 -1
- package/dist/infrastructure/conversations/native-store.js +8 -1
- package/dist/infrastructure/conversations/native-store.js.map +1 -1
- package/dist/infrastructure/conversations/paths.js +3 -0
- package/dist/infrastructure/conversations/paths.js.map +1 -1
- package/dist/infrastructure/conversations/restore.js +7 -0
- package/dist/infrastructure/conversations/restore.js.map +1 -1
- package/dist/infrastructure/conversations/session-bundle.constants.d.ts +5 -0
- package/dist/infrastructure/conversations/session-bundle.constants.js +173 -0
- package/dist/infrastructure/conversations/session-bundle.constants.js.map +1 -0
- package/dist/infrastructure/conversations/session-bundle.d.ts +6 -0
- package/dist/infrastructure/conversations/session-bundle.js +98 -0
- package/dist/infrastructure/conversations/session-bundle.js.map +1 -0
- package/dist/infrastructure/conversations/session-bundle.types.d.ts +1 -0
- package/dist/infrastructure/conversations/session-bundle.types.js +2 -0
- package/dist/infrastructure/conversations/session-bundle.types.js.map +1 -0
- package/dist/infrastructure/conversations.js +4 -2
- package/dist/infrastructure/conversations.js.map +1 -1
- package/dist/infrastructure/conversations.types.d.ts +1 -1
- package/dist/infrastructure/conversations.types.js.map +1 -1
- package/dist/infrastructure/custom-reporter.js +32 -24
- package/dist/infrastructure/custom-reporter.js.map +1 -1
- package/dist/infrastructure/custom-reporter.types.d.ts +2 -0
- package/dist/infrastructure/custom-reporter.types.js.map +1 -1
- package/dist/infrastructure/git/git.constants.d.ts +1 -1
- package/dist/infrastructure/git/git.constants.js +1 -0
- package/dist/infrastructure/git/git.constants.js.map +1 -1
- package/dist/infrastructure/git/workspace-lease.js +4 -3
- package/dist/infrastructure/git/workspace-lease.js.map +1 -1
- package/dist/infrastructure/git/workspace.js +7 -6
- package/dist/infrastructure/git/workspace.js.map +1 -1
- package/dist/infrastructure/git/workspace.types.d.ts +1 -0
- package/dist/infrastructure/git/workspace.types.js.map +1 -1
- package/dist/infrastructure/host-credentials.constants.d.ts +1 -0
- package/dist/infrastructure/host-credentials.constants.js +2 -0
- package/dist/infrastructure/host-credentials.constants.js.map +1 -0
- package/dist/infrastructure/host-credentials.d.ts +4 -0
- package/dist/infrastructure/host-credentials.js +89 -0
- package/dist/infrastructure/host-credentials.js.map +1 -0
- package/dist/infrastructure/inspection-path.js +4 -3
- package/dist/infrastructure/inspection-path.js.map +1 -1
- package/dist/infrastructure/journal.constants.js +10 -1
- package/dist/infrastructure/journal.constants.js.map +1 -1
- package/dist/infrastructure/journal.d.ts +1 -1
- package/dist/infrastructure/journal.js +8 -75
- package/dist/infrastructure/journal.js.map +1 -1
- package/dist/infrastructure/journal.types.d.ts +2 -4
- package/dist/infrastructure/journal.types.js.map +1 -1
- package/dist/infrastructure/local-transport.js +9 -4
- package/dist/infrastructure/local-transport.js.map +1 -1
- package/dist/infrastructure/opentelemetry-dispatch.d.ts +3 -3
- package/dist/infrastructure/opentelemetry-dispatch.js +5 -4
- package/dist/infrastructure/opentelemetry-dispatch.js.map +1 -1
- package/dist/infrastructure/opentelemetry-observation.d.ts +5 -0
- package/dist/infrastructure/opentelemetry-observation.js +59 -0
- package/dist/infrastructure/opentelemetry-observation.js.map +1 -0
- package/dist/infrastructure/opentelemetry.js +15 -1
- package/dist/infrastructure/opentelemetry.js.map +1 -1
- package/dist/infrastructure/opentelemetry.types.d.ts +9 -1
- package/dist/infrastructure/opentelemetry.types.js.map +1 -1
- package/dist/infrastructure/reporter.d.ts +2 -2
- package/dist/infrastructure/reporter.js +5 -1
- package/dist/infrastructure/reporter.js.map +1 -1
- package/dist/infrastructure/repository-transport.constants.d.ts +1 -0
- package/dist/infrastructure/repository-transport.constants.js +2 -0
- package/dist/infrastructure/repository-transport.constants.js.map +1 -0
- package/dist/infrastructure/repository-transport.d.ts +2 -0
- package/dist/infrastructure/repository-transport.js +9 -0
- package/dist/infrastructure/repository-transport.js.map +1 -0
- package/dist/infrastructure/resource-activity-inspection.js +19 -24
- package/dist/infrastructure/resource-activity-inspection.js.map +1 -1
- package/dist/infrastructure/resource-activity.constants.d.ts +0 -1
- package/dist/infrastructure/resource-activity.constants.js +0 -1
- package/dist/infrastructure/resource-activity.constants.js.map +1 -1
- package/dist/infrastructure/resource-activity.js +20 -83
- package/dist/infrastructure/resource-activity.js.map +1 -1
- package/dist/infrastructure/s3-transport.constants.d.ts +2 -0
- package/dist/infrastructure/s3-transport.constants.js +3 -0
- package/dist/infrastructure/s3-transport.constants.js.map +1 -0
- package/dist/infrastructure/s3-transport.js +57 -3
- package/dist/infrastructure/s3-transport.js.map +1 -1
- package/dist/infrastructure/s3-transport.types.d.ts +1 -0
- package/dist/infrastructure/s3-transport.types.js.map +1 -1
- package/dist/infrastructure/speculation-store.constants.d.ts +3 -0
- package/dist/infrastructure/speculation-store.constants.js +2 -0
- package/dist/infrastructure/speculation-store.constants.js.map +1 -0
- package/dist/infrastructure/speculation-store.d.ts +4 -0
- package/dist/infrastructure/speculation-store.js +73 -0
- package/dist/infrastructure/speculation-store.js.map +1 -0
- package/dist/infrastructure/speculation-store.types.d.ts +12 -0
- package/dist/infrastructure/speculation-store.types.js +2 -0
- package/dist/infrastructure/speculation-store.types.js.map +1 -0
- package/dist/infrastructure/storage-inventory.constants.js +1 -0
- package/dist/infrastructure/storage-inventory.constants.js.map +1 -1
- package/dist/infrastructure/storage-inventory.types.d.ts +1 -1
- package/dist/infrastructure/storage-inventory.types.js.map +1 -1
- package/dist/infrastructure/storage-reservations.types.d.ts +0 -8
- package/dist/infrastructure/storage-reservations.types.js.map +1 -1
- package/dist/infrastructure/task-queue-bullmq-resources.js +3 -0
- package/dist/infrastructure/task-queue-bullmq-resources.js.map +1 -1
- package/dist/infrastructure/task-queue-http.js +29 -4
- package/dist/infrastructure/task-queue-http.js.map +1 -1
- package/dist/infrastructure/task-queue-http.types.d.ts +2 -2
- package/dist/infrastructure/task-queue-http.types.js.map +1 -1
- package/dist/infrastructure/transport-conversations.js +2 -0
- package/dist/infrastructure/transport-conversations.js.map +1 -1
- package/dist/infrastructure/transport-journal.d.ts +1 -1
- package/dist/infrastructure/transport-journal.js +8 -2
- package/dist/infrastructure/transport-journal.js.map +1 -1
- package/dist/infrastructure/transport-reservations.d.ts +1 -1
- package/dist/infrastructure/transport-reservations.js +14 -8
- package/dist/infrastructure/transport-reservations.js.map +1 -1
- package/dist/infrastructure/workflow-decision-signature.constants.d.ts +4 -0
- package/dist/infrastructure/workflow-decision-signature.constants.js +5 -0
- package/dist/infrastructure/workflow-decision-signature.constants.js.map +1 -0
- package/dist/infrastructure/workflow-decision-signature.d.ts +4 -0
- package/dist/infrastructure/workflow-decision-signature.js +83 -0
- package/dist/infrastructure/workflow-decision-signature.js.map +1 -0
- package/dist/infrastructure/workflow-decision-signature.types.d.ts +16 -0
- package/dist/infrastructure/workflow-decision-signature.types.js +2 -0
- package/dist/infrastructure/workflow-decision-signature.types.js.map +1 -0
- package/dist/providers/agents.d.ts +7 -2
- package/dist/providers/agents.js +4 -1
- package/dist/providers/agents.js.map +1 -1
- package/dist/providers/antigravity-install.constants.d.ts +2 -0
- package/dist/providers/antigravity-install.constants.js +28 -0
- package/dist/providers/antigravity-install.constants.js.map +1 -0
- package/dist/providers/antigravity-install.d.ts +2 -0
- package/dist/providers/antigravity-install.js +29 -0
- package/dist/providers/antigravity-install.js.map +1 -0
- package/dist/providers/antigravity-install.types.d.ts +4 -0
- package/dist/providers/antigravity-install.types.js +2 -0
- package/dist/providers/antigravity-install.types.js.map +1 -0
- package/dist/providers/container-recovery.d.ts +4 -0
- package/dist/providers/container-recovery.js +28 -0
- package/dist/providers/container-recovery.js.map +1 -0
- package/dist/providers/container.js +8 -0
- package/dist/providers/container.js.map +1 -1
- package/dist/providers/daytona-network.constants.d.ts +5 -0
- package/dist/providers/daytona-network.constants.js +8 -0
- package/dist/providers/daytona-network.constants.js.map +1 -0
- package/dist/providers/daytona-network.d.ts +4 -0
- package/dist/providers/daytona-network.js +33 -0
- package/dist/providers/daytona-network.js.map +1 -0
- package/dist/providers/daytona.d.ts +1 -0
- package/dist/providers/daytona.js +9 -3
- package/dist/providers/daytona.js.map +1 -1
- package/dist/providers/daytona.types.d.ts +2 -0
- package/dist/providers/daytona.types.js.map +1 -1
- package/dist/providers/firecracker-command.js +1 -1
- package/dist/providers/firecracker-command.js.map +1 -1
- package/dist/providers/firecracker-jailer.constants.d.ts +9 -0
- package/dist/providers/firecracker-jailer.constants.js +10 -0
- package/dist/providers/firecracker-jailer.constants.js.map +1 -0
- package/dist/providers/firecracker-jailer.d.ts +4 -0
- package/dist/providers/firecracker-jailer.js +171 -0
- package/dist/providers/firecracker-jailer.js.map +1 -0
- package/dist/providers/firecracker-machine.js +30 -8
- package/dist/providers/firecracker-machine.js.map +1 -1
- package/dist/providers/firecracker.types.d.ts +16 -0
- package/dist/providers/firecracker.types.js.map +1 -1
- package/dist/providers/vercel-network.js +1 -1
- package/dist/providers/vercel-network.js.map +1 -1
- package/dist/providers/vercel.js +6 -3
- package/dist/providers/vercel.js.map +1 -1
- package/dist/providers/versions.constants.d.ts +3 -1
- package/dist/providers/versions.constants.js +3 -1
- package/dist/providers/versions.constants.js.map +1 -1
- package/package.json +3 -3
- package/dist/adapters/agents/gemini-adapter.d.ts +0 -3
- package/dist/adapters/agents/gemini-adapter.js +0 -34
- package/dist/adapters/agents/gemini-adapter.js.map +0 -1
- package/dist/adapters/agents/gemini-diagnostics.d.ts +0 -2
- package/dist/adapters/agents/gemini-diagnostics.js +0 -15
- package/dist/adapters/agents/gemini-diagnostics.js.map +0 -1
- package/dist/adapters/agents/gemini-events.d.ts +0 -2
- package/dist/adapters/agents/gemini-events.js +0 -50
- package/dist/adapters/agents/gemini-events.js.map +0 -1
- package/dist/adapters/agents/gemini-request.js +0 -23
- package/dist/adapters/agents/gemini-request.js.map +0 -1
- package/dist/adapters/agents/gemini.types.js +0 -2
- package/dist/adapters/agents/gemini.types.js.map +0 -1
- package/dist/infrastructure/artifact-store.d.ts +0 -3
- package/dist/infrastructure/artifact-store.js +0 -110
- package/dist/infrastructure/artifact-store.js.map +0 -1
- package/dist/infrastructure/artifact-store.types.d.ts +0 -6
- package/dist/infrastructure/artifact-store.types.js +0 -2
- package/dist/infrastructure/artifact-store.types.js.map +0 -1
- package/dist/infrastructure/journal-retention.constants.d.ts +0 -4
- package/dist/infrastructure/journal-retention.constants.js +0 -5
- package/dist/infrastructure/journal-retention.constants.js.map +0 -1
- package/dist/infrastructure/journal-retention.d.ts +0 -2
- package/dist/infrastructure/journal-retention.js +0 -51
- package/dist/infrastructure/journal-retention.js.map +0 -1
- package/dist/infrastructure/storage-mutation-lock.constants.d.ts +0 -5
- package/dist/infrastructure/storage-mutation-lock.constants.js +0 -6
- package/dist/infrastructure/storage-mutation-lock.constants.js.map +0 -1
- package/dist/infrastructure/storage-mutation-lock.d.ts +0 -1
- package/dist/infrastructure/storage-mutation-lock.js +0 -21
- package/dist/infrastructure/storage-mutation-lock.js.map +0 -1
- package/dist/infrastructure/storage-reservations.constants.d.ts +0 -4
- package/dist/infrastructure/storage-reservations.constants.js +0 -5
- package/dist/infrastructure/storage-reservations.constants.js.map +0 -1
- package/dist/infrastructure/storage-reservations.d.ts +0 -2
- package/dist/infrastructure/storage-reservations.js +0 -150
- package/dist/infrastructure/storage-reservations.js.map +0 -1
- package/dist/infrastructure/workflow-checkpoint.d.ts +0 -3
- package/dist/infrastructure/workflow-checkpoint.js +0 -84
- package/dist/infrastructure/workflow-checkpoint.js.map +0 -1
- package/dist/infrastructure/workflow-checkpoint.types.d.ts +0 -6
- package/dist/infrastructure/workflow-checkpoint.types.js +0 -2
- package/dist/infrastructure/workflow-checkpoint.types.js.map +0 -1
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { invariant, OutpostError } from "../domain/errors.js";
|
|
2
|
+
import { addUsage } from "../domain/usage.js";
|
|
3
|
+
export function harnessBudget(limits, parent) {
|
|
4
|
+
let usage = { input: 0, cached: 0, output: 0 };
|
|
5
|
+
let failure;
|
|
6
|
+
return {
|
|
7
|
+
check() {
|
|
8
|
+
parent?.check();
|
|
9
|
+
if (failure)
|
|
10
|
+
throw failure;
|
|
11
|
+
},
|
|
12
|
+
account(result) {
|
|
13
|
+
parent?.account(result);
|
|
14
|
+
try {
|
|
15
|
+
if (result.usage) {
|
|
16
|
+
const tokens = result.usage;
|
|
17
|
+
for (const value of [
|
|
18
|
+
tokens.input,
|
|
19
|
+
tokens.cached,
|
|
20
|
+
tokens.cacheCreated ?? 0,
|
|
21
|
+
tokens.output,
|
|
22
|
+
])
|
|
23
|
+
invariant(Number.isSafeInteger(value) && value >= 0, "Harness usage must contain nonnegative token counts");
|
|
24
|
+
invariant(tokens.cached + (tokens.cacheCreated ?? 0) <= tokens.input, "Cached tokens must be included in input usage");
|
|
25
|
+
usage = addUsage(usage, tokens);
|
|
26
|
+
}
|
|
27
|
+
if (!limits.usage)
|
|
28
|
+
return;
|
|
29
|
+
if (!result.usage || result.usage.complete === false)
|
|
30
|
+
throw new OutpostError("configuration", "Harness usage limits require a model provider that reports usage completely");
|
|
31
|
+
const exceeded = Object.entries(limits.usage).find(([key, value]) => (usage[key] ?? 0) > value);
|
|
32
|
+
if (exceeded)
|
|
33
|
+
throw new OutpostError("limit", `Harness exceeded its ${exceeded[0]} token budget`, { limit: "usage" });
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
failure ??= error;
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=harness-budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-budget.js","sourceRoot":"","sources":["../../src/application/harness-budget.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,MAAM,UAAU,aAAa,CAC3B,MAAqB,EACrB,MAAsB;IAEtB,IAAI,KAAK,GAAU,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACtD,IAAI,OAAgB,CAAC;IACrB,OAAO;QACL,KAAK;YACH,MAAM,EAAE,KAAK,EAAE,CAAC;YAChB,IAAI,OAAO;gBAAE,MAAM,OAAO,CAAC;QAC7B,CAAC;QACD,OAAO,CAAC,MAAM;YACZ,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YACxB,IAAI,CAAC;gBACH,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;oBACjB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;oBAC5B,KAAK,MAAM,KAAK,IAAI;wBAClB,MAAM,CAAC,KAAK;wBACZ,MAAM,CAAC,MAAM;wBACb,MAAM,CAAC,YAAY,IAAI,CAAC;wBACxB,MAAM,CAAC,MAAM;qBACd;wBACC,SAAS,CACP,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EACzC,qDAAqD,CACtD,CAAC;oBACJ,SAAS,CACP,MAAM,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,EAC1D,+CAA+C,CAChD,CAAC;oBACF,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBAClC,CAAC;gBACD,IAAI,CAAC,MAAM,CAAC,KAAK;oBAAE,OAAO;gBAC1B,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,KAAK,KAAK;oBAClD,MAAM,IAAI,YAAY,CACpB,eAAe,EACf,6EAA6E,CAC9E,CAAC;gBACJ,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAChD,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CACf,CAAC,KAAK,CAAC,GAAuC,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAChE,CAAC;gBACF,IAAI,QAAQ;oBACV,MAAM,IAAI,YAAY,CACpB,OAAO,EACP,wBAAwB,QAAQ,CAAC,CAAC,CAAC,eAAe,EAClD,EAAE,KAAK,EAAE,OAAO,EAAE,CACnB,CAAC;YACN,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,KAAK,KAAK,CAAC;gBAClB,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { Usage } from \"../domain/agent.types.ts\";\nimport { invariant, OutpostError } from \"../domain/errors.ts\";\nimport type { HarnessLimits } from \"../domain/harness.types.ts\";\nimport { addUsage } from \"../domain/usage.ts\";\nimport type { HarnessBudget } from \"./harness-budget.types.ts\";\n\nexport function harnessBudget(\n limits: HarnessLimits,\n parent?: HarnessBudget,\n): HarnessBudget {\n let usage: Usage = { input: 0, cached: 0, output: 0 };\n let failure: unknown;\n return {\n check() {\n parent?.check();\n if (failure) throw failure;\n },\n account(result) {\n parent?.account(result);\n try {\n if (result.usage) {\n const tokens = result.usage;\n for (const value of [\n tokens.input,\n tokens.cached,\n tokens.cacheCreated ?? 0,\n tokens.output,\n ])\n invariant(\n Number.isSafeInteger(value) && value >= 0,\n \"Harness usage must contain nonnegative token counts\",\n );\n invariant(\n tokens.cached + (tokens.cacheCreated ?? 0) <= tokens.input,\n \"Cached tokens must be included in input usage\",\n );\n usage = addUsage(usage, tokens);\n }\n if (!limits.usage) return;\n if (!result.usage || result.usage.complete === false)\n throw new OutpostError(\n \"configuration\",\n \"Harness usage limits require a model provider that reports usage completely\",\n );\n const exceeded = Object.entries(limits.usage).find(\n ([key, value]) =>\n (usage[key as Exclude<keyof Usage, \"complete\">] ?? 0) > value,\n );\n if (exceeded)\n throw new OutpostError(\n \"limit\",\n `Harness exceeded its ${exceeded[0]} token budget`,\n { limit: \"usage\" },\n );\n } catch (error) {\n failure ??= error;\n throw error;\n }\n },\n };\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-budget.types.js","sourceRoot":"","sources":["../../src/application/harness-budget.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ModelResult } from \"../domain/model.types.ts\";\n\nexport interface HarnessBudget {\n check(): void;\n account(result: ModelResult): void;\n}\n"]}
|
|
@@ -22,6 +22,11 @@ export async function beforeTool(runtime, call, step) {
|
|
|
22
22
|
call: current,
|
|
23
23
|
...context(runtime, step),
|
|
24
24
|
});
|
|
25
|
+
runtime.emit({
|
|
26
|
+
kind: "hook",
|
|
27
|
+
phase: "before-tool",
|
|
28
|
+
changed: decision !== undefined,
|
|
29
|
+
});
|
|
25
30
|
if (decision === undefined)
|
|
26
31
|
continue;
|
|
27
32
|
expect(decision !== null && typeof decision === "object", "before-tool hooks may return { deny } or { input }");
|
|
@@ -42,6 +47,11 @@ export async function afterTool(runtime, call, outcome, step, normalize) {
|
|
|
42
47
|
result: current,
|
|
43
48
|
...context(runtime, step),
|
|
44
49
|
});
|
|
50
|
+
runtime.emit({
|
|
51
|
+
kind: "hook",
|
|
52
|
+
phase: "after-tool",
|
|
53
|
+
changed: decision !== undefined,
|
|
54
|
+
});
|
|
45
55
|
if (decision === undefined)
|
|
46
56
|
continue;
|
|
47
57
|
expect(decision !== null && typeof decision === "object" && "result" in decision, "after-tool hooks may only return { result }");
|
|
@@ -52,6 +62,11 @@ export async function afterTool(runtime, call, outcome, step, normalize) {
|
|
|
52
62
|
export async function stopRequest(runtime, text, step) {
|
|
53
63
|
for (const hook of hooks(runtime, "stop")) {
|
|
54
64
|
const decision = await hook.run({ text, ...context(runtime, step) });
|
|
65
|
+
runtime.emit({
|
|
66
|
+
kind: "hook",
|
|
67
|
+
phase: "stop",
|
|
68
|
+
changed: decision !== undefined,
|
|
69
|
+
});
|
|
55
70
|
if (decision === undefined)
|
|
56
71
|
continue;
|
|
57
72
|
expect(decision !== null &&
|
|
@@ -64,11 +79,19 @@ export async function stopRequest(runtime, text, step) {
|
|
|
64
79
|
}
|
|
65
80
|
async function each(runtime, phase, event, step) {
|
|
66
81
|
const decisions = [];
|
|
67
|
-
for (const hook of hooks(runtime, phase))
|
|
68
|
-
|
|
82
|
+
for (const hook of hooks(runtime, phase)) {
|
|
83
|
+
const before = snapshot(event);
|
|
84
|
+
const decision = await hook.run({
|
|
69
85
|
...event,
|
|
70
86
|
...context(runtime, step),
|
|
71
|
-
})
|
|
87
|
+
});
|
|
88
|
+
runtime.emit({
|
|
89
|
+
kind: "hook",
|
|
90
|
+
phase,
|
|
91
|
+
changed: decision !== undefined || before !== snapshot(event),
|
|
92
|
+
});
|
|
93
|
+
decisions.push(decision);
|
|
94
|
+
}
|
|
72
95
|
return decisions;
|
|
73
96
|
}
|
|
74
97
|
function hooks(runtime, phase) {
|
|
@@ -87,4 +110,12 @@ function expect(condition, message) {
|
|
|
87
110
|
if (!condition)
|
|
88
111
|
throw new OutpostError("configuration", message);
|
|
89
112
|
}
|
|
113
|
+
function snapshot(value) {
|
|
114
|
+
try {
|
|
115
|
+
return JSON.stringify(value);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
90
121
|
//# sourceMappingURL=harness-hooks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-hooks.js","sourceRoot":"","sources":["../../src/application/harness-hooks.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"harness-hooks.js","sourceRoot":"","sources":["../../src/application/harness-hooks.ts"],"names":[],"mappings":"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","sourcesContent":["import { OutpostError } from \"../domain/errors.ts\";\nimport type {\n HarnessHook,\n HarnessHookContext,\n HarnessHookEvents,\n HarnessHookInput,\n HarnessHookPhase,\n HarnessHookResult,\n} from \"../domain/hook.types.ts\";\nimport type {\n ModelMessage,\n ModelResult,\n ModelToolCallBlock,\n} from \"../domain/model.types.ts\";\nimport type { ToolOutput } from \"../domain/tool.types.ts\";\nimport type {\n HarnessRuntime,\n ToolDenial,\n ToolOutcome,\n} from \"./harness.types.ts\";\n\nexport async function sessionInstructions(\n runtime: HarnessRuntime,\n prompt: string,\n): Promise<readonly string[]> {\n const texts: string[] = [];\n for (const decision of await each(runtime, \"session-start\", { prompt }, 0)) {\n if (decision === undefined) continue;\n expect(\n typeof decision.instructions === \"string\",\n \"session-start hooks may only return { instructions }\",\n );\n texts.push(decision.instructions);\n }\n return texts;\n}\n\nexport async function beforeModel(\n runtime: HarnessRuntime,\n messages: readonly ModelMessage[],\n step: number,\n): Promise<void> {\n await each(runtime, \"before-model\", { messages }, step);\n}\n\nexport async function afterModel(\n runtime: HarnessRuntime,\n result: ModelResult,\n step: number,\n): Promise<void> {\n await each(runtime, \"after-model\", { result }, step);\n}\n\nexport async function beforeTool(\n runtime: HarnessRuntime,\n call: ModelToolCallBlock,\n step: number,\n): Promise<ToolDenial | ModelToolCallBlock> {\n let current = call;\n for (const hook of hooks(runtime, \"before-tool\")) {\n const decision = await hook.run({\n call: current,\n ...context(runtime, step),\n });\n runtime.emit({\n kind: \"hook\",\n phase: \"before-tool\",\n changed: decision !== undefined,\n });\n if (decision === undefined) continue;\n expect(\n decision !== null && typeof decision === \"object\",\n \"before-tool hooks may return { deny } or { input }\",\n );\n if (\"deny\" in decision) {\n expect(\n typeof decision.deny === \"string\" && decision.deny.trim() !== \"\",\n \"before-tool deny reasons must be nonempty text\",\n );\n return { deny: decision.deny };\n }\n expect(\n \"input\" in decision,\n \"before-tool hooks may return { deny } or { input }\",\n );\n current = { ...current, input: decision.input };\n }\n return current;\n}\n\nexport async function afterTool(\n runtime: HarnessRuntime,\n call: ModelToolCallBlock,\n outcome: ToolOutcome,\n step: number,\n normalize: (output: ToolOutput) => ToolOutcome,\n): Promise<ToolOutcome> {\n let current = outcome;\n for (const hook of hooks(runtime, \"after-tool\")) {\n const decision = await hook.run({\n call,\n result: current,\n ...context(runtime, step),\n });\n runtime.emit({\n kind: \"hook\",\n phase: \"after-tool\",\n changed: decision !== undefined,\n });\n if (decision === undefined) continue;\n expect(\n decision !== null && typeof decision === \"object\" && \"result\" in decision,\n \"after-tool hooks may only return { result }\",\n );\n current = normalize(decision.result);\n }\n return current;\n}\n\nexport async function stopRequest(\n runtime: HarnessRuntime,\n text: string,\n step: number,\n): Promise<string | undefined> {\n for (const hook of hooks(runtime, \"stop\")) {\n const decision = await hook.run({ text, ...context(runtime, step) });\n runtime.emit({\n kind: \"hook\",\n phase: \"stop\",\n changed: decision !== undefined,\n });\n if (decision === undefined) continue;\n expect(\n decision !== null &&\n typeof decision === \"object\" &&\n typeof decision.continue === \"string\" &&\n decision.continue.trim() !== \"\",\n \"stop hooks may only return { continue } with nonempty text\",\n );\n return decision.continue;\n }\n return undefined;\n}\n\nasync function each<Phase extends HarnessHookPhase>(\n runtime: HarnessRuntime,\n phase: Phase,\n event: HarnessHookEvents[Phase],\n step: number,\n): Promise<readonly HarnessHookResult<Phase>[]> {\n const decisions: HarnessHookResult<Phase>[] = [];\n for (const hook of hooks(runtime, phase)) {\n const before = snapshot(event);\n const decision = await hook.run({\n ...event,\n ...context(runtime, step),\n } as HarnessHookInput<Phase>);\n runtime.emit({\n kind: \"hook\",\n phase,\n changed: decision !== undefined || before !== snapshot(event),\n });\n decisions.push(decision);\n }\n return decisions;\n}\n\nfunction hooks<Phase extends HarnessHookPhase>(\n runtime: HarnessRuntime,\n phase: Phase,\n): readonly HarnessHook<Phase>[] {\n return runtime.agent.harness.hooks.filter(\n (hook): hook is HarnessHook<Phase> => hook.on === phase,\n );\n}\n\nfunction context(runtime: HarnessRuntime, step: number): HarnessHookContext {\n runtime.signal.throwIfAborted();\n return {\n sandbox: runtime.sandbox,\n signal: runtime.signal,\n model: runtime.agent.model,\n step,\n };\n}\n\nfunction expect(condition: unknown, message: string): asserts condition {\n if (!condition) throw new OutpostError(\"configuration\", message);\n}\n\nfunction snapshot(value: unknown): string | undefined {\n try {\n return JSON.stringify(value);\n } catch {\n return undefined;\n }\n}\n"]}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { OutpostError } from "../domain/errors.js";
|
|
2
2
|
import { loadedSkills } from "../domain/skill.js";
|
|
3
|
-
import { addUsage } from "../domain/usage.js";
|
|
4
3
|
import { compact } from "./harness-context.js";
|
|
5
4
|
import { afterModel, beforeModel, sessionInstructions, stopRequest, } from "./harness-hooks.js";
|
|
6
5
|
import { executeToolCalls } from "./tool-execution.js";
|
|
@@ -56,15 +55,18 @@ export async function harnessLoop(runtime, prompt, history) {
|
|
|
56
55
|
role: "user",
|
|
57
56
|
content: [{ type: "text", text: prompt }],
|
|
58
57
|
});
|
|
59
|
-
let usage = { input: 0, cached: 0, output: 0 };
|
|
60
58
|
let toolCalls = 0;
|
|
59
|
+
const announcedSkills = new Set();
|
|
61
60
|
for (let step = 1;; step++) {
|
|
62
61
|
runtime.signal.throwIfAborted();
|
|
63
62
|
if (step > harness.limits.maxSteps)
|
|
64
63
|
throw limit("maxSteps", `Harness reached ${harness.limits.maxSteps} steps without a final answer`);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
runtime.budget.check();
|
|
65
|
+
const newlyLoaded = [...loadedSkills(history.messages)].filter((name) => !announcedSkills.has(name));
|
|
66
|
+
for (const name of newlyLoaded)
|
|
67
|
+
announcedSkills.add(name);
|
|
68
|
+
if (newlyLoaded.length)
|
|
69
|
+
runtime.emit({ kind: "skills-loaded", names: newlyLoaded });
|
|
68
70
|
runtime.emit({ kind: "step", index: step });
|
|
69
71
|
await compact(runtime, history, step);
|
|
70
72
|
await beforeModel(runtime, history.messages, step);
|
|
@@ -75,21 +77,21 @@ export async function harnessLoop(runtime, prompt, history) {
|
|
|
75
77
|
...(tools.length ? { tools } : {}),
|
|
76
78
|
...(harness.cache ? { cache: true } : {}),
|
|
77
79
|
});
|
|
78
|
-
if (harness.limits.usage && !result.usage)
|
|
79
|
-
throw new OutpostError("configuration", "Harness usage limits require a model provider that reports usage");
|
|
80
|
-
if (result.usage)
|
|
81
|
-
usage = addUsage(usage, result.usage);
|
|
82
80
|
await afterModel(runtime, result, step);
|
|
83
81
|
const content = result.content ?? [
|
|
84
82
|
{ type: "text", text: result.text },
|
|
85
83
|
];
|
|
86
|
-
for (const block of content)
|
|
84
|
+
for (const block of content) {
|
|
87
85
|
if (block.type === "text" && block.text)
|
|
88
86
|
runtime.emit({ kind: "text", text: block.text });
|
|
87
|
+
if (block.type === "reasoning" && block.text)
|
|
88
|
+
runtime.emit({ kind: "reasoning", text: block.text });
|
|
89
|
+
}
|
|
89
90
|
const state = { history, step, toolCalls };
|
|
90
91
|
const reason = result.stopReason ?? inferredStop(content);
|
|
91
92
|
const answer = await stopHandlers[reason](runtime, state, result, content);
|
|
92
93
|
toolCalls = state.toolCalls;
|
|
94
|
+
runtime.budget.check();
|
|
93
95
|
if (answer !== undefined)
|
|
94
96
|
return answer;
|
|
95
97
|
}
|
|
@@ -101,6 +103,10 @@ async function instructions(runtime) {
|
|
|
101
103
|
model: runtime.agent.model,
|
|
102
104
|
})));
|
|
103
105
|
runtime.signal.throwIfAborted();
|
|
106
|
+
runtime.emit({
|
|
107
|
+
kind: "instructions-loaded",
|
|
108
|
+
count: texts.filter((text) => text.trim()).length,
|
|
109
|
+
});
|
|
104
110
|
return texts.filter((text) => text.trim()).join("\n\n");
|
|
105
111
|
}
|
|
106
112
|
function inferredStop(content) {
|
|
@@ -108,25 +114,47 @@ function inferredStop(content) {
|
|
|
108
114
|
? "tool-calls"
|
|
109
115
|
: "end";
|
|
110
116
|
}
|
|
111
|
-
function exceededUsage(usage, limits) {
|
|
112
|
-
return Object.entries(limits ?? {}).find(([key, value]) => (usage[key] ?? 0) > (value ?? Infinity))?.[0];
|
|
113
|
-
}
|
|
114
117
|
function limit(name, message) {
|
|
115
118
|
return new OutpostError("limit", message, { limit: name });
|
|
116
119
|
}
|
|
117
120
|
async function requestModel(runtime, request) {
|
|
118
121
|
const provider = runtime.modelProvider;
|
|
119
|
-
if (
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (
|
|
124
|
-
runtime.emit({ kind: "
|
|
125
|
-
|
|
126
|
-
|
|
122
|
+
if (runtime.verbose)
|
|
123
|
+
runtime.emit({ kind: "model-request", request });
|
|
124
|
+
try {
|
|
125
|
+
const result = await receive();
|
|
126
|
+
if (runtime.verbose)
|
|
127
|
+
runtime.emit({ kind: "model-response", response: result });
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
runtime.emit({
|
|
132
|
+
kind: "model-error",
|
|
133
|
+
message: error instanceof Error ? error.message : String(error),
|
|
134
|
+
});
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
async function receive() {
|
|
138
|
+
if (!provider.stream)
|
|
139
|
+
return provider.request(request);
|
|
140
|
+
let result;
|
|
141
|
+
for await (const event of provider.stream(request)) {
|
|
142
|
+
if (event.type === "text-delta")
|
|
143
|
+
runtime.emit({ kind: "text-delta", text: event.text });
|
|
144
|
+
if (event.type === "reasoning")
|
|
145
|
+
runtime.emit({ kind: "reasoning", text: event.text });
|
|
146
|
+
if (event.type === "retry")
|
|
147
|
+
runtime.emit({
|
|
148
|
+
kind: "model-retry",
|
|
149
|
+
attempt: event.attempt,
|
|
150
|
+
...(event.message ? { message: event.message } : {}),
|
|
151
|
+
});
|
|
152
|
+
if (event.type === "result")
|
|
153
|
+
result = event.result;
|
|
154
|
+
}
|
|
155
|
+
if (!result)
|
|
156
|
+
throw new OutpostError("response", "Model stream ended without a result");
|
|
157
|
+
return result;
|
|
127
158
|
}
|
|
128
|
-
if (!result)
|
|
129
|
-
throw new OutpostError("response", "Model stream ended without a result");
|
|
130
|
-
return result;
|
|
131
159
|
}
|
|
132
160
|
//# sourceMappingURL=harness-loop.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-loop.js","sourceRoot":"","sources":["../../src/application/harness-loop.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Usage } from \"../domain/agent.types.ts\";\nimport { 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 { addUsage } from \"../domain/usage.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 if (message === undefined) return result.text;\n runtime.emit({ kind: \"stop-prevented\", message });\n await state.history.append({\n role: \"user\",\n content: [{ type: \"text\", text: message }],\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 await state.history.append({\n role: \"user\",\n content: await executeToolCalls(\n runtime,\n calls,\n state.step,\n loadedSkills(state.history.messages),\n ),\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 }],\n });\n let usage: Usage = { input: 0, cached: 0, output: 0 };\n let toolCalls = 0;\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 const exceeded = exceededUsage(usage, harness.limits.usage);\n if (exceeded)\n throw limit(\"usage\", `Harness exceeded its ${exceeded} token budget`);\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 if (harness.limits.usage && !result.usage)\n throw new OutpostError(\n \"configuration\",\n \"Harness usage limits require a model provider that reports usage\",\n );\n if (result.usage) usage = addUsage(usage, result.usage);\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 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 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 }),\n ),\n );\n runtime.signal.throwIfAborted();\n return texts.filter((text) => text.trim()).join(\"\\n\\n\");\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 exceededUsage(\n usage: Usage,\n limits: Partial<Usage> | undefined,\n): string | undefined {\n return Object.entries(limits ?? {}).find(\n ([key, value]) => (usage[key as keyof Usage] ?? 0) > (value ?? Infinity),\n )?.[0];\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 (!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 === \"result\") result = event.result;\n }\n if (!result)\n throw new OutpostError(\"response\", \"Model stream ended without a result\");\n return result;\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;AAEvD,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,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC,IAAI,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC,CAAC;QAClD,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YACzB,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;SAC3C,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,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YACzB,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,MAAM,gBAAgB,CAC7B,OAAO,EACP,KAAK,EACL,KAAK,CAAC,IAAI,EACV,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CACrC;SACF,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,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;IACzC,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,CAAC;KAC1C,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,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,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;KAC3B,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,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\";\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 if (message === undefined) return result.text;\n runtime.emit({ kind: \"stop-prevented\", message });\n await state.history.append({\n role: \"user\",\n content: [{ type: \"text\", text: message }],\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 await state.history.append({\n role: \"user\",\n content: await executeToolCalls(\n runtime,\n calls,\n state.step,\n loadedSkills(state.history.messages),\n ),\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 }],\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 }),\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 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"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { invariant } from "../domain/errors.js";
|
|
2
|
+
export function harnessModelProvider(scope) {
|
|
3
|
+
const { agent, signal, budget, track } = scope;
|
|
4
|
+
const provider = agent.harness.modelProvider;
|
|
5
|
+
const scoped = (request) => {
|
|
6
|
+
signal.throwIfAborted();
|
|
7
|
+
budget.check();
|
|
8
|
+
const { reasoning, maxOutputTokens } = agent.model;
|
|
9
|
+
return {
|
|
10
|
+
...(reasoning === undefined ? {} : { reasoning }),
|
|
11
|
+
...(maxOutputTokens === undefined ? {} : { maxOutputTokens }),
|
|
12
|
+
...request,
|
|
13
|
+
signal,
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
const account = (result) => {
|
|
17
|
+
signal.throwIfAborted();
|
|
18
|
+
invariant(result && typeof result.text === "string", "Model provider must return text");
|
|
19
|
+
scope.account(result);
|
|
20
|
+
budget.account(result);
|
|
21
|
+
return result;
|
|
22
|
+
};
|
|
23
|
+
async function* stream(request) {
|
|
24
|
+
let finish;
|
|
25
|
+
track(new Promise((resolve) => (finish = resolve)));
|
|
26
|
+
try {
|
|
27
|
+
let received = false;
|
|
28
|
+
for await (const event of provider.stream(scoped(request))) {
|
|
29
|
+
signal.throwIfAborted();
|
|
30
|
+
if (event.type === "result") {
|
|
31
|
+
invariant(!received, "Model stream returned more than one result");
|
|
32
|
+
received = true;
|
|
33
|
+
yield { type: "result", result: account(event.result) };
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
yield event;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
finish();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
name: provider.name,
|
|
45
|
+
...(provider.stream ? { stream } : {}),
|
|
46
|
+
request: (request) => track(Promise.resolve().then(async () => account(await provider.request(scoped(request))))),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=harness-model-provider.js.map
|
|
@@ -0,0 +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,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC;QACnD,OAAO;YACL,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;YACjD,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC;YAC7D,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 const { reasoning, maxOutputTokens } = agent.model;\n return {\n ...(reasoning === undefined ? {} : { reasoning }),\n ...(maxOutputTokens === undefined ? {} : { maxOutputTokens }),\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,10 @@
|
|
|
1
|
+
import type { CustomAgent } from "../domain/agent.types.ts";
|
|
2
|
+
import type { ModelResult } from "../domain/model.types.ts";
|
|
3
|
+
import type { HarnessBudget } from "./harness-budget.types.ts";
|
|
4
|
+
export interface HarnessModelScope {
|
|
5
|
+
readonly agent: CustomAgent;
|
|
6
|
+
readonly signal: AbortSignal;
|
|
7
|
+
readonly budget: HarnessBudget;
|
|
8
|
+
track<T>(operation: Promise<T>): Promise<T>;
|
|
9
|
+
account(result: ModelResult, subagentId?: string): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-model-provider.types.js","sourceRoot":"","sources":["../../src/application/harness-model-provider.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { CustomAgent } from \"../domain/agent.types.ts\";\nimport type { ModelResult } from \"../domain/model.types.ts\";\nimport type { HarnessBudget } from \"./harness-budget.types.ts\";\n\nexport interface HarnessModelScope {\n readonly agent: CustomAgent;\n readonly signal: AbortSignal;\n readonly budget: HarnessBudget;\n track<T>(operation: Promise<T>): Promise<T>;\n account(result: ModelResult, subagentId?: string): void;\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { HarnessSubagent } from "../domain/subagent.types.ts";
|
|
2
|
+
import type { HarnessToolContext } from "../domain/tool.types.ts";
|
|
3
|
+
import type { HarnessRuntime } from "./harness.types.ts";
|
|
4
|
+
export declare function runSubagent(runtime: HarnessRuntime, tool: HarnessSubagent, input: unknown, context: HarnessToolContext): Promise<string>;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { OutpostError, recordRecovery } from "../domain/errors.js";
|
|
4
|
+
import { MAX_DELEGATION_DEPTH } from "../domain/subagent.constants.js";
|
|
5
|
+
import { openTranscript } from "../infrastructure/conversations/harness-transcript.js";
|
|
6
|
+
import { storageFor } from "./agent-storage.js";
|
|
7
|
+
import { harnessBudget } from "./harness-budget.js";
|
|
8
|
+
import { harnessHistory } from "./harness-history.js";
|
|
9
|
+
import { harnessLoop } from "./harness-loop.js";
|
|
10
|
+
import { harnessModelProvider } from "./harness-model-provider.js";
|
|
11
|
+
export async function runSubagent(runtime, tool, input, context) {
|
|
12
|
+
const validated = await tool.validate(input);
|
|
13
|
+
if ("issues" in validated)
|
|
14
|
+
throw new OutpostError("configuration", validated.issues);
|
|
15
|
+
if (runtime.depth >= runtime.maxDepth)
|
|
16
|
+
throw new OutpostError("limit", "Harness reached its delegation depth limit", { limit: "maxDelegationDepth" });
|
|
17
|
+
runtime.budget.check();
|
|
18
|
+
const agent = tool.subagent;
|
|
19
|
+
const budget = harnessBudget(agent.harness.limits, runtime.budget);
|
|
20
|
+
const id = randomUUID();
|
|
21
|
+
const depth = runtime.depth + 1;
|
|
22
|
+
const store = storageFor(agent);
|
|
23
|
+
let transcript;
|
|
24
|
+
let failure;
|
|
25
|
+
let text = "";
|
|
26
|
+
const lifecycle = (status) => runtime.emit({
|
|
27
|
+
kind: "subagent",
|
|
28
|
+
id,
|
|
29
|
+
callId: context.callId,
|
|
30
|
+
name: tool.name,
|
|
31
|
+
status,
|
|
32
|
+
...(transcript ? { conversation: transcript.id } : {}),
|
|
33
|
+
});
|
|
34
|
+
try {
|
|
35
|
+
transcript = store
|
|
36
|
+
? await openTranscript({
|
|
37
|
+
repository: runtime.repository,
|
|
38
|
+
store,
|
|
39
|
+
model: agent.model.name,
|
|
40
|
+
...(runtime.conversation
|
|
41
|
+
? { parentConversation: runtime.conversation }
|
|
42
|
+
: {}),
|
|
43
|
+
parentCallId: context.callId,
|
|
44
|
+
})
|
|
45
|
+
: undefined;
|
|
46
|
+
lifecycle("started");
|
|
47
|
+
text = await harnessLoop({
|
|
48
|
+
...runtime,
|
|
49
|
+
agent,
|
|
50
|
+
budget,
|
|
51
|
+
depth,
|
|
52
|
+
maxDepth: Math.min(runtime.maxDepth, depth +
|
|
53
|
+
(agent.harness.limits.maxDelegationDepth ?? MAX_DELEGATION_DEPTH)),
|
|
54
|
+
conversation: transcript?.id,
|
|
55
|
+
tools: agent.harness.tools,
|
|
56
|
+
permissions: [
|
|
57
|
+
...runtime.permissions,
|
|
58
|
+
...(agent.harness.permissions ? [agent.harness.permissions] : []),
|
|
59
|
+
],
|
|
60
|
+
sandbox: context.sandbox,
|
|
61
|
+
signal: context.signal,
|
|
62
|
+
modelProvider: harnessModelProvider({
|
|
63
|
+
agent,
|
|
64
|
+
signal: context.signal,
|
|
65
|
+
budget,
|
|
66
|
+
...runtime.modelScope,
|
|
67
|
+
account: (result) => runtime.modelScope.account(result, id),
|
|
68
|
+
}),
|
|
69
|
+
emit: (event) => {
|
|
70
|
+
context.signal.throwIfAborted();
|
|
71
|
+
runtime.emit({ ...event, subagentId: event.subagentId ?? id });
|
|
72
|
+
},
|
|
73
|
+
}, validated.value.prompt, harnessHistory(transcript));
|
|
74
|
+
context.signal.throwIfAborted();
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
failure = error;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
if (transcript && store)
|
|
81
|
+
await store.capture(transcript.id, {
|
|
82
|
+
repository: runtime.repository,
|
|
83
|
+
sandbox: context.sandbox,
|
|
84
|
+
staging: join(runtime.repository, ".outpost", "conversations", "harness"),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
if (failure)
|
|
89
|
+
recordRecovery(failure, {
|
|
90
|
+
subagentCaptureError: error,
|
|
91
|
+
conversation: transcript?.id,
|
|
92
|
+
});
|
|
93
|
+
failure ??= error;
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
await transcript?.close();
|
|
97
|
+
}
|
|
98
|
+
if (failure) {
|
|
99
|
+
if (!runtime.signal.aborted)
|
|
100
|
+
lifecycle("failed");
|
|
101
|
+
throw failure;
|
|
102
|
+
}
|
|
103
|
+
context.signal.throwIfAborted();
|
|
104
|
+
lifecycle("finished");
|
|
105
|
+
return JSON.stringify({
|
|
106
|
+
text,
|
|
107
|
+
...(transcript ? { conversation: transcript.id } : {}),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=harness-subagent.js.map
|
|
@@ -0,0 +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 { 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 harnessLoop(\n {\n ...runtime,\n agent,\n budget,\n depth,\n maxDepth: Math.min(\n runtime.maxDepth,\n depth +\n (agent.harness.limits.maxDelegationDepth ?? MAX_DELEGATION_DEPTH),\n ),\n conversation: transcript?.id,\n tools: agent.harness.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 context.signal.throwIfAborted();\n } catch (error) {\n failure = error;\n }\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,9 +1,20 @@
|
|
|
1
|
+
import type { HarnessBudget } from "./harness-budget.types.ts";
|
|
2
|
+
import type { HarnessPermissions } from "../domain/permissions.types.ts";
|
|
3
|
+
import type { HarnessModelScope } from "./harness-model-provider.types.ts";
|
|
1
4
|
import type { AgentEvent, CustomAgent } from "../domain/agent.types.ts";
|
|
2
5
|
import type { ModelContentBlock, ModelMessage, ModelProvider, ModelResult, ModelToolCallBlock } from "../domain/model.types.ts";
|
|
3
6
|
import type { SandboxLease } from "../domain/sandbox.types.ts";
|
|
4
7
|
import type { HarnessTool } from "../domain/tool.types.ts";
|
|
5
8
|
import type { DispatchOptions, TurnContext } from "./execution.types.ts";
|
|
6
9
|
export interface HarnessRuntime {
|
|
10
|
+
readonly verbose?: boolean;
|
|
11
|
+
readonly repository: string;
|
|
12
|
+
readonly conversation?: string | undefined;
|
|
13
|
+
readonly budget: HarnessBudget;
|
|
14
|
+
readonly permissions: readonly HarnessPermissions[];
|
|
15
|
+
readonly depth: number;
|
|
16
|
+
readonly maxDepth: number;
|
|
17
|
+
readonly modelScope: Pick<HarnessModelScope, "track" | "account">;
|
|
7
18
|
readonly agent: CustomAgent;
|
|
8
19
|
readonly tools: readonly HarnessTool[];
|
|
9
20
|
readonly modelProvider: ModelProvider;
|