@elie-laloum/outpost 4.2.0 → 5.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 +27 -0
- package/README.md +5 -3
- package/dist/{cli/init-authentication.constants.js → adapters/agents/authentication.constants.js} +1 -1
- package/dist/adapters/agents/authentication.constants.js.map +1 -0
- package/dist/adapters/agents/authentication.d.ts +2 -0
- package/dist/adapters/agents/authentication.js +52 -0
- package/dist/adapters/agents/authentication.js.map +1 -0
- package/dist/adapters/agents/claude-adapter.d.ts +2 -2
- package/dist/adapters/agents/claude-adapter.js +30 -2
- package/dist/adapters/agents/claude-adapter.js.map +1 -1
- package/dist/adapters/agents/claude-request.d.ts +2 -2
- package/dist/adapters/agents/claude-request.js +3 -3
- package/dist/adapters/agents/claude-request.js.map +1 -1
- package/dist/adapters/agents/codex-adapter.d.ts +2 -2
- package/dist/adapters/agents/codex-adapter.js +17 -1
- package/dist/adapters/agents/codex-adapter.js.map +1 -1
- package/dist/adapters/agents/codex-provider.d.ts +2 -2
- package/dist/adapters/agents/codex-provider.js +1 -1
- package/dist/adapters/agents/codex-provider.js.map +1 -1
- package/dist/adapters/agents/codex-request.d.ts +2 -2
- package/dist/adapters/agents/codex-request.js +3 -3
- package/dist/adapters/agents/codex-request.js.map +1 -1
- package/dist/adapters/agents/gemini-adapter.d.ts +2 -2
- package/dist/adapters/agents/gemini-adapter.js +20 -1
- package/dist/adapters/agents/gemini-adapter.js.map +1 -1
- package/dist/adapters/agents/gemini-request.d.ts +2 -1
- package/dist/adapters/agents/gemini-request.js +1 -1
- package/dist/adapters/agents/gemini-request.js.map +1 -1
- package/dist/adapters/agents/gemini.types.d.ts +2 -1
- package/dist/adapters/agents/gemini.types.js.map +1 -1
- package/dist/adapters/agents/model-support.constants.d.ts +6 -0
- package/dist/adapters/agents/model-support.constants.js +18 -0
- package/dist/adapters/agents/model-support.constants.js.map +1 -0
- package/dist/adapters/agents/model-support.d.ts +4 -0
- package/dist/adapters/agents/model-support.js +11 -0
- package/dist/adapters/agents/model-support.js.map +1 -0
- package/dist/adapters/agents/settings.types.d.ts +11 -3
- package/dist/adapters/agents/settings.types.js.map +1 -1
- package/dist/adapters/models/anthropic-model-provider.constants.d.ts +3 -0
- package/dist/adapters/models/anthropic-model-provider.constants.js +17 -0
- package/dist/adapters/models/anthropic-model-provider.constants.js.map +1 -0
- package/dist/adapters/models/anthropic-model-provider.d.ts +3 -0
- package/dist/adapters/models/anthropic-model-provider.js +31 -0
- package/dist/adapters/models/anthropic-model-provider.js.map +1 -0
- package/dist/adapters/models/anthropic-model-provider.types.d.ts +7 -0
- package/dist/adapters/models/anthropic-model-provider.types.js +2 -0
- package/dist/adapters/models/anthropic-model-provider.types.js.map +1 -0
- package/dist/adapters/models/anthropic-request.d.ts +4 -0
- package/dist/adapters/models/anthropic-request.js +81 -0
- package/dist/adapters/models/anthropic-request.js.map +1 -0
- package/dist/adapters/models/anthropic-response.d.ts +3 -0
- package/dist/adapters/models/anthropic-response.js +55 -0
- package/dist/adapters/models/anthropic-response.js.map +1 -0
- package/dist/adapters/models/anthropic-stream.d.ts +2 -0
- package/dist/adapters/models/anthropic-stream.js +96 -0
- package/dist/adapters/models/anthropic-stream.js.map +1 -0
- package/dist/adapters/models/http-provider.d.ts +3 -0
- package/dist/adapters/models/http-provider.js +113 -0
- package/dist/adapters/models/http-provider.js.map +1 -0
- package/dist/adapters/models/{openai-http.js → model-http.js} +1 -1
- package/dist/adapters/models/model-http.js.map +1 -0
- package/dist/adapters/models/model-protocol.types.d.ts +41 -0
- package/dist/adapters/models/model-protocol.types.js +2 -0
- package/dist/adapters/models/model-protocol.types.js.map +1 -0
- package/dist/adapters/models/model-request.d.ts +2 -0
- package/dist/adapters/models/model-request.js +18 -0
- package/dist/adapters/models/model-request.js.map +1 -0
- package/dist/adapters/models/model-response.d.ts +7 -0
- package/dist/adapters/models/model-response.js +41 -0
- package/dist/adapters/models/model-response.js.map +1 -0
- package/dist/adapters/models/{openai-compatible.constants.js → model.constants.js} +6 -1
- package/dist/adapters/models/model.constants.js.map +1 -0
- package/dist/adapters/models/openai-chat-stream.d.ts +2 -0
- package/dist/adapters/models/openai-chat-stream.js +66 -0
- package/dist/adapters/models/openai-chat-stream.js.map +1 -0
- package/dist/adapters/models/openai-chat.d.ts +4 -0
- package/dist/adapters/models/openai-chat.js +108 -0
- package/dist/adapters/models/openai-chat.js.map +1 -0
- package/dist/adapters/models/openai-model-provider.d.ts +3 -0
- package/dist/adapters/models/openai-model-provider.js +13 -0
- package/dist/adapters/models/openai-model-provider.js.map +1 -0
- package/dist/adapters/models/openai-model-provider.types.d.ts +4 -0
- package/dist/adapters/models/openai-model-provider.types.js +2 -0
- package/dist/adapters/models/openai-model-provider.types.js.map +1 -0
- package/dist/adapters/models/openai-protocols.d.ts +2 -0
- package/dist/adapters/models/openai-protocols.js +22 -0
- package/dist/adapters/models/openai-protocols.js.map +1 -0
- package/dist/adapters/models/openai-responses-stream.d.ts +2 -0
- package/dist/adapters/models/openai-responses-stream.js +35 -0
- package/dist/adapters/models/openai-responses-stream.js.map +1 -0
- package/dist/adapters/models/openai-responses.d.ts +4 -0
- package/dist/adapters/models/openai-responses.js +107 -0
- package/dist/adapters/models/openai-responses.js.map +1 -0
- package/dist/adapters/models/openai-usage.d.ts +3 -0
- package/dist/adapters/models/openai-usage.js +20 -0
- package/dist/adapters/models/openai-usage.js.map +1 -0
- package/dist/adapters/models/stop-reasons.constants.d.ts +4 -0
- package/dist/adapters/models/stop-reasons.constants.js +19 -0
- package/dist/adapters/models/stop-reasons.constants.js.map +1 -0
- package/dist/adapters/models/stream-events.d.ts +3 -0
- package/dist/adapters/models/stream-events.js +22 -0
- package/dist/adapters/models/stream-events.js.map +1 -0
- package/dist/adapters/tools/edit-tools.d.ts +2 -0
- package/dist/adapters/tools/edit-tools.js +84 -0
- package/dist/adapters/tools/edit-tools.js.map +1 -0
- package/dist/adapters/tools/file-tools.d.ts +2 -0
- package/dist/adapters/tools/file-tools.js +97 -0
- package/dist/adapters/tools/file-tools.js.map +1 -0
- package/dist/adapters/tools/git-tools.d.ts +2 -0
- package/dist/adapters/tools/git-tools.js +54 -0
- package/dist/adapters/tools/git-tools.js.map +1 -0
- package/dist/adapters/tools/sandbox-files.d.ts +10 -0
- package/dist/adapters/tools/sandbox-files.js +60 -0
- package/dist/adapters/tools/sandbox-files.js.map +1 -0
- package/dist/adapters/tools/search-tools.d.ts +2 -0
- package/dist/adapters/tools/search-tools.js +65 -0
- package/dist/adapters/tools/search-tools.js.map +1 -0
- package/dist/adapters/tools/shell-tools.d.ts +3 -0
- package/dist/adapters/tools/shell-tools.js +38 -0
- package/dist/adapters/tools/shell-tools.js.map +1 -0
- package/dist/adapters/tools/tools.constants.d.ts +11 -0
- package/dist/adapters/tools/tools.constants.js +17 -0
- package/dist/adapters/tools/tools.constants.js.map +1 -0
- package/dist/adapters/tools/tools.types.d.ts +41 -0
- package/dist/adapters/tools/tools.types.js +2 -0
- package/dist/adapters/tools/tools.types.js.map +1 -0
- package/dist/application/activity-watchdog.js +15 -2
- package/dist/application/activity-watchdog.js.map +1 -1
- package/dist/application/agent-bootstrap.d.ts +2 -2
- package/dist/application/agent-bootstrap.js +2 -0
- package/dist/application/agent-bootstrap.js.map +1 -1
- package/dist/application/agent-storage.d.ts +3 -2
- package/dist/application/agent-storage.js +9 -2
- package/dist/application/agent-storage.js.map +1 -1
- package/dist/application/agent-turn.d.ts +3 -3
- package/dist/application/agent-turn.js +7 -1
- package/dist/application/agent-turn.js.map +1 -1
- package/dist/application/attach.js +1 -0
- package/dist/application/attach.js.map +1 -1
- package/dist/application/custom-turn.d.ts +5 -0
- package/dist/application/custom-turn.js +190 -0
- package/dist/application/custom-turn.js.map +1 -0
- package/dist/application/dispatch-observation.d.ts +3 -0
- package/dist/application/dispatch-observation.js +51 -0
- package/dist/application/dispatch-observation.js.map +1 -0
- package/dist/application/dispatch-observation.types.d.ts +5 -0
- package/dist/application/dispatch-observation.types.js +2 -0
- package/dist/application/dispatch-observation.types.js.map +1 -0
- package/dist/application/dispatch-validation.d.ts +2 -2
- package/dist/application/dispatch-validation.js.map +1 -1
- package/dist/application/dispatch.js +8 -3
- package/dist/application/dispatch.js.map +1 -1
- package/dist/application/doctor-image.js +3 -3
- package/dist/application/doctor-image.js.map +1 -1
- package/dist/application/doctor-protocol.js +9 -4
- package/dist/application/doctor-protocol.js.map +1 -1
- package/dist/application/doctor-sandbox.js +4 -4
- package/dist/application/doctor-sandbox.js.map +1 -1
- package/dist/application/doctor-sandbox.types.d.ts +2 -2
- package/dist/application/doctor-sandbox.types.js.map +1 -1
- package/dist/application/doctor.constants.d.ts +1 -1
- package/dist/application/doctor.constants.js +1 -1
- package/dist/application/doctor.constants.js.map +1 -1
- package/dist/application/doctor.js +10 -9
- package/dist/application/doctor.js.map +1 -1
- package/dist/application/doctor.types.d.ts +3 -3
- package/dist/application/doctor.types.js.map +1 -1
- package/dist/application/execution.d.ts +2 -2
- package/dist/application/execution.js +1 -1
- package/dist/application/execution.js.map +1 -1
- package/dist/application/execution.types.d.ts +9 -2
- package/dist/application/execution.types.js.map +1 -1
- package/dist/application/harness-context.d.ts +2 -0
- package/dist/application/harness-context.js +54 -0
- package/dist/application/harness-context.js.map +1 -0
- package/dist/application/harness-history.d.ts +3 -0
- package/dist/application/harness-history.js +17 -0
- package/dist/application/harness-history.js.map +1 -0
- package/dist/application/harness-hooks.d.ts +9 -0
- package/dist/application/harness-hooks.js +90 -0
- package/dist/application/harness-hooks.js.map +1 -0
- package/dist/application/harness-loop.d.ts +2 -0
- package/dist/application/harness-loop.js +132 -0
- package/dist/application/harness-loop.js.map +1 -0
- package/dist/application/harness.types.d.ts +55 -0
- package/dist/application/harness.types.js +2 -0
- package/dist/application/harness.types.js.map +1 -0
- package/dist/application/lifecycle.constants.d.ts +1 -1
- package/dist/application/lifecycle.constants.js +1 -1
- package/dist/application/lifecycle.constants.js.map +1 -1
- package/dist/application/outpost.types.d.ts +6 -6
- package/dist/application/outpost.types.js.map +1 -1
- package/dist/application/remote-download.js +1 -1
- package/dist/application/remote-download.js.map +1 -1
- package/dist/application/sandbox-agents.js +12 -4
- package/dist/application/sandbox-agents.js.map +1 -1
- package/dist/application/sandbox-attach.js +5 -2
- package/dist/application/sandbox-attach.js.map +1 -1
- package/dist/application/sandbox-dispatch.js +3 -3
- package/dist/application/sandbox-dispatch.js.map +1 -1
- package/dist/application/sandbox-provision.js +13 -10
- package/dist/application/sandbox-provision.js.map +1 -1
- package/dist/application/sandbox-session.types.d.ts +8 -8
- package/dist/application/sandbox-session.types.js.map +1 -1
- package/dist/application/sandbox.js +6 -3
- package/dist/application/sandbox.js.map +1 -1
- package/dist/application/speculation.js +1 -1
- package/dist/application/speculation.js.map +1 -1
- package/dist/application/speculation.types.d.ts +3 -3
- package/dist/application/speculation.types.js.map +1 -1
- package/dist/application/tasks.types.d.ts +2 -2
- package/dist/application/tasks.types.js.map +1 -1
- package/dist/application/tool-execution.d.ts +3 -0
- package/dist/application/tool-execution.js +211 -0
- package/dist/application/tool-execution.js.map +1 -0
- package/dist/cli/commands.js +4 -2
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/doctor-command.js +6 -6
- package/dist/cli/doctor-command.js.map +1 -1
- package/dist/cli/init-authentication.js +6 -7
- 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 +4 -4
- package/dist/cli/main.constants.js +4 -4
- package/dist/cli/main.constants.js.map +1 -1
- package/dist/cli/recovery-command.js +1 -1
- package/dist/cli/recovery-command.js.map +1 -1
- package/dist/cli/scaffold-files.js +5 -4
- package/dist/cli/scaffold-files.js.map +1 -1
- package/dist/cli/scaffold-validation.js +13 -10
- package/dist/cli/scaffold-validation.js.map +1 -1
- package/dist/cli/scaffold.js +8 -4
- package/dist/cli/scaffold.js.map +1 -1
- package/dist/cli/scaffold.types.d.ts +1 -1
- package/dist/cli/scaffold.types.js.map +1 -1
- package/dist/cli/starters.js +8 -8
- package/dist/cli/starters.js.map +1 -1
- package/dist/domain/agent-model.d.ts +3 -0
- package/dist/domain/agent-model.js +22 -0
- package/dist/domain/agent-model.js.map +1 -0
- package/dist/domain/agent.d.ts +4 -0
- package/dist/domain/agent.js +32 -0
- package/dist/domain/agent.js.map +1 -0
- package/dist/domain/agent.types.d.ts +69 -2
- package/dist/domain/agent.types.js.map +1 -1
- package/dist/domain/context.constants.d.ts +7 -0
- package/dist/domain/context.constants.js +8 -0
- package/dist/domain/context.constants.js.map +1 -0
- package/dist/domain/context.d.ts +4 -0
- package/dist/domain/context.js +81 -0
- package/dist/domain/context.js.map +1 -0
- package/dist/domain/context.types.d.ts +26 -0
- package/dist/domain/context.types.js +2 -0
- package/dist/domain/context.types.js.map +1 -0
- package/dist/domain/dispatch-telemetry.types.d.ts +12 -0
- package/dist/domain/dispatch-telemetry.types.js +2 -0
- package/dist/domain/dispatch-telemetry.types.js.map +1 -0
- package/dist/domain/errors.types.d.ts +1 -1
- package/dist/domain/errors.types.js.map +1 -1
- package/dist/domain/glob.d.ts +2 -0
- package/dist/domain/glob.js +25 -0
- package/dist/domain/glob.js.map +1 -0
- package/dist/domain/glob.types.d.ts +1 -0
- package/dist/domain/glob.types.js +2 -0
- package/dist/domain/glob.types.js.map +1 -0
- package/dist/domain/harness.constants.d.ts +11 -0
- package/dist/domain/harness.constants.js +24 -0
- package/dist/domain/harness.constants.js.map +1 -0
- package/dist/domain/harness.d.ts +2 -0
- package/dist/domain/harness.js +89 -0
- package/dist/domain/harness.js.map +1 -0
- package/dist/domain/harness.types.d.ts +60 -0
- package/dist/domain/harness.types.js +2 -0
- package/dist/domain/harness.types.js.map +1 -0
- package/dist/domain/hook.constants.d.ts +3 -0
- package/dist/domain/hook.constants.js +10 -0
- package/dist/domain/hook.constants.js.map +1 -0
- package/dist/domain/hook.d.ts +3 -0
- package/dist/domain/hook.js +25 -0
- package/dist/domain/hook.js.map +1 -0
- package/dist/domain/hook.types.d.ts +66 -0
- package/dist/domain/hook.types.js +2 -0
- package/dist/domain/hook.types.js.map +1 -0
- package/dist/domain/instructions.d.ts +3 -0
- package/dist/domain/instructions.js +25 -0
- package/dist/domain/instructions.js.map +1 -0
- package/dist/domain/model-messages.d.ts +5 -0
- package/dist/domain/model-messages.js +81 -0
- package/dist/domain/model-messages.js.map +1 -0
- package/dist/domain/model-messages.types.d.ts +6 -0
- package/dist/domain/model-messages.types.js +2 -0
- package/dist/domain/model-messages.types.js.map +1 -0
- package/dist/domain/model.constants.d.ts +4 -0
- package/dist/domain/model.constants.js +16 -0
- package/dist/domain/model.constants.js.map +1 -0
- package/dist/domain/model.types.d.ts +59 -2
- package/dist/domain/model.types.js.map +1 -1
- package/dist/domain/permissions.d.ts +3 -0
- package/dist/domain/permissions.js +92 -0
- package/dist/domain/permissions.js.map +1 -0
- package/dist/domain/permissions.types.d.ts +34 -0
- package/dist/domain/permissions.types.js +2 -0
- package/dist/domain/permissions.types.js.map +1 -0
- package/dist/domain/response.js +3 -2
- package/dist/domain/response.js.map +1 -1
- package/dist/domain/response.types.d.ts +12 -0
- package/dist/domain/response.types.js.map +1 -1
- package/dist/domain/skill.constants.d.ts +2 -0
- package/dist/domain/skill.constants.js +8 -0
- package/dist/domain/skill.constants.js.map +1 -0
- package/dist/domain/skill.d.ts +8 -0
- package/dist/domain/skill.js +79 -0
- package/dist/domain/skill.js.map +1 -0
- package/dist/domain/skill.types.d.ts +18 -0
- package/dist/domain/skill.types.js +2 -0
- package/dist/domain/skill.types.js.map +1 -0
- package/dist/domain/standard-schema.d.ts +6 -0
- package/dist/domain/standard-schema.js +45 -0
- package/dist/domain/standard-schema.js.map +1 -0
- package/dist/domain/tool-schema.d.ts +3 -0
- package/dist/domain/tool-schema.js +109 -0
- package/dist/domain/tool-schema.js.map +1 -0
- package/dist/domain/tool.constants.d.ts +4 -0
- package/dist/domain/tool.constants.js +36 -0
- package/dist/domain/tool.constants.js.map +1 -0
- package/dist/domain/tool.d.ts +4 -0
- package/dist/domain/tool.js +66 -0
- package/dist/domain/tool.js.map +1 -0
- package/dist/domain/tool.types.d.ts +62 -0
- package/dist/domain/tool.types.js +2 -0
- package/dist/domain/tool.types.js.map +1 -0
- package/dist/domain/transcript.d.ts +4 -0
- package/dist/domain/transcript.js +48 -0
- package/dist/domain/transcript.js.map +1 -0
- package/dist/domain/transcript.types.d.ts +15 -0
- package/dist/domain/transcript.types.js +2 -0
- package/dist/domain/transcript.types.js.map +1 -0
- package/dist/domain/workflow/workflow-state.js +13 -6
- package/dist/domain/workflow/workflow-state.js.map +1 -1
- package/dist/domain/workflow.d.ts +1 -1
- package/dist/domain/workflow.js.map +1 -1
- package/dist/domain/workflow.types.d.ts +4 -0
- package/dist/domain/workflow.types.js.map +1 -1
- package/dist/index.d.ts +34 -8
- package/dist/index.js +19 -4
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/conversations/harness-store.d.ts +3 -0
- package/dist/infrastructure/conversations/harness-store.js +27 -0
- package/dist/infrastructure/conversations/harness-store.js.map +1 -0
- package/dist/infrastructure/conversations/harness-transcript.d.ts +2 -0
- package/dist/infrastructure/conversations/harness-transcript.js +50 -0
- package/dist/infrastructure/conversations/harness-transcript.js.map +1 -0
- package/dist/infrastructure/conversations/harness-transcript.types.d.ts +18 -0
- package/dist/infrastructure/conversations/harness-transcript.types.js +2 -0
- package/dist/infrastructure/conversations/harness-transcript.types.js.map +1 -0
- package/dist/infrastructure/conversations.d.ts +4 -1
- package/dist/infrastructure/conversations.js +3 -0
- package/dist/infrastructure/conversations.js.map +1 -1
- package/dist/infrastructure/conversations.types.d.ts +1 -0
- package/dist/infrastructure/conversations.types.js.map +1 -1
- package/dist/infrastructure/custom-reporter.d.ts +2 -0
- package/dist/infrastructure/custom-reporter.js +33 -0
- package/dist/infrastructure/custom-reporter.js.map +1 -0
- package/dist/infrastructure/custom-reporter.types.d.ts +13 -0
- package/dist/infrastructure/custom-reporter.types.js +2 -0
- package/dist/infrastructure/custom-reporter.types.js.map +1 -0
- 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/journal.constants.d.ts +1 -0
- package/dist/infrastructure/journal.constants.js +2 -0
- package/dist/infrastructure/journal.constants.js.map +1 -0
- package/dist/infrastructure/journal.js +4 -1
- package/dist/infrastructure/journal.js.map +1 -1
- package/dist/infrastructure/opentelemetry-dispatch.d.ts +6 -0
- package/dist/infrastructure/opentelemetry-dispatch.js +70 -0
- package/dist/infrastructure/opentelemetry-dispatch.js.map +1 -0
- package/dist/infrastructure/opentelemetry.constants.d.ts +3 -0
- package/dist/infrastructure/opentelemetry.constants.js +3 -0
- package/dist/infrastructure/opentelemetry.constants.js.map +1 -1
- package/dist/infrastructure/opentelemetry.js +4 -0
- package/dist/infrastructure/opentelemetry.js.map +1 -1
- package/dist/infrastructure/opentelemetry.types.d.ts +3 -3
- package/dist/infrastructure/opentelemetry.types.js.map +1 -1
- package/dist/infrastructure/reporter.js +27 -2
- package/dist/infrastructure/reporter.js.map +1 -1
- package/dist/infrastructure/resource-activity-inspection.js +3 -2
- package/dist/infrastructure/resource-activity-inspection.js.map +1 -1
- package/dist/infrastructure/resource-activity.js +2 -2
- package/dist/infrastructure/resource-activity.js.map +1 -1
- package/dist/infrastructure/resource-activity.types.d.ts +2 -2
- package/dist/infrastructure/resource-activity.types.js.map +1 -1
- package/dist/infrastructure/settings.d.ts +1 -1
- package/dist/infrastructure/settings.js +3 -3
- package/dist/infrastructure/settings.js.map +1 -1
- package/dist/infrastructure/sse.d.ts +2 -0
- package/dist/infrastructure/sse.js +64 -0
- package/dist/infrastructure/sse.js.map +1 -0
- package/dist/infrastructure/sse.types.d.ts +4 -0
- package/dist/infrastructure/sse.types.js +2 -0
- package/dist/infrastructure/sse.types.js.map +1 -0
- package/dist/infrastructure/transport-conversations.d.ts +2 -2
- package/dist/infrastructure/transport-conversations.js +8 -1
- package/dist/infrastructure/transport-conversations.js.map +1 -1
- package/dist/infrastructure/transport-journal.js +2 -1
- package/dist/infrastructure/transport-journal.js.map +1 -1
- package/dist/providers/agents.d.ts +3 -3
- package/dist/providers/agents.js +3 -3
- package/dist/providers/agents.js.map +1 -1
- package/dist/providers/daytona.d.ts +1 -1
- package/dist/providers/daytona.js +1 -1
- package/dist/providers/daytona.js.map +1 -1
- package/dist/providers/docker.d.ts +1 -1
- package/dist/providers/docker.js +1 -1
- package/dist/providers/docker.js.map +1 -1
- package/dist/providers/factories.d.ts +2 -2
- package/dist/providers/factories.js +3 -3
- package/dist/providers/factories.js.map +1 -1
- package/dist/providers/firecracker.d.ts +1 -1
- package/dist/providers/firecracker.js +1 -1
- package/dist/providers/firecracker.js.map +1 -1
- package/dist/providers/local.d.ts +1 -1
- package/dist/providers/local.js +1 -1
- package/dist/providers/local.js.map +1 -1
- package/dist/providers/podman.d.ts +1 -1
- package/dist/providers/podman.js +1 -1
- package/dist/providers/podman.js.map +1 -1
- package/dist/providers/vercel.d.ts +1 -1
- package/dist/providers/vercel.js +1 -1
- package/dist/providers/vercel.js.map +1 -1
- package/package.json +1 -1
- package/dist/adapters/models/openai-compatible.constants.js.map +0 -1
- package/dist/adapters/models/openai-compatible.d.ts +0 -3
- package/dist/adapters/models/openai-compatible.js +0 -78
- package/dist/adapters/models/openai-compatible.js.map +0 -1
- package/dist/adapters/models/openai-compatible.types.d.ts +0 -14
- package/dist/adapters/models/openai-compatible.types.js +0 -2
- package/dist/adapters/models/openai-compatible.types.js.map +0 -1
- package/dist/adapters/models/openai-http.js.map +0 -1
- package/dist/adapters/models/openai-request.d.ts +0 -4
- package/dist/adapters/models/openai-request.js +0 -46
- package/dist/adapters/models/openai-request.js.map +0 -1
- package/dist/adapters/models/openai-response.d.ts +0 -3
- package/dist/adapters/models/openai-response.js +0 -65
- package/dist/adapters/models/openai-response.js.map +0 -1
- package/dist/cli/init-authentication.constants.js.map +0 -1
- /package/dist/{cli/init-authentication.constants.d.ts → adapters/agents/authentication.constants.d.ts} +0 -0
- /package/dist/adapters/models/{openai-http.d.ts → model-http.d.ts} +0 -0
- /package/dist/adapters/models/{openai-compatible.constants.d.ts → model.constants.d.ts} +0 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { AgentModel, ModelMessage, ModelResult, ModelToolCallBlock } from "./model.types.ts";
|
|
2
|
+
import type { SandboxLease } from "./sandbox.types.ts";
|
|
3
|
+
import type { ToolOutput } from "./tool.types.ts";
|
|
4
|
+
export type HarnessHookPhase = "session-start" | "before-model" | "after-model" | "before-tool" | "after-tool" | "stop";
|
|
5
|
+
export interface HarnessHookContext {
|
|
6
|
+
readonly sandbox: SandboxLease;
|
|
7
|
+
readonly signal: AbortSignal;
|
|
8
|
+
readonly model: AgentModel;
|
|
9
|
+
readonly step: number;
|
|
10
|
+
}
|
|
11
|
+
export interface HarnessToolResultView {
|
|
12
|
+
readonly content: string;
|
|
13
|
+
readonly isError: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface HarnessHookEvents {
|
|
16
|
+
readonly "session-start": {
|
|
17
|
+
readonly prompt: string;
|
|
18
|
+
};
|
|
19
|
+
readonly "before-model": {
|
|
20
|
+
readonly messages: readonly ModelMessage[];
|
|
21
|
+
};
|
|
22
|
+
readonly "after-model": {
|
|
23
|
+
readonly result: ModelResult;
|
|
24
|
+
};
|
|
25
|
+
readonly "before-tool": {
|
|
26
|
+
readonly call: ModelToolCallBlock;
|
|
27
|
+
};
|
|
28
|
+
readonly "after-tool": {
|
|
29
|
+
readonly call: ModelToolCallBlock;
|
|
30
|
+
readonly result: HarnessToolResultView;
|
|
31
|
+
};
|
|
32
|
+
readonly stop: {
|
|
33
|
+
readonly text: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export interface HarnessHookDecisions {
|
|
37
|
+
readonly "session-start": {
|
|
38
|
+
readonly instructions: string;
|
|
39
|
+
};
|
|
40
|
+
readonly "before-model": never;
|
|
41
|
+
readonly "after-model": never;
|
|
42
|
+
readonly "before-tool": {
|
|
43
|
+
readonly deny: string;
|
|
44
|
+
} | {
|
|
45
|
+
readonly input: unknown;
|
|
46
|
+
};
|
|
47
|
+
readonly "after-tool": {
|
|
48
|
+
readonly result: ToolOutput;
|
|
49
|
+
};
|
|
50
|
+
readonly stop: {
|
|
51
|
+
readonly continue: string;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export type HarnessHookInput<Phase extends HarnessHookPhase> = HarnessHookEvents[Phase] & HarnessHookContext;
|
|
55
|
+
export type HarnessHookResult<Phase extends HarnessHookPhase> = HarnessHookDecisions[Phase] | undefined | void;
|
|
56
|
+
export interface HarnessHookOptions<Phase extends HarnessHookPhase> {
|
|
57
|
+
readonly on: Phase;
|
|
58
|
+
readonly name?: string;
|
|
59
|
+
run(input: HarnessHookInput<Phase>): HarnessHookResult<Phase> | Promise<HarnessHookResult<Phase>>;
|
|
60
|
+
}
|
|
61
|
+
export interface HarnessHook<Phase extends HarnessHookPhase = HarnessHookPhase> {
|
|
62
|
+
readonly kind: "hook";
|
|
63
|
+
readonly on: Phase;
|
|
64
|
+
readonly name: string;
|
|
65
|
+
run(input: HarnessHookInput<Phase>): HarnessHookResult<Phase> | Promise<HarnessHookResult<Phase>>;
|
|
66
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.types.js","sourceRoot":"","sources":["../../src/domain/hook.types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n AgentModel,\n ModelMessage,\n ModelResult,\n ModelToolCallBlock,\n} from \"./model.types.ts\";\nimport type { SandboxLease } from \"./sandbox.types.ts\";\nimport type { ToolOutput } from \"./tool.types.ts\";\n\nexport type HarnessHookPhase =\n | \"session-start\"\n | \"before-model\"\n | \"after-model\"\n | \"before-tool\"\n | \"after-tool\"\n | \"stop\";\n\nexport interface HarnessHookContext {\n readonly sandbox: SandboxLease;\n readonly signal: AbortSignal;\n readonly model: AgentModel;\n readonly step: number;\n}\n\nexport interface HarnessToolResultView {\n readonly content: string;\n readonly isError: boolean;\n}\n\nexport interface HarnessHookEvents {\n readonly \"session-start\": { readonly prompt: string };\n readonly \"before-model\": { readonly messages: readonly ModelMessage[] };\n readonly \"after-model\": { readonly result: ModelResult };\n readonly \"before-tool\": { readonly call: ModelToolCallBlock };\n readonly \"after-tool\": {\n readonly call: ModelToolCallBlock;\n readonly result: HarnessToolResultView;\n };\n readonly stop: { readonly text: string };\n}\n\nexport interface HarnessHookDecisions {\n readonly \"session-start\": { readonly instructions: string };\n readonly \"before-model\": never;\n readonly \"after-model\": never;\n readonly \"before-tool\":\n { readonly deny: string } | { readonly input: unknown };\n readonly \"after-tool\": { readonly result: ToolOutput };\n readonly stop: { readonly continue: string };\n}\n\nexport type HarnessHookInput<Phase extends HarnessHookPhase> =\n HarnessHookEvents[Phase] & HarnessHookContext;\n\nexport type HarnessHookResult<Phase extends HarnessHookPhase> =\n HarnessHookDecisions[Phase] | undefined | void;\n\nexport interface HarnessHookOptions<Phase extends HarnessHookPhase> {\n readonly on: Phase;\n readonly name?: string;\n run(\n input: HarnessHookInput<Phase>,\n ): HarnessHookResult<Phase> | Promise<HarnessHookResult<Phase>>;\n}\n\nexport interface HarnessHook<\n Phase extends HarnessHookPhase = HarnessHookPhase,\n> {\n readonly kind: \"hook\";\n readonly on: Phase;\n readonly name: string;\n run(\n input: HarnessHookInput<Phase>,\n ): HarnessHookResult<Phase> | Promise<HarnessHookResult<Phase>>;\n}\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { HarnessInstructions, HarnessInstructionSource, HarnessInstructionsOption } from "./harness.types.ts";
|
|
2
|
+
export declare function defineHarnessInstructions(source: HarnessInstructionSource): HarnessInstructions;
|
|
3
|
+
export declare function harnessInstructions(option: HarnessInstructionsOption | undefined): readonly HarnessInstructions[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { invariant } from "./errors.js";
|
|
2
|
+
export function defineHarnessInstructions(source) {
|
|
3
|
+
invariant(typeof source === "function" ||
|
|
4
|
+
(typeof source === "string" && source.trim()), "Instructions must be nonempty text or a function");
|
|
5
|
+
return Object.freeze({
|
|
6
|
+
kind: "instructions",
|
|
7
|
+
async resolve(context) {
|
|
8
|
+
const text = typeof source === "string" ? source : await source(context);
|
|
9
|
+
invariant(typeof text === "string", "Instructions must resolve to text");
|
|
10
|
+
return text;
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export function harnessInstructions(option) {
|
|
15
|
+
if (option === undefined)
|
|
16
|
+
return [];
|
|
17
|
+
const entries = Array.isArray(option) ? option : [option];
|
|
18
|
+
return Object.freeze(entries.map((entry) => {
|
|
19
|
+
if (typeof entry === "string")
|
|
20
|
+
return defineHarnessInstructions(entry);
|
|
21
|
+
invariant(entry?.kind === "instructions", "Declare instructions as text or with defineHarnessInstructions");
|
|
22
|
+
return entry;
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=instructions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instructions.js","sourceRoot":"","sources":["../../src/domain/instructions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAQxC,MAAM,UAAU,yBAAyB,CACvC,MAAgC;IAEhC,SAAS,CACP,OAAO,MAAM,KAAK,UAAU;QAC1B,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,EAC/C,kDAAkD,CACnD,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,cAAc;QACpB,KAAK,CAAC,OAAO,CAAC,OAAkC;YAC9C,MAAM,IAAI,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;YACzE,SAAS,CAAC,OAAO,IAAI,KAAK,QAAQ,EAAE,mCAAmC,CAAC,CAAC;YACzE,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,MAA6C;IAE7C,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC1D,OAAO,MAAM,CAAC,MAAM,CAClB,OAAO,CAAC,GAAG,CAAC,CAAC,KAAmC,EAAE,EAAE;QAClD,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,yBAAyB,CAAC,KAAK,CAAC,CAAC;QACvE,SAAS,CACP,KAAK,EAAE,IAAI,KAAK,cAAc,EAC9B,gEAAgE,CACjE,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CACH,CAAC;AACJ,CAAC","sourcesContent":["import { invariant } from \"./errors.ts\";\nimport type {\n HarnessInstructionContext,\n HarnessInstructions,\n HarnessInstructionSource,\n HarnessInstructionsOption,\n} from \"./harness.types.ts\";\n\nexport function defineHarnessInstructions(\n source: HarnessInstructionSource,\n): HarnessInstructions {\n invariant(\n typeof source === \"function\" ||\n (typeof source === \"string\" && source.trim()),\n \"Instructions must be nonempty text or a function\",\n );\n return Object.freeze({\n kind: \"instructions\",\n async resolve(context: HarnessInstructionContext) {\n const text = typeof source === \"string\" ? source : await source(context);\n invariant(typeof text === \"string\", \"Instructions must resolve to text\");\n return text;\n },\n });\n}\n\nexport function harnessInstructions(\n option: HarnessInstructionsOption | undefined,\n): readonly HarnessInstructions[] {\n if (option === undefined) return [];\n const entries = Array.isArray(option) ? option : [option];\n return Object.freeze(\n entries.map((entry: string | HarnessInstructions) => {\n if (typeof entry === \"string\") return defineHarnessInstructions(entry);\n invariant(\n entry?.kind === \"instructions\",\n \"Declare instructions as text or with defineHarnessInstructions\",\n );\n return entry;\n }),\n );\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ModelContentBlock, ModelMessage, ModelRequest, ModelToolSpec } from "./model.types.ts";
|
|
2
|
+
export declare function requestMessages(request: ModelRequest): readonly ModelMessage[];
|
|
3
|
+
export declare function validateMessages(messages: readonly ModelMessage[]): void;
|
|
4
|
+
export declare function validateTools(tools: readonly ModelToolSpec[]): void;
|
|
5
|
+
export declare function replayable(block: ModelContentBlock, identity: string, model: string): boolean;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { invariant } from "./errors.js";
|
|
2
|
+
import { TOOL_NAME_PATTERN } from "./model.constants.js";
|
|
3
|
+
const text = (value) => typeof value === "string";
|
|
4
|
+
const identifier = (value) => typeof value === "string" && value.trim() !== "";
|
|
5
|
+
const blockRules = {
|
|
6
|
+
text: { role: "any", valid: (block) => text(block.text) },
|
|
7
|
+
"tool-call": {
|
|
8
|
+
role: "assistant",
|
|
9
|
+
valid: (block) => identifier(block.id) &&
|
|
10
|
+
typeof block.name === "string" &&
|
|
11
|
+
TOOL_NAME_PATTERN.test(block.name),
|
|
12
|
+
},
|
|
13
|
+
"tool-result": {
|
|
14
|
+
role: "user",
|
|
15
|
+
valid: (block) => identifier(block.callId) &&
|
|
16
|
+
text(block.content) &&
|
|
17
|
+
(block.isError === undefined || typeof block.isError === "boolean"),
|
|
18
|
+
},
|
|
19
|
+
reasoning: {
|
|
20
|
+
role: "assistant",
|
|
21
|
+
valid: (block) => identifier(block.provider) && identifier(block.model),
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
export function requestMessages(request) {
|
|
25
|
+
invariant((request.prompt === undefined) !== (request.messages === undefined), "Model request requires exactly one of prompt or messages");
|
|
26
|
+
if (request.messages !== undefined) {
|
|
27
|
+
validateMessages(request.messages);
|
|
28
|
+
return request.messages;
|
|
29
|
+
}
|
|
30
|
+
invariant(typeof request.prompt === "string" && request.prompt.trim(), "Model prompt must be nonempty text");
|
|
31
|
+
return [{ role: "user", content: [{ type: "text", text: request.prompt }] }];
|
|
32
|
+
}
|
|
33
|
+
export function validateMessages(messages) {
|
|
34
|
+
invariant(Array.isArray(messages) && messages.length > 0, "Model messages must be a nonempty array");
|
|
35
|
+
let pending = new Set();
|
|
36
|
+
for (const message of messages) {
|
|
37
|
+
invariant(message !== null &&
|
|
38
|
+
typeof message === "object" &&
|
|
39
|
+
(message.role === "user" || message.role === "assistant") &&
|
|
40
|
+
Array.isArray(message.content) &&
|
|
41
|
+
message.content.length > 0, "Model messages need a user or assistant role and content blocks");
|
|
42
|
+
const content = message.content;
|
|
43
|
+
for (const block of content)
|
|
44
|
+
validateBlock(block, message.role);
|
|
45
|
+
const results = content.flatMap((block) => block.type === "tool-result" ? [block.callId] : []);
|
|
46
|
+
invariant(results.length === pending.size &&
|
|
47
|
+
results.every((id) => pending.has(id)) &&
|
|
48
|
+
new Set(results).size === results.length, "Each tool call needs exactly one result in the next user message");
|
|
49
|
+
pending = new Set(content.flatMap((block) => block.type === "tool-call" ? [block.id] : []));
|
|
50
|
+
}
|
|
51
|
+
invariant(messages[0].role === "user" && messages.at(-1).role === "user", "Model messages must start and end with a user message");
|
|
52
|
+
}
|
|
53
|
+
export function validateTools(tools) {
|
|
54
|
+
invariant(Array.isArray(tools), "Model tools must be an array");
|
|
55
|
+
const names = new Set();
|
|
56
|
+
for (const tool of tools) {
|
|
57
|
+
invariant(tool !== null &&
|
|
58
|
+
typeof tool === "object" &&
|
|
59
|
+
typeof tool.name === "string" &&
|
|
60
|
+
TOOL_NAME_PATTERN.test(tool.name) &&
|
|
61
|
+
!names.has(tool.name), "Model tools need unique names of letters, digits, underscores or hyphens");
|
|
62
|
+
names.add(tool.name);
|
|
63
|
+
invariant(typeof tool.description === "string" &&
|
|
64
|
+
tool.inputSchema !== null &&
|
|
65
|
+
typeof tool.inputSchema === "object" &&
|
|
66
|
+
!Array.isArray(tool.inputSchema), "Model tools need a description and a JSON Schema object");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export function replayable(block, identity, model) {
|
|
70
|
+
return (block.type !== "reasoning" ||
|
|
71
|
+
(block.provider === identity && block.model === model));
|
|
72
|
+
}
|
|
73
|
+
function validateBlock(block, role) {
|
|
74
|
+
invariant(block !== null &&
|
|
75
|
+
typeof block === "object" &&
|
|
76
|
+
Object.hasOwn(blockRules, block.type), "Unsupported model content block");
|
|
77
|
+
const rule = blockRules[block.type];
|
|
78
|
+
invariant((rule.role === "any" || rule.role === role) &&
|
|
79
|
+
rule.valid(block), `Invalid ${block.type} block in a ${role} message`);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=model-messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-messages.js","sourceRoot":"","sources":["../../src/domain/model-messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { invariant } from \"./errors.ts\";\nimport { TOOL_NAME_PATTERN } from \"./model.constants.ts\";\nimport type { BlockRules } from \"./model-messages.types.ts\";\nimport type {\n ModelContentBlock,\n ModelMessage,\n ModelRequest,\n ModelToolSpec,\n} from \"./model.types.ts\";\n\nconst text = (value: unknown) => typeof value === \"string\";\nconst identifier = (value: unknown) =>\n typeof value === \"string\" && value.trim() !== \"\";\n\nconst blockRules: BlockRules = {\n text: { role: \"any\", valid: (block) => text(block.text) },\n \"tool-call\": {\n role: \"assistant\",\n valid: (block) =>\n identifier(block.id) &&\n typeof block.name === \"string\" &&\n TOOL_NAME_PATTERN.test(block.name),\n },\n \"tool-result\": {\n role: \"user\",\n valid: (block) =>\n identifier(block.callId) &&\n text(block.content) &&\n (block.isError === undefined || typeof block.isError === \"boolean\"),\n },\n reasoning: {\n role: \"assistant\",\n valid: (block) => identifier(block.provider) && identifier(block.model),\n },\n};\n\nexport function requestMessages(\n request: ModelRequest,\n): readonly ModelMessage[] {\n invariant(\n (request.prompt === undefined) !== (request.messages === undefined),\n \"Model request requires exactly one of prompt or messages\",\n );\n if (request.messages !== undefined) {\n validateMessages(request.messages);\n return request.messages;\n }\n invariant(\n typeof request.prompt === \"string\" && request.prompt.trim(),\n \"Model prompt must be nonempty text\",\n );\n return [{ role: \"user\", content: [{ type: \"text\", text: request.prompt }] }];\n}\n\nexport function validateMessages(messages: readonly ModelMessage[]): void {\n invariant(\n Array.isArray(messages) && messages.length > 0,\n \"Model messages must be a nonempty array\",\n );\n let pending = new Set<string>();\n for (const message of messages) {\n invariant(\n message !== null &&\n typeof message === \"object\" &&\n (message.role === \"user\" || message.role === \"assistant\") &&\n Array.isArray(message.content) &&\n message.content.length > 0,\n \"Model messages need a user or assistant role and content blocks\",\n );\n const content: readonly ModelContentBlock[] = message.content;\n for (const block of content) validateBlock(block, message.role);\n const results = content.flatMap((block) =>\n block.type === \"tool-result\" ? [block.callId] : [],\n );\n invariant(\n results.length === pending.size &&\n results.every((id) => pending.has(id)) &&\n new Set(results).size === results.length,\n \"Each tool call needs exactly one result in the next user message\",\n );\n pending = new Set(\n content.flatMap((block) =>\n block.type === \"tool-call\" ? [block.id] : [],\n ),\n );\n }\n invariant(\n messages[0]!.role === \"user\" && messages.at(-1)!.role === \"user\",\n \"Model messages must start and end with a user message\",\n );\n}\n\nexport function validateTools(tools: readonly ModelToolSpec[]): void {\n invariant(Array.isArray(tools), \"Model tools must be an array\");\n const names = new Set<string>();\n for (const tool of tools) {\n invariant(\n tool !== null &&\n typeof tool === \"object\" &&\n typeof tool.name === \"string\" &&\n TOOL_NAME_PATTERN.test(tool.name) &&\n !names.has(tool.name),\n \"Model tools need unique names of letters, digits, underscores or hyphens\",\n );\n names.add(tool.name);\n invariant(\n typeof tool.description === \"string\" &&\n tool.inputSchema !== null &&\n typeof tool.inputSchema === \"object\" &&\n !Array.isArray(tool.inputSchema),\n \"Model tools need a description and a JSON Schema object\",\n );\n }\n}\n\nexport function replayable(\n block: ModelContentBlock,\n identity: string,\n model: string,\n): boolean {\n return (\n block.type !== \"reasoning\" ||\n (block.provider === identity && block.model === model)\n );\n}\n\nfunction validateBlock(block: ModelContentBlock, role: ModelMessage[\"role\"]) {\n invariant(\n block !== null &&\n typeof block === \"object\" &&\n Object.hasOwn(blockRules, block.type),\n \"Unsupported model content block\",\n );\n const rule = blockRules[block.type];\n invariant(\n (rule.role === \"any\" || rule.role === role) &&\n rule.valid(block as unknown as Record<string, unknown>),\n `Invalid ${block.type} block in a ${role} message`,\n );\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ModelContentBlock, ModelMessage } from "./model.types.ts";
|
|
2
|
+
export interface BlockRule {
|
|
3
|
+
readonly role: ModelMessage["role"] | "any";
|
|
4
|
+
valid(block: Readonly<Record<string, unknown>>): boolean;
|
|
5
|
+
}
|
|
6
|
+
export type BlockRules = Readonly<Record<ModelContentBlock["type"], BlockRule>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-messages.types.js","sourceRoot":"","sources":["../../src/domain/model-messages.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ModelContentBlock, ModelMessage } from \"./model.types.ts\";\n\nexport interface BlockRule {\n readonly role: ModelMessage[\"role\"] | \"any\";\n valid(block: Readonly<Record<string, unknown>>): boolean;\n}\n\nexport type BlockRules = Readonly<Record<ModelContentBlock[\"type\"], BlockRule>>;\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const MODEL_REASONING = new Set([
|
|
2
|
+
"none",
|
|
3
|
+
"minimal",
|
|
4
|
+
"low",
|
|
5
|
+
"medium",
|
|
6
|
+
"high",
|
|
7
|
+
"xhigh",
|
|
8
|
+
"max",
|
|
9
|
+
]);
|
|
10
|
+
export const AGENT_MODEL_FIELDS = new Set([
|
|
11
|
+
"name",
|
|
12
|
+
"reasoning",
|
|
13
|
+
"maxOutputTokens",
|
|
14
|
+
]);
|
|
15
|
+
export const TOOL_NAME_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
16
|
+
//# sourceMappingURL=model.constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.constants.js","sourceRoot":"","sources":["../../src/domain/model.constants.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAgC,IAAI,GAAG,CAAC;IAClE,MAAM;IACN,SAAS;IACT,KAAK;IACL,QAAQ;IACR,MAAM;IACN,OAAO;IACP,KAAK;CACN,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAwB,IAAI,GAAG,CAAC;IAC7D,MAAM;IACN,WAAW;IACX,iBAAiB;CAClB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,uBAAuB,CAAC","sourcesContent":["import type { ModelReasoning } from \"./model.types.ts\";\n\nexport const MODEL_REASONING: ReadonlySet<ModelReasoning> = new Set([\n \"none\",\n \"minimal\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n]);\n\nexport const AGENT_MODEL_FIELDS: ReadonlySet<string> = new Set([\n \"name\",\n \"reasoning\",\n \"maxOutputTokens\",\n]);\n\nexport const TOOL_NAME_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;\n"]}
|
|
@@ -1,15 +1,72 @@
|
|
|
1
1
|
import type { Usage } from "./agent.types.ts";
|
|
2
|
+
export type ModelReasoning = "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
|
|
3
|
+
export interface AgentModel {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly reasoning?: ModelReasoning;
|
|
6
|
+
readonly maxOutputTokens?: number;
|
|
7
|
+
}
|
|
8
|
+
export type ModelSpec = string | AgentModel;
|
|
9
|
+
export interface ModelTextBlock {
|
|
10
|
+
readonly type: "text";
|
|
11
|
+
readonly text: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ModelToolCallBlock {
|
|
14
|
+
readonly type: "tool-call";
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly name: string;
|
|
17
|
+
readonly input: unknown;
|
|
18
|
+
}
|
|
19
|
+
export interface ModelToolResultBlock {
|
|
20
|
+
readonly type: "tool-result";
|
|
21
|
+
readonly callId: string;
|
|
22
|
+
readonly content: string;
|
|
23
|
+
readonly isError?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface ModelReasoningBlock {
|
|
26
|
+
readonly type: "reasoning";
|
|
27
|
+
readonly provider: string;
|
|
28
|
+
readonly model: string;
|
|
29
|
+
readonly data: unknown;
|
|
30
|
+
}
|
|
31
|
+
export type ModelContentBlock = ModelTextBlock | ModelToolCallBlock | ModelToolResultBlock | ModelReasoningBlock;
|
|
32
|
+
export interface ModelMessage {
|
|
33
|
+
readonly role: "user" | "assistant";
|
|
34
|
+
readonly content: readonly ModelContentBlock[];
|
|
35
|
+
}
|
|
36
|
+
export interface ModelToolSpec {
|
|
37
|
+
readonly name: string;
|
|
38
|
+
readonly description: string;
|
|
39
|
+
readonly inputSchema: Readonly<Record<string, unknown>>;
|
|
40
|
+
}
|
|
41
|
+
export type ModelStopReason = "end" | "tool-calls" | "max-tokens" | "refusal";
|
|
2
42
|
export interface ModelRequest {
|
|
3
|
-
readonly
|
|
43
|
+
readonly model: string;
|
|
44
|
+
readonly prompt?: string;
|
|
45
|
+
readonly messages?: readonly ModelMessage[];
|
|
4
46
|
readonly system?: string;
|
|
47
|
+
readonly tools?: readonly ModelToolSpec[];
|
|
5
48
|
readonly maxOutputTokens?: number;
|
|
49
|
+
readonly reasoning?: ModelReasoning;
|
|
50
|
+
readonly cache?: boolean;
|
|
6
51
|
readonly signal?: AbortSignal;
|
|
7
52
|
}
|
|
8
53
|
export interface ModelResult {
|
|
9
54
|
readonly text: string;
|
|
55
|
+
readonly content?: readonly ModelContentBlock[];
|
|
56
|
+
readonly stopReason?: ModelStopReason;
|
|
10
57
|
readonly usage?: Usage;
|
|
11
58
|
}
|
|
59
|
+
export type ModelStreamEvent = {
|
|
60
|
+
readonly type: "text-delta";
|
|
61
|
+
readonly text: string;
|
|
62
|
+
} | {
|
|
63
|
+
readonly type: "result";
|
|
64
|
+
readonly result: ModelResult;
|
|
65
|
+
};
|
|
12
66
|
export interface ModelProvider {
|
|
13
67
|
readonly name: string;
|
|
14
|
-
|
|
68
|
+
readonly identity?: string;
|
|
69
|
+
validate?(model: AgentModel): void;
|
|
70
|
+
request(request: ModelRequest): Promise<ModelResult>;
|
|
71
|
+
stream?(request: ModelRequest): AsyncIterable<ModelStreamEvent>;
|
|
15
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.types.js","sourceRoot":"","sources":["../../src/domain/model.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Usage } from \"./agent.types.ts\";\n\nexport interface ModelRequest {\n readonly
|
|
1
|
+
{"version":3,"file":"model.types.js","sourceRoot":"","sources":["../../src/domain/model.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Usage } from \"./agent.types.ts\";\n\nexport type ModelReasoning =\n \"none\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | \"max\";\n\nexport interface AgentModel {\n readonly name: string;\n readonly reasoning?: ModelReasoning;\n readonly maxOutputTokens?: number;\n}\n\nexport type ModelSpec = string | AgentModel;\n\nexport interface ModelTextBlock {\n readonly type: \"text\";\n readonly text: string;\n}\n\nexport interface ModelToolCallBlock {\n readonly type: \"tool-call\";\n readonly id: string;\n readonly name: string;\n readonly input: unknown;\n}\n\nexport interface ModelToolResultBlock {\n readonly type: \"tool-result\";\n readonly callId: string;\n readonly content: string;\n readonly isError?: boolean;\n}\n\nexport interface ModelReasoningBlock {\n readonly type: \"reasoning\";\n readonly provider: string;\n readonly model: string;\n readonly data: unknown;\n}\n\nexport type ModelContentBlock =\n | ModelTextBlock\n | ModelToolCallBlock\n | ModelToolResultBlock\n | ModelReasoningBlock;\n\nexport interface ModelMessage {\n readonly role: \"user\" | \"assistant\";\n readonly content: readonly ModelContentBlock[];\n}\n\nexport interface ModelToolSpec {\n readonly name: string;\n readonly description: string;\n readonly inputSchema: Readonly<Record<string, unknown>>;\n}\n\nexport type ModelStopReason = \"end\" | \"tool-calls\" | \"max-tokens\" | \"refusal\";\n\nexport interface ModelRequest {\n readonly model: string;\n readonly prompt?: string;\n readonly messages?: readonly ModelMessage[];\n readonly system?: string;\n readonly tools?: readonly ModelToolSpec[];\n readonly maxOutputTokens?: number;\n readonly reasoning?: ModelReasoning;\n readonly cache?: boolean;\n readonly signal?: AbortSignal;\n}\n\nexport interface ModelResult {\n readonly text: string;\n readonly content?: readonly ModelContentBlock[];\n readonly stopReason?: ModelStopReason;\n readonly usage?: Usage;\n}\n\nexport type ModelStreamEvent =\n | { readonly type: \"text-delta\"; readonly text: string }\n | { readonly type: \"result\"; readonly result: ModelResult };\n\nexport interface ModelProvider {\n readonly name: string;\n readonly identity?: string;\n validate?(model: AgentModel): void;\n request(request: ModelRequest): Promise<ModelResult>;\n stream?(request: ModelRequest): AsyncIterable<ModelStreamEvent>;\n}\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { HarnessPermissions, HarnessPermissionsOptions } from "./permissions.types.ts";
|
|
2
|
+
export declare function defineHarnessPermissions(options: HarnessPermissionsOptions): HarnessPermissions;
|
|
3
|
+
export declare function normalizeResourcePath(path: string): string | undefined;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { invariant } from "./errors.js";
|
|
2
|
+
import { glob } from "./glob.js";
|
|
3
|
+
const RULE_FIELDS = new Set(["effect", "tools", "paths", "commands", "reason"]);
|
|
4
|
+
const allowed = Object.freeze({ allowed: true });
|
|
5
|
+
export function defineHarnessPermissions(options) {
|
|
6
|
+
invariant(options !== null &&
|
|
7
|
+
typeof options === "object" &&
|
|
8
|
+
Array.isArray(options.rules), "Permissions require a rules array");
|
|
9
|
+
const fallback = options.default ?? "allow";
|
|
10
|
+
invariant(fallback === "allow" || fallback === "deny", 'Permission default must be "allow" or "deny"');
|
|
11
|
+
const compiled = options.rules.map(compileRule);
|
|
12
|
+
return Object.freeze({
|
|
13
|
+
kind: "permissions",
|
|
14
|
+
rules: Object.freeze(compiled.map(({ rule }) => rule)),
|
|
15
|
+
default: fallback,
|
|
16
|
+
evaluate(tool, resources) {
|
|
17
|
+
const index = compiled.findIndex((entry) => applies(entry, tool, resources));
|
|
18
|
+
const rule = compiled[index]?.rule;
|
|
19
|
+
if (rule?.effect === "allow")
|
|
20
|
+
return allowed;
|
|
21
|
+
if (rule)
|
|
22
|
+
return {
|
|
23
|
+
allowed: false,
|
|
24
|
+
reason: rule.reason ?? `Denied by permission rule ${index + 1}`,
|
|
25
|
+
};
|
|
26
|
+
if (fallback === "allow")
|
|
27
|
+
return allowed;
|
|
28
|
+
return { allowed: false, reason: "Denied by default permissions" };
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export function normalizeResourcePath(path) {
|
|
33
|
+
const segments = [];
|
|
34
|
+
const posix = path.replaceAll("\\", "/");
|
|
35
|
+
if (posix.startsWith("/") || /^[A-Za-z]:\//.test(posix))
|
|
36
|
+
return undefined;
|
|
37
|
+
for (const segment of posix.split("/")) {
|
|
38
|
+
if (segment === "" || segment === ".")
|
|
39
|
+
continue;
|
|
40
|
+
if (segment !== "..") {
|
|
41
|
+
segments.push(segment);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (!segments.length)
|
|
45
|
+
return undefined;
|
|
46
|
+
segments.pop();
|
|
47
|
+
}
|
|
48
|
+
return segments.join("/");
|
|
49
|
+
}
|
|
50
|
+
function compileRule(rule) {
|
|
51
|
+
invariant(rule !== null &&
|
|
52
|
+
typeof rule === "object" &&
|
|
53
|
+
Object.keys(rule).every((key) => RULE_FIELDS.has(key)), "Permission rules accept effect, tools, paths, commands and reason");
|
|
54
|
+
invariant(rule.effect === "allow" || rule.effect === "deny", 'Permission effect must be "allow" or "deny"');
|
|
55
|
+
invariant(rule.reason === undefined ||
|
|
56
|
+
(typeof rule.reason === "string" && rule.reason.trim()), "Permission reason must be nonempty text");
|
|
57
|
+
return Object.freeze({
|
|
58
|
+
rule: Object.freeze({ ...rule }),
|
|
59
|
+
...patterns("tools", rule.tools, (value) => glob(value, "text")),
|
|
60
|
+
...patterns("paths", rule.paths, (value) => glob(value, "path")),
|
|
61
|
+
...patterns("commands", rule.commands, (value) => glob(value, "text")),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function patterns(key, values, compile) {
|
|
65
|
+
if (values === undefined)
|
|
66
|
+
return {};
|
|
67
|
+
invariant(Array.isArray(values) &&
|
|
68
|
+
values.length > 0 &&
|
|
69
|
+
values.every((value) => typeof value === "string" && value.trim()), `Permission ${key} must be a nonempty list of patterns`);
|
|
70
|
+
return { [key]: Object.freeze(values.map(compile)) };
|
|
71
|
+
}
|
|
72
|
+
function applies(entry, tool, resources) {
|
|
73
|
+
if (entry.tools && !entry.tools.some((pattern) => pattern.test(tool)))
|
|
74
|
+
return false;
|
|
75
|
+
if (entry.commands) {
|
|
76
|
+
const command = resources.command;
|
|
77
|
+
if (command === undefined)
|
|
78
|
+
return false;
|
|
79
|
+
if (!entry.commands.some((pattern) => pattern.test(command)))
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
if (!entry.paths)
|
|
83
|
+
return true;
|
|
84
|
+
const paths = (resources.paths ?? []).map(normalizeResourcePath);
|
|
85
|
+
if (!paths.length)
|
|
86
|
+
return false;
|
|
87
|
+
const matches = (path) => path !== undefined && entry.paths.some((pattern) => pattern.test(path));
|
|
88
|
+
return entry.rule.effect === "allow"
|
|
89
|
+
? paths.every(matches)
|
|
90
|
+
: paths.some(matches);
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/domain/permissions.ts"],"names":[],"mappings":"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","sourcesContent":["import { invariant } from \"./errors.ts\";\nimport { glob } from \"./glob.ts\";\nimport type {\n CompiledRule,\n HarnessPermissionRule,\n HarnessPermissions,\n HarnessPermissionsOptions,\n PermissionDecision,\n ToolResources,\n} from \"./permissions.types.ts\";\n\nconst RULE_FIELDS = new Set([\"effect\", \"tools\", \"paths\", \"commands\", \"reason\"]);\nconst allowed: PermissionDecision = Object.freeze({ allowed: true });\n\nexport function defineHarnessPermissions(\n options: HarnessPermissionsOptions,\n): HarnessPermissions {\n invariant(\n options !== null &&\n typeof options === \"object\" &&\n Array.isArray(options.rules),\n \"Permissions require a rules array\",\n );\n const fallback = options.default ?? \"allow\";\n invariant(\n fallback === \"allow\" || fallback === \"deny\",\n 'Permission default must be \"allow\" or \"deny\"',\n );\n const compiled = options.rules.map(compileRule);\n return Object.freeze({\n kind: \"permissions\",\n rules: Object.freeze(compiled.map(({ rule }) => rule)),\n default: fallback,\n evaluate(tool: string, resources: ToolResources): PermissionDecision {\n const index = compiled.findIndex((entry) =>\n applies(entry, tool, resources),\n );\n const rule = compiled[index]?.rule;\n if (rule?.effect === \"allow\") return allowed;\n if (rule)\n return {\n allowed: false,\n reason: rule.reason ?? `Denied by permission rule ${index + 1}`,\n };\n if (fallback === \"allow\") return allowed;\n return { allowed: false, reason: \"Denied by default permissions\" };\n },\n });\n}\n\nexport function normalizeResourcePath(path: string): string | undefined {\n const segments: string[] = [];\n const posix = path.replaceAll(\"\\\\\", \"/\");\n if (posix.startsWith(\"/\") || /^[A-Za-z]:\\//.test(posix)) return undefined;\n for (const segment of posix.split(\"/\")) {\n if (segment === \"\" || segment === \".\") continue;\n if (segment !== \"..\") {\n segments.push(segment);\n continue;\n }\n if (!segments.length) return undefined;\n segments.pop();\n }\n return segments.join(\"/\");\n}\n\nfunction compileRule(rule: HarnessPermissionRule): CompiledRule {\n invariant(\n rule !== null &&\n typeof rule === \"object\" &&\n Object.keys(rule).every((key) => RULE_FIELDS.has(key)),\n \"Permission rules accept effect, tools, paths, commands and reason\",\n );\n invariant(\n rule.effect === \"allow\" || rule.effect === \"deny\",\n 'Permission effect must be \"allow\" or \"deny\"',\n );\n invariant(\n rule.reason === undefined ||\n (typeof rule.reason === \"string\" && rule.reason.trim()),\n \"Permission reason must be nonempty text\",\n );\n return Object.freeze({\n rule: Object.freeze({ ...rule }),\n ...patterns(\"tools\", rule.tools, (value) => glob(value, \"text\")),\n ...patterns(\"paths\", rule.paths, (value) => glob(value, \"path\")),\n ...patterns(\"commands\", rule.commands, (value) => glob(value, \"text\")),\n });\n}\n\nfunction patterns(\n key: \"tools\" | \"paths\" | \"commands\",\n values: readonly string[] | undefined,\n compile: (value: string) => RegExp,\n) {\n if (values === undefined) return {};\n invariant(\n Array.isArray(values) &&\n values.length > 0 &&\n values.every((value) => typeof value === \"string\" && value.trim()),\n `Permission ${key} must be a nonempty list of patterns`,\n );\n return { [key]: Object.freeze(values.map(compile)) };\n}\n\nfunction applies(\n entry: CompiledRule,\n tool: string,\n resources: ToolResources,\n): boolean {\n if (entry.tools && !entry.tools.some((pattern) => pattern.test(tool)))\n return false;\n if (entry.commands) {\n const command = resources.command;\n if (command === undefined) return false;\n if (!entry.commands.some((pattern) => pattern.test(command))) return false;\n }\n if (!entry.paths) return true;\n const paths = (resources.paths ?? []).map(normalizeResourcePath);\n if (!paths.length) return false;\n const matches = (path: string | undefined) =>\n path !== undefined && entry.paths!.some((pattern) => pattern.test(path));\n return entry.rule.effect === \"allow\"\n ? paths.every(matches)\n : paths.some(matches);\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type PermissionEffect = "allow" | "deny";
|
|
2
|
+
export interface HarnessPermissionRule {
|
|
3
|
+
readonly effect: PermissionEffect;
|
|
4
|
+
readonly tools?: readonly string[];
|
|
5
|
+
readonly paths?: readonly string[];
|
|
6
|
+
readonly commands?: readonly string[];
|
|
7
|
+
readonly reason?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface HarnessPermissionsOptions {
|
|
10
|
+
readonly rules: readonly HarnessPermissionRule[];
|
|
11
|
+
readonly default?: PermissionEffect;
|
|
12
|
+
}
|
|
13
|
+
export interface ToolResources {
|
|
14
|
+
readonly paths?: readonly string[];
|
|
15
|
+
readonly command?: string;
|
|
16
|
+
}
|
|
17
|
+
export type PermissionDecision = {
|
|
18
|
+
readonly allowed: true;
|
|
19
|
+
} | {
|
|
20
|
+
readonly allowed: false;
|
|
21
|
+
readonly reason: string;
|
|
22
|
+
};
|
|
23
|
+
export interface HarnessPermissions {
|
|
24
|
+
readonly kind: "permissions";
|
|
25
|
+
readonly rules: readonly HarnessPermissionRule[];
|
|
26
|
+
readonly default: PermissionEffect;
|
|
27
|
+
evaluate(tool: string, resources: ToolResources): PermissionDecision;
|
|
28
|
+
}
|
|
29
|
+
export interface CompiledRule {
|
|
30
|
+
readonly rule: HarnessPermissionRule;
|
|
31
|
+
readonly tools?: readonly RegExp[];
|
|
32
|
+
readonly paths?: readonly RegExp[];
|
|
33
|
+
readonly commands?: readonly RegExp[];
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.types.js","sourceRoot":"","sources":["../../src/domain/permissions.types.ts"],"names":[],"mappings":"","sourcesContent":["export type PermissionEffect = \"allow\" | \"deny\";\n\nexport interface HarnessPermissionRule {\n readonly effect: PermissionEffect;\n readonly tools?: readonly string[];\n readonly paths?: readonly string[];\n readonly commands?: readonly string[];\n readonly reason?: string;\n}\n\nexport interface HarnessPermissionsOptions {\n readonly rules: readonly HarnessPermissionRule[];\n readonly default?: PermissionEffect;\n}\n\nexport interface ToolResources {\n readonly paths?: readonly string[];\n readonly command?: string;\n}\n\nexport type PermissionDecision =\n | { readonly allowed: true }\n | { readonly allowed: false; readonly reason: string };\n\nexport interface HarnessPermissions {\n readonly kind: \"permissions\";\n readonly rules: readonly HarnessPermissionRule[];\n readonly default: PermissionEffect;\n evaluate(tool: string, resources: ToolResources): PermissionDecision;\n}\n\nexport interface CompiledRule {\n readonly rule: HarnessPermissionRule;\n readonly tools?: readonly RegExp[];\n readonly paths?: readonly RegExp[];\n readonly commands?: readonly RegExp[];\n}\n"]}
|
package/dist/domain/response.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { OutpostError, invariant } from "./errors.js";
|
|
2
|
+
import { validateStandard } from "./standard-schema.js";
|
|
2
3
|
export class ResponseError extends OutpostError {
|
|
3
4
|
tag;
|
|
4
5
|
raw;
|
|
@@ -41,8 +42,8 @@ export const response = {
|
|
|
41
42
|
const input = JSON.parse(fenced ? fenced[1] : text);
|
|
42
43
|
if (typeof options.schema === "function")
|
|
43
44
|
return options.schema(input);
|
|
44
|
-
const result = await options.schema
|
|
45
|
-
if (result
|
|
45
|
+
const result = await validateStandard(options.schema, input);
|
|
46
|
+
if ("issues" in result)
|
|
46
47
|
throw new Error(JSON.stringify(result.issues));
|
|
47
48
|
return result.value;
|
|
48
49
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/domain/response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/domain/response.ts"],"names":[],"mappings":"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","sourcesContent":["import { OutpostError, invariant } from \"./errors.ts\";\nimport { validateStandard } from \"./standard-schema.ts\";\nimport type {\n JsonResponseOptions,\n ResponseSpec,\n TextResponseOptions,\n} from \"./response.types.ts\";\n\nexport type { ResponseSpec, StandardValidator } from \"./response.types.ts\";\n\nexport class ResponseError extends OutpostError {\n readonly tag: string;\n readonly raw: string | undefined;\n constructor(tag: string, message: string, raw?: string, cause?: unknown) {\n super(\"response\", message, { tag, raw }, cause);\n this.name = \"ResponseError\";\n this.tag = tag;\n this.raw = raw;\n }\n}\n\nfunction content(text: string, tag: string): string {\n const matches = [\n ...text.matchAll(new RegExp(`<${tag}>([\\\\s\\\\S]*?)</${tag}>`, \"g\")),\n ];\n if (!matches.length)\n throw new ResponseError(tag, `No complete <${tag}> response was found`);\n return matches.at(-1)![1]!.trim();\n}\n\nfunction spec<T>(\n tag: string,\n repairs: number,\n parse: (text: string) => Promise<T>,\n): ResponseSpec<T> {\n invariant(\n /^[A-Za-z][A-Za-z0-9_-]*$/.test(tag),\n \"Response tags must be XML-style identifiers\",\n );\n invariant(\n Number.isSafeInteger(repairs) && repairs >= 0,\n \"Response repairs must be a nonnegative integer\",\n );\n return Object.freeze({\n tag,\n repairs,\n async read(text: string) {\n const raw = content(text, tag);\n try {\n return await parse(raw);\n } catch (cause) {\n throw new ResponseError(\n tag,\n `Invalid <${tag}> response: ${cause instanceof Error ? cause.message : String(cause)}`,\n raw,\n cause,\n );\n }\n },\n });\n}\n\nexport const response = {\n text: (options: TextResponseOptions): ResponseSpec<string> =>\n spec(options.tag, options.repairs ?? 0, async (text) => text),\n json: <T>(options: JsonResponseOptions<T>): ResponseSpec<T> =>\n spec(options.tag, options.repairs ?? 0, async (text) => {\n const fenced = text.match(/^```(?:json)?\\s*\\r?\\n([\\s\\S]*?)\\r?\\n```$/i);\n const input: unknown = JSON.parse(fenced ? fenced[1]! : text);\n if (typeof options.schema === \"function\") return options.schema(input);\n const result = await validateStandard(options.schema, input);\n if (\"issues\" in result) throw new Error(JSON.stringify(result.issues));\n return result.value;\n }),\n};\n"]}
|
|
@@ -27,3 +27,15 @@ export type TextResponseOptions = {
|
|
|
27
27
|
tag: string;
|
|
28
28
|
repairs?: number;
|
|
29
29
|
};
|
|
30
|
+
export type StandardResult<T> = {
|
|
31
|
+
readonly value: T;
|
|
32
|
+
} | {
|
|
33
|
+
readonly issues: readonly unknown[];
|
|
34
|
+
};
|
|
35
|
+
export interface StandardIssue {
|
|
36
|
+
readonly message?: unknown;
|
|
37
|
+
readonly path?: readonly unknown[];
|
|
38
|
+
}
|
|
39
|
+
export interface StandardPathSegment {
|
|
40
|
+
readonly key?: unknown;
|
|
41
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response.types.js","sourceRoot":"","sources":["../../src/domain/response.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface StandardValidator<T> {\n readonly \"~standard\": {\n readonly validate: (\n input: unknown,\n ) =>\n | { readonly value: T; readonly issues?: undefined }\n | { readonly issues: readonly unknown[] }\n | Promise<\n | { readonly value: T; readonly issues?: undefined }\n | { readonly issues: readonly unknown[] }\n >;\n };\n}\n\nexport interface ResponseSpec<T> {\n readonly tag: string;\n readonly repairs: number;\n read(text: string): Promise<T>;\n}\n\nexport type JsonResponseOptions<T> = {\n tag: string;\n schema: StandardValidator<T> | ((input: unknown) => T | Promise<T>);\n repairs?: number;\n};\n\nexport type TextResponseOptions = { tag: string; repairs?: number };\n"]}
|
|
1
|
+
{"version":3,"file":"response.types.js","sourceRoot":"","sources":["../../src/domain/response.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface StandardValidator<T> {\n readonly \"~standard\": {\n readonly validate: (\n input: unknown,\n ) =>\n | { readonly value: T; readonly issues?: undefined }\n | { readonly issues: readonly unknown[] }\n | Promise<\n | { readonly value: T; readonly issues?: undefined }\n | { readonly issues: readonly unknown[] }\n >;\n };\n}\n\nexport interface ResponseSpec<T> {\n readonly tag: string;\n readonly repairs: number;\n read(text: string): Promise<T>;\n}\n\nexport type JsonResponseOptions<T> = {\n tag: string;\n schema: StandardValidator<T> | ((input: unknown) => T | Promise<T>);\n repairs?: number;\n};\n\nexport type TextResponseOptions = { tag: string; repairs?: number };\n\nexport type StandardResult<T> =\n { readonly value: T } | { readonly issues: readonly unknown[] };\n\nexport interface StandardIssue {\n readonly message?: unknown;\n readonly path?: readonly unknown[];\n}\n\nexport interface StandardPathSegment {\n readonly key?: unknown;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill.constants.js","sourceRoot":"","sources":["../../src/domain/skill.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,YAAY,CAAC;AAEzC,MAAM,CAAC,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC;IACvD,MAAM;IACN,aAAa;IACb,cAAc;IACd,OAAO;CACR,CAAC,CAAC","sourcesContent":["export const SKILL_LOADER = \"load_skill\";\n\nexport const SKILL_FIELDS: ReadonlySet<string> = new Set([\n \"name\",\n \"description\",\n \"instructions\",\n \"tools\",\n]);\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ModelMessage } from "./model.types.ts";
|
|
2
|
+
import type { HarnessSkill, HarnessSkillOptions } from "./skill.types.ts";
|
|
3
|
+
import type { HarnessTool } from "./tool.types.ts";
|
|
4
|
+
export declare function defineHarnessSkill(options: HarnessSkillOptions): HarnessSkill;
|
|
5
|
+
export declare function harnessSkills(skills: readonly HarnessSkill[] | undefined): readonly HarnessSkill[];
|
|
6
|
+
export declare function skillCatalog(skills: readonly HarnessSkill[]): string;
|
|
7
|
+
export declare function skillLoader(skills: readonly HarnessSkill[]): HarnessTool;
|
|
8
|
+
export declare function loadedSkills(messages: readonly ModelMessage[]): ReadonlySet<string>;
|