@entelligentsia/forgecli 1.0.36 → 1.0.40
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 +83 -0
- package/dist/CHANGELOG-forge-plugin.md +101 -0
- package/dist/CHANGELOG-pi.md +143 -0
- package/dist/bin/argv.d.ts +1 -1
- package/dist/bin/argv.js +12 -0
- package/dist/bin/argv.js.map +1 -1
- package/dist/bin/forge.js +18 -16
- package/dist/bin/forge.js.map +1 -1
- package/dist/bin/reset.d.ts +39 -0
- package/dist/bin/reset.js +101 -0
- package/dist/bin/reset.js.map +1 -0
- package/dist/extensions/forgecli/claude-bootstrap/bootstrap.js +56 -265
- package/dist/extensions/forgecli/claude-bootstrap/bootstrap.js.map +1 -1
- package/dist/extensions/forgecli/claude-bootstrap/uninstall.js +52 -32
- package/dist/extensions/forgecli/claude-bootstrap/uninstall.js.map +1 -1
- package/dist/extensions/forgecli/commands/reset.d.ts +16 -0
- package/dist/extensions/forgecli/commands/reset.js +83 -0
- package/dist/extensions/forgecli/commands/reset.js.map +1 -0
- package/dist/extensions/forgecli/forge-commands.d.ts +7 -2
- package/dist/extensions/forgecli/forge-commands.js +19 -5
- package/dist/extensions/forgecli/forge-commands.js.map +1 -1
- package/dist/extensions/forgecli/forge-subagent.d.ts +4 -4
- package/dist/extensions/forgecli/hooks/forge-permissions.js +20 -6
- package/dist/extensions/forgecli/hooks/forge-permissions.js.map +1 -1
- package/dist/extensions/forgecli/index.js +6 -3
- package/dist/extensions/forgecli/index.js.map +1 -1
- package/dist/extensions/forgecli/lib/forge-root.d.ts +6 -0
- package/dist/extensions/forgecli/lib/forge-root.js +52 -0
- package/dist/extensions/forgecli/lib/forge-root.js.map +1 -1
- package/dist/extensions/forgecli/lib/payload-manifest.d.ts +62 -0
- package/dist/extensions/forgecli/lib/payload-manifest.js +151 -0
- package/dist/extensions/forgecli/lib/payload-manifest.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/advisory-render.d.ts +9 -0
- package/dist/extensions/forgecli/orchestrators/advisory-render.js +107 -0
- package/dist/extensions/forgecli/orchestrators/advisory-render.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-phases.d.ts +3 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-phases.js +22 -0
- package/dist/extensions/forgecli/orchestrators/bug/bug-phases.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/bug/bug-verdict-loop.d.ts +1 -1
- package/dist/extensions/forgecli/orchestrators/bug/bug-verdict-loop.js +34 -2
- package/dist/extensions/forgecli/orchestrators/bug/bug-verdict-loop.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/bug/run-bug-pipeline.js +2 -2
- package/dist/extensions/forgecli/orchestrators/bug/run-bug-pipeline.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/common/recovery-menu.d.ts +24 -0
- package/dist/extensions/forgecli/orchestrators/common/recovery-menu.js +58 -0
- package/dist/extensions/forgecli/orchestrators/common/recovery-menu.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/common/reset-pipeline.d.ts +53 -0
- package/dist/extensions/forgecli/orchestrators/common/reset-pipeline.js +131 -0
- package/dist/extensions/forgecli/orchestrators/common/reset-pipeline.js.map +1 -0
- package/dist/extensions/forgecli/orchestrators/halt-advisor.js +25 -3
- package/dist/extensions/forgecli/orchestrators/halt-advisor.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/task/run-task-pipeline.js +3 -3
- package/dist/extensions/forgecli/orchestrators/task/run-task-pipeline.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/task/task-phases.d.ts +3 -0
- package/dist/extensions/forgecli/orchestrators/task/task-phases.js +22 -0
- package/dist/extensions/forgecli/orchestrators/task/task-phases.js.map +1 -1
- package/dist/extensions/forgecli/orchestrators/task/task-verdict-loop.d.ts +1 -1
- package/dist/extensions/forgecli/orchestrators/task/task-verdict-loop.js +37 -2
- package/dist/extensions/forgecli/orchestrators/task/task-verdict-loop.js.map +1 -1
- package/dist/extensions/forgecli/store/store-resolver.d.ts +15 -0
- package/dist/extensions/forgecli/store/store-resolver.js +118 -18
- package/dist/extensions/forgecli/store/store-resolver.js.map +1 -1
- package/dist/forge-payload/.claude-plugin/plugin.json +1 -1
- package/dist/forge-payload/.schemas/enum-catalog.json +2 -2
- package/dist/forge-payload/.schemas/migrations.json +85 -0
- package/dist/forge-payload/.schemas/payload-manifest.schema.json +100 -0
- package/dist/forge-payload/commands/check-agent.md +7 -23
- package/dist/forge-payload/commands/enhance.md +31 -5
- package/dist/forge-payload/commands/init.md +161 -97
- package/dist/forge-payload/commands/reset.md +117 -0
- package/dist/forge-payload/hooks/forge-permissions.cjs +29 -6
- package/dist/forge-payload/init/phases/phase-3-materialize.md +5 -1
- package/dist/forge-payload/integrity.json +22 -7
- package/dist/forge-payload/payload-manifest.json +314 -0
- package/dist/forge-payload/schemas/enum-catalog.json +2 -2
- package/dist/forge-payload/schemas/payload-manifest.schema.json +100 -0
- package/dist/forge-payload/schemas/structure-manifest.json +4 -2
- package/dist/forge-payload/tools/reset-plan.cjs +210 -0
- package/dist/forge-payload/tools/store.cjs +4 -1
- package/dist/forge-payload/tools/substitute-placeholders.cjs +10 -2
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +8 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.d.ts +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/compaction/compaction.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.d.ts +4 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.js +3 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/execution-env.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.d.ts +20 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.js +92 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/jsonl.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.d.ts +18 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.js +42 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/memory.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.d.ts +10 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.js +31 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/repo/shared.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.d.ts +30 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.js +170 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/jsonl.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.d.ts +26 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.js +90 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/harness/session/storage/memory.js.map +1 -0
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +6 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/README.md +12 -4
- package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/env-api-keys.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +45 -0
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +45 -0
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +1804 -815
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +2031 -1384
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +71 -27
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +24 -16
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +3 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +35 -13
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js +2 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses-shared.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +12 -4
- package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.js +13 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js +4 -2
- package/node_modules/@earendil-works/pi-ai/dist/utils/oauth/openai-codex.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +3 -2
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/CHANGELOG.md +143 -0
- package/node_modules/@earendil-works/pi-coding-agent/README.md +26 -4
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.d.ts +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.js +11 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/args.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/project-trust.d.ts +10 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/project-trust.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/project-trust.js +48 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/project-trust.js.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/startup-ui.d.ts +17 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/startup-ui.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/startup-ui.js +128 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/startup-ui.js.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/config.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/config.js +9 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/config.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-runtime.d.ts +3 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-runtime.js +4 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-runtime.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.d.ts +2 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.js +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session-services.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.d.ts +4 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js +16 -3
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/auth-storage.js +4 -3
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts +3 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/branch-summarization.js +9 -3
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/utils.d.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/utils.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/experimental.d.ts +2 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/experimental.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/experimental.js +4 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/experimental.js.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/export-html/template.js +19 -6
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.d.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.js +4 -4
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.d.ts +10 -3
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.js +47 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/types.d.ts +28 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/footer-data-provider.d.ts +2 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/footer-data-provider.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/footer-data-provider.js +29 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/footer-data-provider.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/index.d.ts +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/index.js +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.js +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.d.ts +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.js +44 -5
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.d.ts +3 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js +47 -13
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/project-trust.d.ts +15 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/project-trust.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/project-trust.js +58 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/project-trust.js.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.d.ts +2 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.js +24 -26
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/prompt-templates.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/provider-attribution.d.ts +4 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/provider-attribution.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/provider-attribution.js +72 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/provider-attribution.js.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/provider-display-names.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/provider-display-names.js +3 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/provider-display-names.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.d.ts +13 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.js +112 -37
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.js +7 -33
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.js +103 -70
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.d.ts +20 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js +97 -30
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.js +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/bash.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/find.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/find.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/grep.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/tools/write.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/trust-manager.d.ts +36 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/trust-manager.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/trust-manager.js +202 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/trust-manager.js.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/index.d.ts +5 -4
- package/node_modules/@earendil-works/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/index.js +2 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/main.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/main.js +72 -32
- package/node_modules/@earendil-works/pi-coding-agent/dist/main.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/migrations.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/migrations.js +39 -34
- package/node_modules/@earendil-works/pi-coding-agent/dist/migrations.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/first-time-setup.js +103 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/first-time-setup.js.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/footer.js +7 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/index.d.ts +2 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/index.js +2 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +10 -13
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +3 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +20 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +22 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/trust-selector.d.ts +23 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/trust-selector.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/trust-selector.js +91 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/trust-selector.js.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +7 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js +101 -5
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/print-mode.js +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.d.ts +6 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js +111 -10
- package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.d.ts +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.js +78 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/git.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/git.js +54 -22
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/git.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/open-browser.d.ts +9 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/open-browser.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/open-browser.js +22 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/open-browser.js.map +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/containerization.md +111 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/docs.json +8 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/extensions.md +67 -13
- package/node_modules/@earendil-works/pi-coding-agent/docs/index.md +2 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/models.md +4 -3
- package/node_modules/@earendil-works/pi-coding-agent/docs/packages.md +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/prompt-templates.md +9 -2
- package/node_modules/@earendil-works/pi-coding-agent/docs/providers.md +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/rpc.md +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/sdk.md +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/security.md +59 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/settings.md +15 -0
- package/node_modules/@earendil-works/pi-coding-agent/docs/skills.md +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/terminal-setup.md +36 -2
- package/node_modules/@earendil-works/pi-coding-agent/docs/themes.md +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/tmux.md +4 -2
- package/node_modules/@earendil-works/pi-coding-agent/docs/tui.md +10 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/usage.md +19 -2
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/README.md +2 -0
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-header.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/doom-overlay/index.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/gondolin/index.ts +531 -0
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/gondolin/package-lock.json +185 -0
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/gondolin/package.json +19 -0
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/handoff.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/interactive-shell.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/overlay-qa-tests.ts +152 -81
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/project-trust.ts +64 -0
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/qna.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/question.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/questionnaire.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/sandbox/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/snake.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/space-invaders.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/summarize.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/tic-tac-toe.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/todo.ts +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/tools.ts +5 -0
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/with-deps/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/npm-shrinkwrap.json +12 -419
- package/node_modules/@earendil-works/pi-coding-agent/package.json +5 -8
- package/node_modules/@earendil-works/pi-tui/README.md +13 -1
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts +2 -0
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +6 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +102 -43
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts +2 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +11 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +2 -2
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +4 -7
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +38 -77
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +20 -4
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.js +244 -42
- package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts +1 -0
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.js +46 -15
- package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/node_modules/@mariozechner/clipboard/package.json +2 -1
- package/node_modules/@mariozechner/clipboard-linux-x64-musl/README.md +3 -0
- package/node_modules/@mariozechner/clipboard-linux-x64-musl/package.json +25 -0
- package/package.json +7 -6
- package/dist/extensions/forgecli/add-pipeline.d.ts +0 -19
- package/dist/extensions/forgecli/add-pipeline.js +0 -143
- package/dist/extensions/forgecli/add-pipeline.js.map +0 -1
- package/dist/extensions/forgecli/add-task.d.ts +0 -20
- package/dist/extensions/forgecli/add-task.js +0 -154
- package/dist/extensions/forgecli/add-task.js.map +0 -1
- package/dist/extensions/forgecli/approve.d.ts +0 -22
- package/dist/extensions/forgecli/approve.js +0 -152
- package/dist/extensions/forgecli/approve.js.map +0 -1
- package/dist/extensions/forgecli/banner.d.ts +0 -10
- package/dist/extensions/forgecli/banner.js +0 -36
- package/dist/extensions/forgecli/banner.js.map +0 -1
- package/dist/extensions/forgecli/calibrate.d.ts +0 -64
- package/dist/extensions/forgecli/calibrate.js +0 -481
- package/dist/extensions/forgecli/calibrate.js.map +0 -1
- package/dist/extensions/forgecli/collate.d.ts +0 -22
- package/dist/extensions/forgecli/collate.js +0 -134
- package/dist/extensions/forgecli/collate.js.map +0 -1
- package/dist/extensions/forgecli/commit.d.ts +0 -22
- package/dist/extensions/forgecli/commit.js +0 -152
- package/dist/extensions/forgecli/commit.js.map +0 -1
- package/dist/extensions/forgecli/config-command.d.ts +0 -8
- package/dist/extensions/forgecli/config-command.js +0 -67
- package/dist/extensions/forgecli/config-command.js.map +0 -1
- package/dist/extensions/forgecli/config-layer.d.ts +0 -53
- package/dist/extensions/forgecli/config-layer.js +0 -72
- package/dist/extensions/forgecli/config-layer.js.map +0 -1
- package/dist/extensions/forgecli/config-writer.d.ts +0 -16
- package/dist/extensions/forgecli/config-writer.js +0 -69
- package/dist/extensions/forgecli/config-writer.js.map +0 -1
- package/dist/extensions/forgecli/enhance.d.ts +0 -27
- package/dist/extensions/forgecli/enhance.js +0 -199
- package/dist/extensions/forgecli/enhance.js.map +0 -1
- package/dist/extensions/forgecli/fix-bug.d.ts +0 -85
- package/dist/extensions/forgecli/fix-bug.js +0 -1580
- package/dist/extensions/forgecli/fix-bug.js.map +0 -1
- package/dist/extensions/forgecli/forge-header.d.ts +0 -12
- package/dist/extensions/forgecli/forge-header.js +0 -114
- package/dist/extensions/forgecli/forge-header.js.map +0 -1
- package/dist/extensions/forgecli/forge-init.d.ts +0 -26
- package/dist/extensions/forgecli/forge-init.js +0 -514
- package/dist/extensions/forgecli/forge-init.js.map +0 -1
- package/dist/extensions/forgecli/forge-root.d.ts +0 -10
- package/dist/extensions/forgecli/forge-root.js +0 -62
- package/dist/extensions/forgecli/forge-root.js.map +0 -1
- package/dist/extensions/forgecli/forge-update-command.d.ts +0 -100
- package/dist/extensions/forgecli/forge-update-command.js +0 -435
- package/dist/extensions/forgecli/forge-update-command.js.map +0 -1
- package/dist/extensions/forgecli/friction-emit.d.ts +0 -99
- package/dist/extensions/forgecli/friction-emit.js +0 -245
- package/dist/extensions/forgecli/friction-emit.js.map +0 -1
- package/dist/extensions/forgecli/implement.d.ts +0 -22
- package/dist/extensions/forgecli/implement.js +0 -170
- package/dist/extensions/forgecli/implement.js.map +0 -1
- package/dist/extensions/forgecli/init-context.d.ts +0 -99
- package/dist/extensions/forgecli/init-context.js +0 -178
- package/dist/extensions/forgecli/init-context.js.map +0 -1
- package/dist/extensions/forgecli/init-progress.d.ts +0 -39
- package/dist/extensions/forgecli/init-progress.js +0 -117
- package/dist/extensions/forgecli/init-progress.js.map +0 -1
- package/dist/extensions/forgecli/input-router.d.ts +0 -33
- package/dist/extensions/forgecli/input-router.js +0 -136
- package/dist/extensions/forgecli/input-router.js.map +0 -1
- package/dist/extensions/forgecli/lib/halt-advisor.d.ts +0 -59
- package/dist/extensions/forgecli/lib/halt-advisor.js +0 -113
- package/dist/extensions/forgecli/lib/halt-advisor.js.map +0 -1
- package/dist/extensions/forgecli/lib/orchestrator-preflight.d.ts +0 -46
- package/dist/extensions/forgecli/lib/orchestrator-preflight.js +0 -64
- package/dist/extensions/forgecli/lib/orchestrator-preflight.js.map +0 -1
- package/dist/extensions/forgecli/materialize.d.ts +0 -16
- package/dist/extensions/forgecli/materialize.js +0 -195
- package/dist/extensions/forgecli/materialize.js.map +0 -1
- package/dist/extensions/forgecli/migrate.d.ts +0 -22
- package/dist/extensions/forgecli/migrate.js +0 -260
- package/dist/extensions/forgecli/migrate.js.map +0 -1
- package/dist/extensions/forgecli/migration-engine.d.ts +0 -117
- package/dist/extensions/forgecli/migration-engine.js +0 -563
- package/dist/extensions/forgecli/migration-engine.js.map +0 -1
- package/dist/extensions/forgecli/model-registry.d.ts +0 -61
- package/dist/extensions/forgecli/model-registry.js +0 -127
- package/dist/extensions/forgecli/model-registry.js.map +0 -1
- package/dist/extensions/forgecli/model-resolver.d.ts +0 -32
- package/dist/extensions/forgecli/model-resolver.js +0 -65
- package/dist/extensions/forgecli/model-resolver.js.map +0 -1
- package/dist/extensions/forgecli/model-validator.d.ts +0 -29
- package/dist/extensions/forgecli/model-validator.js +0 -107
- package/dist/extensions/forgecli/model-validator.js.map +0 -1
- package/dist/extensions/forgecli/orchestrator-status-bar.d.ts +0 -26
- package/dist/extensions/forgecli/orchestrator-status-bar.js +0 -213
- package/dist/extensions/forgecli/orchestrator-status-bar.js.map +0 -1
- package/dist/extensions/forgecli/plan.d.ts +0 -22
- package/dist/extensions/forgecli/plan.js +0 -167
- package/dist/extensions/forgecli/plan.js.map +0 -1
- package/dist/extensions/forgecli/quiz-agent.d.ts +0 -17
- package/dist/extensions/forgecli/quiz-agent.js +0 -98
- package/dist/extensions/forgecli/quiz-agent.js.map +0 -1
- package/dist/extensions/forgecli/read-command.d.ts +0 -2
- package/dist/extensions/forgecli/read-command.js +0 -100
- package/dist/extensions/forgecli/read-command.js.map +0 -1
- package/dist/extensions/forgecli/regenerate.d.ts +0 -40
- package/dist/extensions/forgecli/regenerate.js +0 -438
- package/dist/extensions/forgecli/regenerate.js.map +0 -1
- package/dist/extensions/forgecli/remove-command.d.ts +0 -17
- package/dist/extensions/forgecli/remove-command.js +0 -124
- package/dist/extensions/forgecli/remove-command.js.map +0 -1
- package/dist/extensions/forgecli/report-bug.d.ts +0 -25
- package/dist/extensions/forgecli/report-bug.js +0 -159
- package/dist/extensions/forgecli/report-bug.js.map +0 -1
- package/dist/extensions/forgecli/retrospective.d.ts +0 -20
- package/dist/extensions/forgecli/retrospective.js +0 -126
- package/dist/extensions/forgecli/retrospective.js.map +0 -1
- package/dist/extensions/forgecli/review-code.d.ts +0 -35
- package/dist/extensions/forgecli/review-code.js +0 -196
- package/dist/extensions/forgecli/review-code.js.map +0 -1
- package/dist/extensions/forgecli/review-plan.d.ts +0 -35
- package/dist/extensions/forgecli/review-plan.js +0 -200
- package/dist/extensions/forgecli/review-plan.js.map +0 -1
- package/dist/extensions/forgecli/run-sprint.d.ts +0 -27
- package/dist/extensions/forgecli/run-sprint.js +0 -716
- package/dist/extensions/forgecli/run-sprint.js.map +0 -1
- package/dist/extensions/forgecli/run-task.d.ts +0 -204
- package/dist/extensions/forgecli/run-task.js +0 -1403
- package/dist/extensions/forgecli/run-task.js.map +0 -1
- package/dist/extensions/forgecli/skill-curation-flag.d.ts +0 -21
- package/dist/extensions/forgecli/skill-curation-flag.js +0 -71
- package/dist/extensions/forgecli/skill-curation-flag.js.map +0 -1
- package/dist/extensions/forgecli/skill-curator-subagent.d.ts +0 -102
- package/dist/extensions/forgecli/skill-curator-subagent.js +0 -339
- package/dist/extensions/forgecli/skill-curator-subagent.js.map +0 -1
- package/dist/extensions/forgecli/skill-retriever.d.ts +0 -84
- package/dist/extensions/forgecli/skill-retriever.js +0 -246
- package/dist/extensions/forgecli/skill-retriever.js.map +0 -1
- package/dist/extensions/forgecli/skill-usage-tracker.d.ts +0 -91
- package/dist/extensions/forgecli/skill-usage-tracker.js +0 -224
- package/dist/extensions/forgecli/skill-usage-tracker.js.map +0 -1
- package/dist/extensions/forgecli/sprint-intake.d.ts +0 -10
- package/dist/extensions/forgecli/sprint-intake.js +0 -91
- package/dist/extensions/forgecli/sprint-intake.js.map +0 -1
- package/dist/extensions/forgecli/sprint-plan.d.ts +0 -14
- package/dist/extensions/forgecli/sprint-plan.js +0 -122
- package/dist/extensions/forgecli/sprint-plan.js.map +0 -1
- package/dist/extensions/forgecli/status-command.d.ts +0 -19
- package/dist/extensions/forgecli/status-command.js +0 -140
- package/dist/extensions/forgecli/status-command.js.map +0 -1
- package/dist/extensions/forgecli/store-error-remediation.d.ts +0 -65
- package/dist/extensions/forgecli/store-error-remediation.js +0 -307
- package/dist/extensions/forgecli/store-error-remediation.js.map +0 -1
- package/dist/extensions/forgecli/store-query.d.ts +0 -22
- package/dist/extensions/forgecli/store-query.js +0 -107
- package/dist/extensions/forgecli/store-query.js.map +0 -1
- package/dist/extensions/forgecli/store-repair.d.ts +0 -17
- package/dist/extensions/forgecli/store-repair.js +0 -123
- package/dist/extensions/forgecli/store-repair.js.map +0 -1
- package/dist/extensions/forgecli/store-resolver.d.ts +0 -56
- package/dist/extensions/forgecli/store-resolver.js +0 -263
- package/dist/extensions/forgecli/store-resolver.js.map +0 -1
- package/dist/extensions/forgecli/store-validator.d.ts +0 -16
- package/dist/extensions/forgecli/store-validator.js +0 -32
- package/dist/extensions/forgecli/store-validator.js.map +0 -1
- package/dist/extensions/forgecli/test-orchestrate.d.ts +0 -2
- package/dist/extensions/forgecli/test-orchestrate.js +0 -182
- package/dist/extensions/forgecli/test-orchestrate.js.map +0 -1
- package/dist/extensions/forgecli/thread-switcher.d.ts +0 -5
- package/dist/extensions/forgecli/thread-switcher.js +0 -189
- package/dist/extensions/forgecli/thread-switcher.js.map +0 -1
- package/dist/extensions/forgecli/transition-guard.d.ts +0 -20
- package/dist/extensions/forgecli/transition-guard.js +0 -89
- package/dist/extensions/forgecli/transition-guard.js.map +0 -1
- package/dist/extensions/forgecli/update-check.d.ts +0 -37
- package/dist/extensions/forgecli/update-check.js +0 -185
- package/dist/extensions/forgecli/update-check.js.map +0 -1
- package/dist/extensions/forgecli/update-tools.d.ts +0 -23
- package/dist/extensions/forgecli/update-tools.js +0 -135
- package/dist/extensions/forgecli/update-tools.js.map +0 -1
- package/dist/extensions/forgecli/validate.d.ts +0 -22
- package/dist/extensions/forgecli/validate.js +0 -152
- package/dist/extensions/forgecli/validate.js.map +0 -1
- package/dist/extensions/forgecli/viewport-events.d.ts +0 -78
- package/dist/extensions/forgecli/viewport-events.js +0 -243
- package/dist/extensions/forgecli/viewport-events.js.map +0 -1
- package/dist/extensions/forgecli/viewport-renderer.d.ts +0 -83
- package/dist/extensions/forgecli/viewport-renderer.js +0 -233
- package/dist/extensions/forgecli/viewport-renderer.js.map +0 -1
- package/dist/extensions/forgecli/viewport-theme.d.ts +0 -11
- package/dist/extensions/forgecli/viewport-theme.js +0 -128
- package/dist/extensions/forgecli/viewport-theme.js.map +0 -1
- package/dist/extensions/forgecli/whats-new-widget.d.ts +0 -26
- package/dist/extensions/forgecli/whats-new-widget.js +0 -376
- package/dist/extensions/forgecli/whats-new-widget.js.map +0 -1
- package/dist/extensions/forgecli/whats-new.d.ts +0 -120
- package/dist/extensions/forgecli/whats-new.js +0 -470
- package/dist/extensions/forgecli/whats-new.js.map +0 -1
- package/dist/forge-payload/.base-pack/commands/check-agent.md +0 -22
- package/dist/forge-payload/.base-pack/commands/enhance.md +0 -37
- package/dist/forge-payload/.base-pack/commands/init.md +0 -278
- package/dist/forge-payload/init/generation/generate-knowledge-base.md +0 -56
- package/dist/forge-payload/init/generation/generate-personas.md +0 -54
- package/dist/forge-payload/init/generation/generate-skills.md +0 -36
- package/dist/forge-payload/init/generation/generate-templates.md +0 -39
- /package/dist/forge-payload/{.base-pack/commands → commands}/approve.md +0 -0
- /package/dist/forge-payload/{.base-pack/commands → commands}/collate.md +0 -0
- /package/dist/forge-payload/{.base-pack/commands → commands}/commit.md +0 -0
- /package/dist/forge-payload/{.base-pack/commands → commands}/fix-bug.md +0 -0
- /package/dist/forge-payload/{.base-pack/commands → commands}/implement.md +0 -0
- /package/dist/forge-payload/{.base-pack/commands → commands}/new-sprint.md +0 -0
- /package/dist/forge-payload/{.base-pack/commands → commands}/plan-sprint.md +0 -0
- /package/dist/forge-payload/{.base-pack/commands → commands}/plan.md +0 -0
- /package/dist/forge-payload/{.base-pack/commands → commands}/retro.md +0 -0
- /package/dist/forge-payload/{.base-pack/commands → commands}/review-code.md +0 -0
- /package/dist/forge-payload/{.base-pack/commands → commands}/review-plan.md +0 -0
- /package/dist/forge-payload/{.base-pack/commands → commands}/run-sprint.md +0 -0
- /package/dist/forge-payload/{.base-pack/commands → commands}/run-task.md +0 -0
- /package/dist/forge-payload/{.base-pack/commands → commands}/validate.md +0 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// reset-plan.cjs — FEAT-009 T03: deterministic reset PLANNER + referential-
|
|
3
|
+
// integrity checker for /forge:reset.
|
|
4
|
+
//
|
|
5
|
+
// Given an entity (task | bug | sprint) and a target phase, this computes — but
|
|
6
|
+
// does NOT apply — the status transition(s) a reset would perform, plus the
|
|
7
|
+
// cross-entity integrity implications the operator must acknowledge before the
|
|
8
|
+
// LLM-backed /forge:reset command applies anything through store-cli.
|
|
9
|
+
//
|
|
10
|
+
// It NEVER mutates the store. Application is the command's job (store-cli
|
|
11
|
+
// update-status --force), gated on explicit confirmation of these warnings.
|
|
12
|
+
//
|
|
13
|
+
// Design: planReset(store, opts) is a pure function over the store facade so it
|
|
14
|
+
// is unit-testable with a mock store. The CLI wrapper loads the real store.
|
|
15
|
+
|
|
16
|
+
// Phase → required pre-status. Mirrors forge-cli's PHASE_PRE_STATUS /
|
|
17
|
+
// BUG_PHASE_PRE_STATUS (the two-layer boundary forbids a shared import); the
|
|
18
|
+
// reset-plan.test.cjs locks these against the documented workflow guards.
|
|
19
|
+
const TASK_PRE_STATUS = {
|
|
20
|
+
plan: 'planned',
|
|
21
|
+
'review-plan': 'planned',
|
|
22
|
+
implement: 'plan-approved',
|
|
23
|
+
'review-code': 'implemented',
|
|
24
|
+
validate: 'review-approved',
|
|
25
|
+
approve: 'review-approved',
|
|
26
|
+
writeback: 'approved',
|
|
27
|
+
commit: 'approved',
|
|
28
|
+
};
|
|
29
|
+
const BUG_PRE_STATUS = {
|
|
30
|
+
triage: 'reported',
|
|
31
|
+
'plan-fix': 'in-progress',
|
|
32
|
+
'review-plan': 'in-progress',
|
|
33
|
+
implement: 'in-progress',
|
|
34
|
+
'review-code': 'in-progress',
|
|
35
|
+
approve: 'in-progress',
|
|
36
|
+
commit: 'in-progress',
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// Lifecycle ordinals for rewind detection (higher = later).
|
|
40
|
+
const TASK_ORDER = {
|
|
41
|
+
draft: 0,
|
|
42
|
+
planned: 1,
|
|
43
|
+
'plan-approved': 2,
|
|
44
|
+
implementing: 3,
|
|
45
|
+
implemented: 4,
|
|
46
|
+
'review-approved': 5,
|
|
47
|
+
approved: 6,
|
|
48
|
+
committed: 7,
|
|
49
|
+
};
|
|
50
|
+
const BUG_ORDER = { reported: 0, triaged: 1, 'in-progress': 2, fixed: 3 };
|
|
51
|
+
|
|
52
|
+
function warn(code, msg, extra) {
|
|
53
|
+
return Object.assign({ code, msg }, extra || {});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Tasks (and the sprint) that reference `id` in their dependencies. */
|
|
57
|
+
function findDependents(store, id) {
|
|
58
|
+
const tasks = (store.listTasks() || []).filter(
|
|
59
|
+
(t) => Array.isArray(t.dependencies) && t.dependencies.includes(id),
|
|
60
|
+
);
|
|
61
|
+
return tasks;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function planTask(store, id, to) {
|
|
65
|
+
const task = store.getTask(id);
|
|
66
|
+
if (!task) return { ok: false, error: `task ${id} not found` };
|
|
67
|
+
const targetStatus = TASK_PRE_STATUS[to];
|
|
68
|
+
if (!targetStatus) {
|
|
69
|
+
return { ok: false, error: `unknown task phase '${to}'. Known: ${Object.keys(TASK_PRE_STATUS).join(', ')}` };
|
|
70
|
+
}
|
|
71
|
+
const from = task.status;
|
|
72
|
+
const rewind = (TASK_ORDER[targetStatus] ?? 0) < (TASK_ORDER[from] ?? 0);
|
|
73
|
+
const warnings = [];
|
|
74
|
+
|
|
75
|
+
if (from === 'committed') {
|
|
76
|
+
warnings.push(warn('committed-work', `Task ${id} is committed — its git commit is NOT reverted by this reset; the working tree may diverge from the rewound task state.`));
|
|
77
|
+
}
|
|
78
|
+
// Parent-sprint coherence.
|
|
79
|
+
if (task.sprintId) {
|
|
80
|
+
const sprint = store.getSprint(task.sprintId);
|
|
81
|
+
if (sprint && ['completed', 'retrospective-done'].includes(sprint.status)) {
|
|
82
|
+
warnings.push(warn('sprint-incoherent', `Parent sprint ${task.sprintId} is '${sprint.status}'; resetting a member task makes it inconsistent — reopen the sprint to 'active' as part of the reset.`, { sprintId: task.sprintId, sprintStatus: sprint.status }));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Dependents resting on rewound work.
|
|
86
|
+
const dependents = findDependents(store, id).filter((d) => (TASK_ORDER[d.status] ?? 0) >= TASK_ORDER['plan-approved']);
|
|
87
|
+
if (dependents.length > 0) {
|
|
88
|
+
warnings.push(warn('dependents-affected', `${dependents.length} task(s) depend on ${id} and are already past planning; they rest on work being rewound and may need re-validation.`, { ids: dependents.map((d) => d.taskId) }));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
ok: true,
|
|
93
|
+
entity: { kind: 'task', id, currentStatus: from, targetStatus, targetPhase: to },
|
|
94
|
+
rewind,
|
|
95
|
+
forceRequired: rewind || from === 'blocked' || from === 'escalated',
|
|
96
|
+
transitions: [{ id, kind: 'task', from, to: targetStatus }],
|
|
97
|
+
warnings,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function planBug(store, id, to) {
|
|
102
|
+
const bug = store.getBug(id);
|
|
103
|
+
if (!bug) return { ok: false, error: `bug ${id} not found` };
|
|
104
|
+
const targetStatus = BUG_PRE_STATUS[to];
|
|
105
|
+
if (!targetStatus) {
|
|
106
|
+
return { ok: false, error: `unknown bug phase '${to}'. Known: ${Object.keys(BUG_PRE_STATUS).join(', ')}` };
|
|
107
|
+
}
|
|
108
|
+
const from = bug.status;
|
|
109
|
+
const rewind = (BUG_ORDER[targetStatus] ?? 0) < (BUG_ORDER[from] ?? 0);
|
|
110
|
+
const warnings = [];
|
|
111
|
+
if (from === 'fixed') {
|
|
112
|
+
warnings.push(warn('committed-work', `Bug ${id} is fixed — its commit is NOT reverted by this reset.`));
|
|
113
|
+
}
|
|
114
|
+
const dependents = findDependents(store, id).filter((d) => (TASK_ORDER[d.status] ?? 0) >= TASK_ORDER['plan-approved']);
|
|
115
|
+
if (dependents.length > 0) {
|
|
116
|
+
warnings.push(warn('dependents-affected', `${dependents.length} task(s) depend on ${id} and are past planning; they rest on work being rewound.`, { ids: dependents.map((d) => d.taskId) }));
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
ok: true,
|
|
120
|
+
entity: { kind: 'bug', id, currentStatus: from, targetStatus, targetPhase: to },
|
|
121
|
+
rewind,
|
|
122
|
+
forceRequired: rewind,
|
|
123
|
+
transitions: [{ id, kind: 'bug', from, to: targetStatus }],
|
|
124
|
+
warnings,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Sprint reset: reopen the sprint and cascade-reset a member task plus every
|
|
130
|
+
* member task that (transitively) depends on it — they build on the rewound
|
|
131
|
+
* task. `fromTask` is required (where to rewind from).
|
|
132
|
+
*/
|
|
133
|
+
function planSprint(store, id, fromTask) {
|
|
134
|
+
const sprint = store.getSprint(id);
|
|
135
|
+
if (!sprint) return { ok: false, error: `sprint ${id} not found` };
|
|
136
|
+
if (!fromTask) return { ok: false, error: `sprint reset requires --from-task <taskId> (the member task to rewind from)` };
|
|
137
|
+
const members = (sprint.taskIds || []).map((tid) => store.getTask(tid)).filter(Boolean);
|
|
138
|
+
const memberIds = new Set(members.map((t) => t.taskId));
|
|
139
|
+
if (!memberIds.has(fromTask)) {
|
|
140
|
+
return { ok: false, error: `task ${fromTask} is not a member of sprint ${id}` };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Transitive dependents of fromTask within the sprint.
|
|
144
|
+
const affected = new Set([fromTask]);
|
|
145
|
+
let grew = true;
|
|
146
|
+
while (grew) {
|
|
147
|
+
grew = false;
|
|
148
|
+
for (const t of members) {
|
|
149
|
+
if (affected.has(t.taskId)) continue;
|
|
150
|
+
if ((t.dependencies || []).some((dep) => affected.has(dep))) {
|
|
151
|
+
affected.add(t.taskId);
|
|
152
|
+
grew = true;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const cascade = members
|
|
158
|
+
.filter((t) => affected.has(t.taskId))
|
|
159
|
+
.map((t) => ({ id: t.taskId, from: t.status, to: 'planned' }));
|
|
160
|
+
const warnings = [];
|
|
161
|
+
const committed = cascade.filter((c) => c.from === 'committed').map((c) => c.id);
|
|
162
|
+
if (committed.length) {
|
|
163
|
+
warnings.push(warn('committed-work', `${committed.length} cascade task(s) are committed; their commits are NOT reverted.`, { ids: committed }));
|
|
164
|
+
}
|
|
165
|
+
if (['completed', 'retrospective-done'].includes(sprint.status)) {
|
|
166
|
+
warnings.push(warn('sprint-reopen', `Sprint ${id} is '${sprint.status}' and will be reopened to 'active'.`));
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
ok: true,
|
|
170
|
+
entity: { kind: 'sprint', id, currentStatus: sprint.status, fromTask },
|
|
171
|
+
transitions: [
|
|
172
|
+
{ id, kind: 'sprint', from: sprint.status, to: 'active' },
|
|
173
|
+
...cascade.map((c) => ({ id: c.id, kind: 'task', from: c.from, to: c.to })),
|
|
174
|
+
],
|
|
175
|
+
cascade: cascade.map((c) => c.id),
|
|
176
|
+
warnings,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Pure planner over the store facade. */
|
|
181
|
+
function planReset(store, opts) {
|
|
182
|
+
const { entity, id, to, fromTask } = opts;
|
|
183
|
+
if (entity === 'task') return planTask(store, id, to);
|
|
184
|
+
if (entity === 'bug') return planBug(store, id, to);
|
|
185
|
+
if (entity === 'sprint') return planSprint(store, id, fromTask);
|
|
186
|
+
return { ok: false, error: `unknown entity '${entity}' (expected task | bug | sprint)` };
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
module.exports = { planReset, TASK_PRE_STATUS, BUG_PRE_STATUS };
|
|
190
|
+
|
|
191
|
+
// ── CLI ─────────────────────────────────────────────────────────────────────
|
|
192
|
+
if (require.main === module) {
|
|
193
|
+
const argv = process.argv.slice(2);
|
|
194
|
+
const get = (flag) => {
|
|
195
|
+
const i = argv.indexOf(flag);
|
|
196
|
+
return i >= 0 ? argv[i + 1] : undefined;
|
|
197
|
+
};
|
|
198
|
+
const entity = get('--entity');
|
|
199
|
+
const id = get('--id');
|
|
200
|
+
const to = get('--to');
|
|
201
|
+
const fromTask = get('--from-task');
|
|
202
|
+
if (!entity || !id) {
|
|
203
|
+
process.stderr.write('Usage: reset-plan.cjs --entity task|bug|sprint --id <id> [--to <phase>] [--from-task <taskId>] [--json]\n');
|
|
204
|
+
process.exit(2);
|
|
205
|
+
}
|
|
206
|
+
const store = require('./store.cjs');
|
|
207
|
+
const plan = planReset(store, { entity, id, to, fromTask });
|
|
208
|
+
process.stdout.write(JSON.stringify(plan, null, 2) + '\n');
|
|
209
|
+
process.exit(plan.ok ? 0 : 1);
|
|
210
|
+
}
|
|
@@ -234,7 +234,10 @@ class FSImpl {
|
|
|
234
234
|
getFeature(id) { return this._readJson(this._getPath('feature', id)); }
|
|
235
235
|
listFeatures(filter) { return this._listEntities('features', filter); }
|
|
236
236
|
writeFeature(data) {
|
|
237
|
-
|
|
237
|
+
// FORGE-BUG-047: feature records key on `id` (matching the schema, the
|
|
238
|
+
// store-cli template, and every FEAT-00x record) — not `feature_id`, which
|
|
239
|
+
// was always undefined and misfiled writes to features/undefined.json.
|
|
240
|
+
return this._writeJson(this._getPath('feature', data.id), data);
|
|
238
241
|
}
|
|
239
242
|
deleteFeature(id) {
|
|
240
243
|
const p = this._getPath('feature', id);
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
* output to the appropriate output directories.
|
|
10
10
|
*
|
|
11
11
|
* Output path mapping (--target claude-code, default):
|
|
12
|
-
* base-pack/commands/ → <outRoot>/.claude/commands/forge/ (fixed namespace)
|
|
13
12
|
* base-pack/personas/ → <outRoot>/.forge/personas/
|
|
14
13
|
* base-pack/skills/ → <outRoot>/.forge/skills/
|
|
15
14
|
* base-pack/workflows/ → <outRoot>/.forge/workflows/
|
|
@@ -20,7 +19,13 @@
|
|
|
20
19
|
* base-pack/skills/ → <outRoot>/skills/
|
|
21
20
|
* base-pack/workflows/ → <outRoot>/workflows/ (including _fragments/)
|
|
22
21
|
* base-pack/templates/ → <outRoot>/templates/
|
|
23
|
-
*
|
|
22
|
+
*
|
|
23
|
+
* Commands are NO LONGER materialised here. The unified slash-command tree
|
|
24
|
+
* lives at forge/forge/commands/ (FORGE-S32-T06 collapsed the former
|
|
25
|
+
* base-pack/commands/ second tree into it) and is installed verbatim by the
|
|
26
|
+
* bootstrap manifest's single `commands` entry. base-pack/ no longer carries a
|
|
27
|
+
* commands/ subdir, so the walker's commands branch below is inert; pi commands
|
|
28
|
+
* remain registered programmatically.
|
|
24
29
|
*
|
|
25
30
|
* CLI:
|
|
26
31
|
* node substitute-placeholders.cjs
|
|
@@ -409,6 +414,9 @@ function walkBasePack(basePack, map, outRoot, dryRun, io, categoryFilter) {
|
|
|
409
414
|
|
|
410
415
|
let relOutputDir;
|
|
411
416
|
if (subdir === 'commands') {
|
|
417
|
+
// Inert since FORGE-S32-T06: base-pack/commands/ was collapsed into the
|
|
418
|
+
// unified forge/forge/commands/ tree (installed verbatim by bootstrap).
|
|
419
|
+
// Retained so a stray base-pack commands/ subdir still maps correctly.
|
|
412
420
|
relOutputDir = path.join('.claude', 'commands', commandsSubdir);
|
|
413
421
|
} else {
|
|
414
422
|
relOutputDir = SUBDIR_OUTPUT_MAP[subdir];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGN,WAAW,EAIX,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EAIZ,QAAQ,EACR,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,SAAS,CACxB,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAiBzC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAwBzC;AAED,wBAAsB,YAAY,CACjC,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAgBzB;AAED,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAiBzB","sourcesContent":["/**\n * Agent loop that works with AgentMessage throughout.\n * Transforms to Message[] only at the LLM call boundary.\n */\n\nimport {\n\ttype AssistantMessage,\n\ttype Context,\n\tEventStream,\n\tstreamSimple,\n\ttype ToolResultMessage,\n\tvalidateToolArguments,\n} from \"@earendil-works/pi-ai\";\nimport type {\n\tAgentContext,\n\tAgentEvent,\n\tAgentLoopConfig,\n\tAgentMessage,\n\tAgentTool,\n\tAgentToolCall,\n\tAgentToolResult,\n\tStreamFn,\n} from \"./types.ts\";\n\nexport type AgentEventSink = (event: AgentEvent) => Promise<void> | void;\n\n/**\n * Start an agent loop with a new prompt message.\n * The prompt is added to the context and events are emitted for it.\n */\nexport function agentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoop(\n\t\tprompts,\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t).then((messages) => {\n\t\tstream.end(messages);\n\t});\n\n\treturn stream;\n}\n\n/**\n * Continue an agent loop from the current context without adding a new message.\n * Used for retries - context already has user message or tool results.\n *\n * **Important:** The last message in context must convert to a `user` or `toolResult` message\n * via `convertToLlm`. If it doesn't, the LLM provider will reject the request.\n * This cannot be validated here since `convertToLlm` is only called once per turn.\n */\nexport function agentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoopContinue(\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t).then((messages) => {\n\t\tstream.end(messages);\n\t});\n\n\treturn stream;\n}\n\nexport async function runAgentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tconst newMessages: AgentMessage[] = [...prompts];\n\tconst currentContext: AgentContext = {\n\t\t...context,\n\t\tmessages: [...context.messages, ...prompts],\n\t};\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\tfor (const prompt of prompts) {\n\t\tawait emit({ type: \"message_start\", message: prompt });\n\t\tawait emit({ type: \"message_end\", message: prompt });\n\t}\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nexport async function runAgentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst newMessages: AgentMessage[] = [];\n\tconst currentContext: AgentContext = { ...context };\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nfunction createAgentStream(): EventStream<AgentEvent, AgentMessage[]> {\n\treturn new EventStream<AgentEvent, AgentMessage[]>(\n\t\t(event: AgentEvent) => event.type === \"agent_end\",\n\t\t(event: AgentEvent) => (event.type === \"agent_end\" ? event.messages : []),\n\t);\n}\n\n/**\n * Main loop logic shared by agentLoop and agentLoopContinue.\n */\nasync function runLoop(\n\tinitialContext: AgentContext,\n\tnewMessages: AgentMessage[],\n\tinitialConfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<void> {\n\tlet currentContext = initialContext;\n\tlet config = initialConfig;\n\tlet firstTurn = true;\n\t// Check for steering messages at start (user may have typed while waiting)\n\tlet pendingMessages: AgentMessage[] = (await config.getSteeringMessages?.()) || [];\n\n\t// Outer loop: continues when queued follow-up messages arrive after agent would stop\n\twhile (true) {\n\t\tlet hasMoreToolCalls = true;\n\n\t\t// Inner loop: process tool calls and steering messages\n\t\twhile (hasMoreToolCalls || pendingMessages.length > 0) {\n\t\t\tif (!firstTurn) {\n\t\t\t\tawait emit({ type: \"turn_start\" });\n\t\t\t} else {\n\t\t\t\tfirstTurn = false;\n\t\t\t}\n\n\t\t\t// Process pending messages (inject before next assistant response)\n\t\t\tif (pendingMessages.length > 0) {\n\t\t\t\tfor (const message of pendingMessages) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message });\n\t\t\t\t\tawait emit({ type: \"message_end\", message });\n\t\t\t\t\tcurrentContext.messages.push(message);\n\t\t\t\t\tnewMessages.push(message);\n\t\t\t\t}\n\t\t\t\tpendingMessages = [];\n\t\t\t}\n\n\t\t\t// Stream assistant response\n\t\t\tconst message = await streamAssistantResponse(currentContext, config, signal, emit, streamFn);\n\t\t\tnewMessages.push(message);\n\n\t\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\t\t\tawait emit({ type: \"turn_end\", message, toolResults: [] });\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Check for tool calls\n\t\t\tconst toolCalls = message.content.filter((c) => c.type === \"toolCall\");\n\n\t\t\tconst toolResults: ToolResultMessage[] = [];\n\t\t\thasMoreToolCalls = false;\n\t\t\tif (toolCalls.length > 0) {\n\t\t\t\tconst executedToolBatch = await executeToolCalls(currentContext, message, config, signal, emit);\n\t\t\t\ttoolResults.push(...executedToolBatch.messages);\n\t\t\t\thasMoreToolCalls = !executedToolBatch.terminate;\n\n\t\t\t\tfor (const result of toolResults) {\n\t\t\t\t\tcurrentContext.messages.push(result);\n\t\t\t\t\tnewMessages.push(result);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait emit({ type: \"turn_end\", message, toolResults });\n\n\t\t\tconst nextTurnContext = {\n\t\t\t\tmessage,\n\t\t\t\ttoolResults,\n\t\t\t\tcontext: currentContext,\n\t\t\t\tnewMessages,\n\t\t\t};\n\t\t\tconst nextTurnSnapshot = await config.prepareNextTurn?.(nextTurnContext);\n\t\t\tif (nextTurnSnapshot) {\n\t\t\t\tcurrentContext = nextTurnSnapshot.context ?? currentContext;\n\t\t\t\tconfig = {\n\t\t\t\t\t...config,\n\t\t\t\t\tmodel: nextTurnSnapshot.model ?? config.model,\n\t\t\t\t\treasoning:\n\t\t\t\t\t\tnextTurnSnapshot.thinkingLevel === undefined\n\t\t\t\t\t\t\t? config.reasoning\n\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel === \"off\"\n\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tawait config.shouldStopAfterTurn?.({\n\t\t\t\t\tmessage,\n\t\t\t\t\ttoolResults,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t\tnewMessages,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpendingMessages = (await config.getSteeringMessages?.()) || [];\n\t\t}\n\n\t\t// Agent would stop here. Check for follow-up messages.\n\t\tconst followUpMessages = (await config.getFollowUpMessages?.()) || [];\n\t\tif (followUpMessages.length > 0) {\n\t\t\t// Set as pending so inner loop processes them\n\t\t\tpendingMessages = followUpMessages;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// No more messages, exit\n\t\tbreak;\n\t}\n\n\tawait emit({ type: \"agent_end\", messages: newMessages });\n}\n\n/**\n * Stream an assistant response from the LLM.\n * This is where AgentMessage[] gets transformed to Message[] for the LLM.\n */\nasync function streamAssistantResponse(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<AssistantMessage> {\n\t// Apply context transform if configured (AgentMessage[] → AgentMessage[])\n\tlet messages = context.messages;\n\tif (config.transformContext) {\n\t\tmessages = await config.transformContext(messages, signal);\n\t}\n\n\t// Convert to LLM-compatible messages (AgentMessage[] → Message[])\n\tconst llmMessages = await config.convertToLlm(messages);\n\n\t// Build LLM context\n\tconst llmContext: Context = {\n\t\tsystemPrompt: context.systemPrompt,\n\t\tmessages: llmMessages,\n\t\ttools: context.tools,\n\t};\n\n\tconst streamFunction = streamFn || streamSimple;\n\n\t// Resolve API key (important for expiring tokens)\n\tconst resolvedApiKey =\n\t\t(config.getApiKey ? await config.getApiKey(config.model.provider) : undefined) || config.apiKey;\n\n\tconst response = await streamFunction(config.model, llmContext, {\n\t\t...config,\n\t\tapiKey: resolvedApiKey,\n\t\tsignal,\n\t});\n\n\tlet partialMessage: AssistantMessage | null = null;\n\tlet addedPartial = false;\n\n\tfor await (const event of response) {\n\t\tswitch (event.type) {\n\t\t\tcase \"start\":\n\t\t\t\tpartialMessage = event.partial;\n\t\t\t\tcontext.messages.push(partialMessage);\n\t\t\t\taddedPartial = true;\n\t\t\t\tawait emit({ type: \"message_start\", message: { ...partialMessage } });\n\t\t\t\tbreak;\n\n\t\t\tcase \"text_start\":\n\t\t\tcase \"text_delta\":\n\t\t\tcase \"text_end\":\n\t\t\tcase \"thinking_start\":\n\t\t\tcase \"thinking_delta\":\n\t\t\tcase \"thinking_end\":\n\t\t\tcase \"toolcall_start\":\n\t\t\tcase \"toolcall_delta\":\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tif (partialMessage) {\n\t\t\t\t\tpartialMessage = event.partial;\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = partialMessage;\n\t\t\t\t\tawait emit({\n\t\t\t\t\t\ttype: \"message_update\",\n\t\t\t\t\t\tassistantMessageEvent: event,\n\t\t\t\t\t\tmessage: { ...partialMessage },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"done\":\n\t\t\tcase \"error\": {\n\t\t\t\tconst finalMessage = await response.result();\n\t\t\t\tif (addedPartial) {\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t\t\t\t} else {\n\t\t\t\t\tcontext.messages.push(finalMessage);\n\t\t\t\t}\n\t\t\t\tif (!addedPartial) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t\t\t\t}\n\t\t\t\tawait emit({ type: \"message_end\", message: finalMessage });\n\t\t\t\treturn finalMessage;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst finalMessage = await response.result();\n\tif (addedPartial) {\n\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t} else {\n\t\tcontext.messages.push(finalMessage);\n\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t}\n\tawait emit({ type: \"message_end\", message: finalMessage });\n\treturn finalMessage;\n}\n\n/**\n * Execute tool calls from an assistant message.\n */\nasync function executeToolCalls(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst toolCalls = assistantMessage.content.filter((c) => c.type === \"toolCall\");\n\tconst hasSequentialToolCall = toolCalls.some(\n\t\t(tc) => currentContext.tools?.find((t) => t.name === tc.name)?.executionMode === \"sequential\",\n\t);\n\tif (config.toolExecution === \"sequential\" || hasSequentialToolCall) {\n\t\treturn executeToolCallsSequential(currentContext, assistantMessage, toolCalls, config, signal, emit);\n\t}\n\treturn executeToolCallsParallel(currentContext, assistantMessage, toolCalls, config, signal, emit);\n}\n\ntype ExecutedToolCallBatch = {\n\tmessages: ToolResultMessage[];\n\tterminate: boolean;\n};\n\nasync function executeToolCallsSequential(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallOutcome[] = [];\n\tconst messages: ToolResultMessage[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tawait emit({\n\t\t\ttype: \"tool_execution_start\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\targs: toolCall.arguments,\n\t\t});\n\n\t\tconst preparation = await prepareToolCall(currentContext, assistantMessage, toolCall, config, signal);\n\t\tlet finalized: FinalizedToolCallOutcome;\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tfinalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t};\n\t\t} else {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tfinalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t}\n\n\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tfinalizedCalls.push(finalized);\n\t\tmessages.push(toolResultMessage);\n\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(finalizedCalls),\n\t};\n}\n\nasync function executeToolCallsParallel(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallEntry[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tawait emit({\n\t\t\ttype: \"tool_execution_start\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\targs: toolCall.arguments,\n\t\t});\n\n\t\tconst preparation = await prepareToolCall(currentContext, assistantMessage, toolCall, config, signal);\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tconst finalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t} satisfies FinalizedToolCallOutcome;\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\tfinalizedCalls.push(finalized);\n\t\t\tif (signal?.aborted) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tfinalizedCalls.push(async () => {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tconst finalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\treturn finalized;\n\t\t});\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst orderedFinalizedCalls = await Promise.all(\n\t\tfinalizedCalls.map((entry) => (typeof entry === \"function\" ? entry() : Promise.resolve(entry))),\n\t);\n\tconst messages: ToolResultMessage[] = [];\n\tfor (const finalized of orderedFinalizedCalls) {\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tmessages.push(toolResultMessage);\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(orderedFinalizedCalls),\n\t};\n}\n\ntype PreparedToolCall = {\n\tkind: \"prepared\";\n\ttoolCall: AgentToolCall;\n\ttool: AgentTool<any>;\n\targs: unknown;\n};\n\ntype ImmediateToolCallOutcome = {\n\tkind: \"immediate\";\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype ExecutedToolCallOutcome = {\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype FinalizedToolCallOutcome = {\n\ttoolCall: AgentToolCall;\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype FinalizedToolCallEntry = FinalizedToolCallOutcome | (() => Promise<FinalizedToolCallOutcome>);\n\nfunction shouldTerminateToolBatch(finalizedCalls: FinalizedToolCallOutcome[]): boolean {\n\treturn finalizedCalls.length > 0 && finalizedCalls.every((finalized) => finalized.result.terminate === true);\n}\n\nfunction prepareToolCallArguments(tool: AgentTool<any>, toolCall: AgentToolCall): AgentToolCall {\n\tif (!tool.prepareArguments) {\n\t\treturn toolCall;\n\t}\n\tconst preparedArguments = tool.prepareArguments(toolCall.arguments);\n\tif (preparedArguments === toolCall.arguments) {\n\t\treturn toolCall;\n\t}\n\treturn {\n\t\t...toolCall,\n\t\targuments: preparedArguments as Record<string, any>,\n\t};\n}\n\nasync function prepareToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCall: AgentToolCall,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n): Promise<PreparedToolCall | ImmediateToolCallOutcome> {\n\tconst tool = currentContext.tools?.find((t) => t.name === toolCall.name);\n\tif (!tool) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(`Tool ${toolCall.name} not found`),\n\t\t\tisError: true,\n\t\t};\n\t}\n\n\ttry {\n\t\tconst preparedToolCall = prepareToolCallArguments(tool, toolCall);\n\t\tconst validatedArgs = validateToolArguments(tool, preparedToolCall);\n\t\tif (config.beforeToolCall) {\n\t\t\tconst beforeResult = await config.beforeToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall,\n\t\t\t\t\targs: validatedArgs,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (signal?.aborted) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (beforeResult?.block) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(beforeResult.reason || \"Tool execution was blocked\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tif (signal?.aborted) {\n\t\t\treturn {\n\t\t\t\tkind: \"immediate\",\n\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\tisError: true,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tkind: \"prepared\",\n\t\t\ttoolCall,\n\t\t\ttool,\n\t\t\targs: validatedArgs,\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(error instanceof Error ? error.message : String(error)),\n\t\t\tisError: true,\n\t\t};\n\t}\n}\n\nasync function executePreparedToolCall(\n\tprepared: PreparedToolCall,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallOutcome> {\n\tconst updateEvents: Promise<void>[] = [];\n\n\ttry {\n\t\tconst result = await prepared.tool.execute(\n\t\t\tprepared.toolCall.id,\n\t\t\tprepared.args as never,\n\t\t\tsignal,\n\t\t\t(partialResult) => {\n\t\t\t\tupdateEvents.push(\n\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\temit({\n\t\t\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\t\t\ttoolCallId: prepared.toolCall.id,\n\t\t\t\t\t\t\ttoolName: prepared.toolCall.name,\n\t\t\t\t\t\t\targs: prepared.toolCall.arguments,\n\t\t\t\t\t\t\tpartialResult,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t},\n\t\t);\n\t\tawait Promise.all(updateEvents);\n\t\treturn { result, isError: false };\n\t} catch (error) {\n\t\tawait Promise.all(updateEvents);\n\t\treturn {\n\t\t\tresult: createErrorToolResult(error instanceof Error ? error.message : String(error)),\n\t\t\tisError: true,\n\t\t};\n\t}\n}\n\nasync function finalizeExecutedToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tprepared: PreparedToolCall,\n\texecuted: ExecutedToolCallOutcome,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n): Promise<FinalizedToolCallOutcome> {\n\tlet result = executed.result;\n\tlet isError = executed.isError;\n\n\tif (config.afterToolCall) {\n\t\ttry {\n\t\t\tconst afterResult = await config.afterToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall: prepared.toolCall,\n\t\t\t\t\targs: prepared.args,\n\t\t\t\t\tresult,\n\t\t\t\t\tisError,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (afterResult) {\n\t\t\t\tresult = {\n\t\t\t\t\tcontent: afterResult.content ?? result.content,\n\t\t\t\t\tdetails: afterResult.details ?? result.details,\n\t\t\t\t\tterminate: afterResult.terminate ?? result.terminate,\n\t\t\t\t};\n\t\t\t\tisError = afterResult.isError ?? isError;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tresult = createErrorToolResult(error instanceof Error ? error.message : String(error));\n\t\t\tisError = true;\n\t\t}\n\t}\n\n\treturn {\n\t\ttoolCall: prepared.toolCall,\n\t\tresult,\n\t\tisError,\n\t};\n}\n\nfunction createErrorToolResult(message: string): AgentToolResult<any> {\n\treturn {\n\t\tcontent: [{ type: \"text\", text: message }],\n\t\tdetails: {},\n\t};\n}\n\nasync function emitToolExecutionEnd(finalized: FinalizedToolCallOutcome, emit: AgentEventSink): Promise<void> {\n\tawait emit({\n\t\ttype: \"tool_execution_end\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tresult: finalized.result,\n\t\tisError: finalized.isError,\n\t});\n}\n\nfunction createToolResultMessage(finalized: FinalizedToolCallOutcome): ToolResultMessage {\n\treturn {\n\t\trole: \"toolResult\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tcontent: finalized.result.content,\n\t\tdetails: finalized.result.details,\n\t\tisError: finalized.isError,\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nasync function emitToolResultMessage(toolResultMessage: ToolResultMessage, emit: AgentEventSink): Promise<void> {\n\tawait emit({ type: \"message_start\", message: toolResultMessage });\n\tawait emit({ type: \"message_end\", message: toolResultMessage });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGN,WAAW,EAIX,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EAIZ,QAAQ,EACR,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,SAAS,CACxB,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAiBzC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAwBzC;AAED,wBAAsB,YAAY,CACjC,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAgBzB;AAED,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAiBzB","sourcesContent":["/**\n * Agent loop that works with AgentMessage throughout.\n * Transforms to Message[] only at the LLM call boundary.\n */\n\nimport {\n\ttype AssistantMessage,\n\ttype Context,\n\tEventStream,\n\tstreamSimple,\n\ttype ToolResultMessage,\n\tvalidateToolArguments,\n} from \"@earendil-works/pi-ai\";\nimport type {\n\tAgentContext,\n\tAgentEvent,\n\tAgentLoopConfig,\n\tAgentMessage,\n\tAgentTool,\n\tAgentToolCall,\n\tAgentToolResult,\n\tStreamFn,\n} from \"./types.ts\";\n\nexport type AgentEventSink = (event: AgentEvent) => Promise<void> | void;\n\n/**\n * Start an agent loop with a new prompt message.\n * The prompt is added to the context and events are emitted for it.\n */\nexport function agentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoop(\n\t\tprompts,\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t).then((messages) => {\n\t\tstream.end(messages);\n\t});\n\n\treturn stream;\n}\n\n/**\n * Continue an agent loop from the current context without adding a new message.\n * Used for retries - context already has user message or tool results.\n *\n * **Important:** The last message in context must convert to a `user` or `toolResult` message\n * via `convertToLlm`. If it doesn't, the LLM provider will reject the request.\n * This cannot be validated here since `convertToLlm` is only called once per turn.\n */\nexport function agentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoopContinue(\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t).then((messages) => {\n\t\tstream.end(messages);\n\t});\n\n\treturn stream;\n}\n\nexport async function runAgentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tconst newMessages: AgentMessage[] = [...prompts];\n\tconst currentContext: AgentContext = {\n\t\t...context,\n\t\tmessages: [...context.messages, ...prompts],\n\t};\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\tfor (const prompt of prompts) {\n\t\tawait emit({ type: \"message_start\", message: prompt });\n\t\tawait emit({ type: \"message_end\", message: prompt });\n\t}\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nexport async function runAgentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst newMessages: AgentMessage[] = [];\n\tconst currentContext: AgentContext = { ...context };\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nfunction createAgentStream(): EventStream<AgentEvent, AgentMessage[]> {\n\treturn new EventStream<AgentEvent, AgentMessage[]>(\n\t\t(event: AgentEvent) => event.type === \"agent_end\",\n\t\t(event: AgentEvent) => (event.type === \"agent_end\" ? event.messages : []),\n\t);\n}\n\n/**\n * Main loop logic shared by agentLoop and agentLoopContinue.\n */\nasync function runLoop(\n\tinitialContext: AgentContext,\n\tnewMessages: AgentMessage[],\n\tinitialConfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<void> {\n\tlet currentContext = initialContext;\n\tlet config = initialConfig;\n\tlet firstTurn = true;\n\t// Check for steering messages at start (user may have typed while waiting)\n\tlet pendingMessages: AgentMessage[] = (await config.getSteeringMessages?.()) || [];\n\n\t// Outer loop: continues when queued follow-up messages arrive after agent would stop\n\twhile (true) {\n\t\tlet hasMoreToolCalls = true;\n\n\t\t// Inner loop: process tool calls and steering messages\n\t\twhile (hasMoreToolCalls || pendingMessages.length > 0) {\n\t\t\tif (!firstTurn) {\n\t\t\t\tawait emit({ type: \"turn_start\" });\n\t\t\t} else {\n\t\t\t\tfirstTurn = false;\n\t\t\t}\n\n\t\t\t// Process pending messages (inject before next assistant response)\n\t\t\tif (pendingMessages.length > 0) {\n\t\t\t\tfor (const message of pendingMessages) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message });\n\t\t\t\t\tawait emit({ type: \"message_end\", message });\n\t\t\t\t\tcurrentContext.messages.push(message);\n\t\t\t\t\tnewMessages.push(message);\n\t\t\t\t}\n\t\t\t\tpendingMessages = [];\n\t\t\t}\n\n\t\t\t// Stream assistant response\n\t\t\tconst message = await streamAssistantResponse(currentContext, config, signal, emit, streamFn);\n\t\t\tnewMessages.push(message);\n\n\t\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\t\t\tawait emit({ type: \"turn_end\", message, toolResults: [] });\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Check for tool calls\n\t\t\tconst toolCalls = message.content.filter((c) => c.type === \"toolCall\");\n\n\t\t\tconst toolResults: ToolResultMessage[] = [];\n\t\t\thasMoreToolCalls = false;\n\t\t\tif (toolCalls.length > 0) {\n\t\t\t\tconst executedToolBatch = await executeToolCalls(currentContext, message, config, signal, emit);\n\t\t\t\ttoolResults.push(...executedToolBatch.messages);\n\t\t\t\thasMoreToolCalls = !executedToolBatch.terminate;\n\n\t\t\t\tfor (const result of toolResults) {\n\t\t\t\t\tcurrentContext.messages.push(result);\n\t\t\t\t\tnewMessages.push(result);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait emit({ type: \"turn_end\", message, toolResults });\n\n\t\t\tconst nextTurnContext = {\n\t\t\t\tmessage,\n\t\t\t\ttoolResults,\n\t\t\t\tcontext: currentContext,\n\t\t\t\tnewMessages,\n\t\t\t};\n\t\t\tconst nextTurnSnapshot = await config.prepareNextTurn?.(nextTurnContext);\n\t\t\tif (nextTurnSnapshot) {\n\t\t\t\tcurrentContext = nextTurnSnapshot.context ?? currentContext;\n\t\t\t\tconfig = {\n\t\t\t\t\t...config,\n\t\t\t\t\tmodel: nextTurnSnapshot.model ?? config.model,\n\t\t\t\t\treasoning:\n\t\t\t\t\t\tnextTurnSnapshot.thinkingLevel === undefined\n\t\t\t\t\t\t\t? config.reasoning\n\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel === \"off\"\n\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tawait config.shouldStopAfterTurn?.({\n\t\t\t\t\tmessage,\n\t\t\t\t\ttoolResults,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t\tnewMessages,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpendingMessages = (await config.getSteeringMessages?.()) || [];\n\t\t}\n\n\t\t// Agent would stop here. Check for follow-up messages.\n\t\tconst followUpMessages = (await config.getFollowUpMessages?.()) || [];\n\t\tif (followUpMessages.length > 0) {\n\t\t\t// Set as pending so inner loop processes them\n\t\t\tpendingMessages = followUpMessages;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// No more messages, exit\n\t\tbreak;\n\t}\n\n\tawait emit({ type: \"agent_end\", messages: newMessages });\n}\n\n/**\n * Stream an assistant response from the LLM.\n * This is where AgentMessage[] gets transformed to Message[] for the LLM.\n */\nasync function streamAssistantResponse(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<AssistantMessage> {\n\t// Apply context transform if configured (AgentMessage[] → AgentMessage[])\n\tlet messages = context.messages;\n\tif (config.transformContext) {\n\t\tmessages = await config.transformContext(messages, signal);\n\t}\n\n\t// Convert to LLM-compatible messages (AgentMessage[] → Message[])\n\tconst llmMessages = await config.convertToLlm(messages);\n\n\t// Build LLM context\n\tconst llmContext: Context = {\n\t\tsystemPrompt: context.systemPrompt,\n\t\tmessages: llmMessages,\n\t\ttools: context.tools,\n\t};\n\n\tconst streamFunction = streamFn || streamSimple;\n\n\t// Resolve API key (important for expiring tokens)\n\tconst resolvedApiKey =\n\t\t(config.getApiKey ? await config.getApiKey(config.model.provider) : undefined) || config.apiKey;\n\n\tconst response = await streamFunction(config.model, llmContext, {\n\t\t...config,\n\t\tapiKey: resolvedApiKey,\n\t\tsignal,\n\t});\n\n\tlet partialMessage: AssistantMessage | null = null;\n\tlet addedPartial = false;\n\n\tfor await (const event of response) {\n\t\tswitch (event.type) {\n\t\t\tcase \"start\":\n\t\t\t\tpartialMessage = event.partial;\n\t\t\t\tcontext.messages.push(partialMessage);\n\t\t\t\taddedPartial = true;\n\t\t\t\tawait emit({ type: \"message_start\", message: { ...partialMessage } });\n\t\t\t\tbreak;\n\n\t\t\tcase \"text_start\":\n\t\t\tcase \"text_delta\":\n\t\t\tcase \"text_end\":\n\t\t\tcase \"thinking_start\":\n\t\t\tcase \"thinking_delta\":\n\t\t\tcase \"thinking_end\":\n\t\t\tcase \"toolcall_start\":\n\t\t\tcase \"toolcall_delta\":\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tif (partialMessage) {\n\t\t\t\t\tpartialMessage = event.partial;\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = partialMessage;\n\t\t\t\t\tawait emit({\n\t\t\t\t\t\ttype: \"message_update\",\n\t\t\t\t\t\tassistantMessageEvent: event,\n\t\t\t\t\t\tmessage: { ...partialMessage },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"done\":\n\t\t\tcase \"error\": {\n\t\t\t\tconst finalMessage = await response.result();\n\t\t\t\tif (addedPartial) {\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t\t\t\t} else {\n\t\t\t\t\tcontext.messages.push(finalMessage);\n\t\t\t\t}\n\t\t\t\tif (!addedPartial) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t\t\t\t}\n\t\t\t\tawait emit({ type: \"message_end\", message: finalMessage });\n\t\t\t\treturn finalMessage;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst finalMessage = await response.result();\n\tif (addedPartial) {\n\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t} else {\n\t\tcontext.messages.push(finalMessage);\n\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t}\n\tawait emit({ type: \"message_end\", message: finalMessage });\n\treturn finalMessage;\n}\n\n/**\n * Execute tool calls from an assistant message.\n */\nasync function executeToolCalls(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst toolCalls = assistantMessage.content.filter((c) => c.type === \"toolCall\");\n\tconst hasSequentialToolCall = toolCalls.some(\n\t\t(tc) => currentContext.tools?.find((t) => t.name === tc.name)?.executionMode === \"sequential\",\n\t);\n\tif (config.toolExecution === \"sequential\" || hasSequentialToolCall) {\n\t\treturn executeToolCallsSequential(currentContext, assistantMessage, toolCalls, config, signal, emit);\n\t}\n\treturn executeToolCallsParallel(currentContext, assistantMessage, toolCalls, config, signal, emit);\n}\n\ntype ExecutedToolCallBatch = {\n\tmessages: ToolResultMessage[];\n\tterminate: boolean;\n};\n\nasync function executeToolCallsSequential(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallOutcome[] = [];\n\tconst messages: ToolResultMessage[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tawait emit({\n\t\t\ttype: \"tool_execution_start\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\targs: toolCall.arguments,\n\t\t});\n\n\t\tconst preparation = await prepareToolCall(currentContext, assistantMessage, toolCall, config, signal);\n\t\tlet finalized: FinalizedToolCallOutcome;\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tfinalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t};\n\t\t} else {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tfinalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t}\n\n\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tfinalizedCalls.push(finalized);\n\t\tmessages.push(toolResultMessage);\n\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(finalizedCalls),\n\t};\n}\n\nasync function executeToolCallsParallel(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallEntry[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tawait emit({\n\t\t\ttype: \"tool_execution_start\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\targs: toolCall.arguments,\n\t\t});\n\n\t\tconst preparation = await prepareToolCall(currentContext, assistantMessage, toolCall, config, signal);\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tconst finalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t} satisfies FinalizedToolCallOutcome;\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\tfinalizedCalls.push(finalized);\n\t\t\tif (signal?.aborted) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tfinalizedCalls.push(async () => {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tconst finalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\treturn finalized;\n\t\t});\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst orderedFinalizedCalls = await Promise.all(\n\t\tfinalizedCalls.map((entry) => (typeof entry === \"function\" ? entry() : Promise.resolve(entry))),\n\t);\n\tconst messages: ToolResultMessage[] = [];\n\tfor (const finalized of orderedFinalizedCalls) {\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tmessages.push(toolResultMessage);\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(orderedFinalizedCalls),\n\t};\n}\n\ntype PreparedToolCall = {\n\tkind: \"prepared\";\n\ttoolCall: AgentToolCall;\n\ttool: AgentTool<any>;\n\targs: unknown;\n};\n\ntype ImmediateToolCallOutcome = {\n\tkind: \"immediate\";\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype ExecutedToolCallOutcome = {\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype FinalizedToolCallOutcome = {\n\ttoolCall: AgentToolCall;\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype FinalizedToolCallEntry = FinalizedToolCallOutcome | (() => Promise<FinalizedToolCallOutcome>);\n\nfunction shouldTerminateToolBatch(finalizedCalls: FinalizedToolCallOutcome[]): boolean {\n\treturn finalizedCalls.length > 0 && finalizedCalls.every((finalized) => finalized.result.terminate === true);\n}\n\nfunction prepareToolCallArguments(tool: AgentTool<any>, toolCall: AgentToolCall): AgentToolCall {\n\tif (!tool.prepareArguments) {\n\t\treturn toolCall;\n\t}\n\tconst preparedArguments = tool.prepareArguments(toolCall.arguments);\n\tif (preparedArguments === toolCall.arguments) {\n\t\treturn toolCall;\n\t}\n\treturn {\n\t\t...toolCall,\n\t\targuments: preparedArguments as Record<string, any>,\n\t};\n}\n\nasync function prepareToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCall: AgentToolCall,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n): Promise<PreparedToolCall | ImmediateToolCallOutcome> {\n\tconst tool = currentContext.tools?.find((t) => t.name === toolCall.name);\n\tif (!tool) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(`Tool ${toolCall.name} not found`),\n\t\t\tisError: true,\n\t\t};\n\t}\n\n\ttry {\n\t\tconst preparedToolCall = prepareToolCallArguments(tool, toolCall);\n\t\tconst validatedArgs = validateToolArguments(tool, preparedToolCall);\n\t\tif (config.beforeToolCall) {\n\t\t\tconst beforeResult = await config.beforeToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall,\n\t\t\t\t\targs: validatedArgs,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (signal?.aborted) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (beforeResult?.block) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(beforeResult.reason || \"Tool execution was blocked\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tif (signal?.aborted) {\n\t\t\treturn {\n\t\t\t\tkind: \"immediate\",\n\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\tisError: true,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tkind: \"prepared\",\n\t\t\ttoolCall,\n\t\t\ttool,\n\t\t\targs: validatedArgs,\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(error instanceof Error ? error.message : String(error)),\n\t\t\tisError: true,\n\t\t};\n\t}\n}\n\nasync function executePreparedToolCall(\n\tprepared: PreparedToolCall,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallOutcome> {\n\tconst updateEvents: Promise<void>[] = [];\n\tlet acceptingUpdates = true;\n\n\ttry {\n\t\tconst result = await prepared.tool.execute(\n\t\t\tprepared.toolCall.id,\n\t\t\tprepared.args as never,\n\t\t\tsignal,\n\t\t\t(partialResult) => {\n\t\t\t\tif (!acceptingUpdates) return;\n\t\t\t\tupdateEvents.push(\n\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\temit({\n\t\t\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\t\t\ttoolCallId: prepared.toolCall.id,\n\t\t\t\t\t\t\ttoolName: prepared.toolCall.name,\n\t\t\t\t\t\t\targs: prepared.toolCall.arguments,\n\t\t\t\t\t\t\tpartialResult,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t},\n\t\t);\n\t\tacceptingUpdates = false;\n\t\tawait Promise.all(updateEvents);\n\t\treturn { result, isError: false };\n\t} catch (error) {\n\t\tacceptingUpdates = false;\n\t\tawait Promise.all(updateEvents);\n\t\treturn {\n\t\t\tresult: createErrorToolResult(error instanceof Error ? error.message : String(error)),\n\t\t\tisError: true,\n\t\t};\n\t} finally {\n\t\tacceptingUpdates = false;\n\t}\n}\n\nasync function finalizeExecutedToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tprepared: PreparedToolCall,\n\texecuted: ExecutedToolCallOutcome,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n): Promise<FinalizedToolCallOutcome> {\n\tlet result = executed.result;\n\tlet isError = executed.isError;\n\n\tif (config.afterToolCall) {\n\t\ttry {\n\t\t\tconst afterResult = await config.afterToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall: prepared.toolCall,\n\t\t\t\t\targs: prepared.args,\n\t\t\t\t\tresult,\n\t\t\t\t\tisError,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (afterResult) {\n\t\t\t\tresult = {\n\t\t\t\t\tcontent: afterResult.content ?? result.content,\n\t\t\t\t\tdetails: afterResult.details ?? result.details,\n\t\t\t\t\tterminate: afterResult.terminate ?? result.terminate,\n\t\t\t\t};\n\t\t\t\tisError = afterResult.isError ?? isError;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tresult = createErrorToolResult(error instanceof Error ? error.message : String(error));\n\t\t\tisError = true;\n\t\t}\n\t}\n\n\treturn {\n\t\ttoolCall: prepared.toolCall,\n\t\tresult,\n\t\tisError,\n\t};\n}\n\nfunction createErrorToolResult(message: string): AgentToolResult<any> {\n\treturn {\n\t\tcontent: [{ type: \"text\", text: message }],\n\t\tdetails: {},\n\t};\n}\n\nasync function emitToolExecutionEnd(finalized: FinalizedToolCallOutcome, emit: AgentEventSink): Promise<void> {\n\tawait emit({\n\t\ttype: \"tool_execution_end\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tresult: finalized.result,\n\t\tisError: finalized.isError,\n\t});\n}\n\nfunction createToolResultMessage(finalized: FinalizedToolCallOutcome): ToolResultMessage {\n\treturn {\n\t\trole: \"toolResult\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tcontent: finalized.result.content,\n\t\tdetails: finalized.result.details,\n\t\tisError: finalized.isError,\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nasync function emitToolResultMessage(toolResultMessage: ToolResultMessage, emit: AgentEventSink): Promise<void> {\n\tawait emit({ type: \"message_start\", message: toolResultMessage });\n\tawait emit({ type: \"message_end\", message: toolResultMessage });\n}\n"]}
|
|
@@ -415,8 +415,11 @@ async function prepareToolCall(currentContext, assistantMessage, toolCall, confi
|
|
|
415
415
|
}
|
|
416
416
|
async function executePreparedToolCall(prepared, signal, emit) {
|
|
417
417
|
const updateEvents = [];
|
|
418
|
+
let acceptingUpdates = true;
|
|
418
419
|
try {
|
|
419
420
|
const result = await prepared.tool.execute(prepared.toolCall.id, prepared.args, signal, (partialResult) => {
|
|
421
|
+
if (!acceptingUpdates)
|
|
422
|
+
return;
|
|
420
423
|
updateEvents.push(Promise.resolve(emit({
|
|
421
424
|
type: "tool_execution_update",
|
|
422
425
|
toolCallId: prepared.toolCall.id,
|
|
@@ -425,16 +428,21 @@ async function executePreparedToolCall(prepared, signal, emit) {
|
|
|
425
428
|
partialResult,
|
|
426
429
|
})));
|
|
427
430
|
});
|
|
431
|
+
acceptingUpdates = false;
|
|
428
432
|
await Promise.all(updateEvents);
|
|
429
433
|
return { result, isError: false };
|
|
430
434
|
}
|
|
431
435
|
catch (error) {
|
|
436
|
+
acceptingUpdates = false;
|
|
432
437
|
await Promise.all(updateEvents);
|
|
433
438
|
return {
|
|
434
439
|
result: createErrorToolResult(error instanceof Error ? error.message : String(error)),
|
|
435
440
|
isError: true,
|
|
436
441
|
};
|
|
437
442
|
}
|
|
443
|
+
finally {
|
|
444
|
+
acceptingUpdates = false;
|
|
445
|
+
}
|
|
438
446
|
}
|
|
439
447
|
async function finalizeExecutedToolCall(currentContext, assistantMessage, prepared, executed, config, signal) {
|
|
440
448
|
let result = executed.result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-loop.js","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Agent loop that works with AgentMessage throughout.\n * Transforms to Message[] only at the LLM call boundary.\n */\n\nimport {\n\ttype AssistantMessage,\n\ttype Context,\n\tEventStream,\n\tstreamSimple,\n\ttype ToolResultMessage,\n\tvalidateToolArguments,\n} from \"@earendil-works/pi-ai\";\nimport type {\n\tAgentContext,\n\tAgentEvent,\n\tAgentLoopConfig,\n\tAgentMessage,\n\tAgentTool,\n\tAgentToolCall,\n\tAgentToolResult,\n\tStreamFn,\n} from \"./types.ts\";\n\nexport type AgentEventSink = (event: AgentEvent) => Promise<void> | void;\n\n/**\n * Start an agent loop with a new prompt message.\n * The prompt is added to the context and events are emitted for it.\n */\nexport function agentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoop(\n\t\tprompts,\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t).then((messages) => {\n\t\tstream.end(messages);\n\t});\n\n\treturn stream;\n}\n\n/**\n * Continue an agent loop from the current context without adding a new message.\n * Used for retries - context already has user message or tool results.\n *\n * **Important:** The last message in context must convert to a `user` or `toolResult` message\n * via `convertToLlm`. If it doesn't, the LLM provider will reject the request.\n * This cannot be validated here since `convertToLlm` is only called once per turn.\n */\nexport function agentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoopContinue(\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t).then((messages) => {\n\t\tstream.end(messages);\n\t});\n\n\treturn stream;\n}\n\nexport async function runAgentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tconst newMessages: AgentMessage[] = [...prompts];\n\tconst currentContext: AgentContext = {\n\t\t...context,\n\t\tmessages: [...context.messages, ...prompts],\n\t};\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\tfor (const prompt of prompts) {\n\t\tawait emit({ type: \"message_start\", message: prompt });\n\t\tawait emit({ type: \"message_end\", message: prompt });\n\t}\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nexport async function runAgentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst newMessages: AgentMessage[] = [];\n\tconst currentContext: AgentContext = { ...context };\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nfunction createAgentStream(): EventStream<AgentEvent, AgentMessage[]> {\n\treturn new EventStream<AgentEvent, AgentMessage[]>(\n\t\t(event: AgentEvent) => event.type === \"agent_end\",\n\t\t(event: AgentEvent) => (event.type === \"agent_end\" ? event.messages : []),\n\t);\n}\n\n/**\n * Main loop logic shared by agentLoop and agentLoopContinue.\n */\nasync function runLoop(\n\tinitialContext: AgentContext,\n\tnewMessages: AgentMessage[],\n\tinitialConfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<void> {\n\tlet currentContext = initialContext;\n\tlet config = initialConfig;\n\tlet firstTurn = true;\n\t// Check for steering messages at start (user may have typed while waiting)\n\tlet pendingMessages: AgentMessage[] = (await config.getSteeringMessages?.()) || [];\n\n\t// Outer loop: continues when queued follow-up messages arrive after agent would stop\n\twhile (true) {\n\t\tlet hasMoreToolCalls = true;\n\n\t\t// Inner loop: process tool calls and steering messages\n\t\twhile (hasMoreToolCalls || pendingMessages.length > 0) {\n\t\t\tif (!firstTurn) {\n\t\t\t\tawait emit({ type: \"turn_start\" });\n\t\t\t} else {\n\t\t\t\tfirstTurn = false;\n\t\t\t}\n\n\t\t\t// Process pending messages (inject before next assistant response)\n\t\t\tif (pendingMessages.length > 0) {\n\t\t\t\tfor (const message of pendingMessages) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message });\n\t\t\t\t\tawait emit({ type: \"message_end\", message });\n\t\t\t\t\tcurrentContext.messages.push(message);\n\t\t\t\t\tnewMessages.push(message);\n\t\t\t\t}\n\t\t\t\tpendingMessages = [];\n\t\t\t}\n\n\t\t\t// Stream assistant response\n\t\t\tconst message = await streamAssistantResponse(currentContext, config, signal, emit, streamFn);\n\t\t\tnewMessages.push(message);\n\n\t\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\t\t\tawait emit({ type: \"turn_end\", message, toolResults: [] });\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Check for tool calls\n\t\t\tconst toolCalls = message.content.filter((c) => c.type === \"toolCall\");\n\n\t\t\tconst toolResults: ToolResultMessage[] = [];\n\t\t\thasMoreToolCalls = false;\n\t\t\tif (toolCalls.length > 0) {\n\t\t\t\tconst executedToolBatch = await executeToolCalls(currentContext, message, config, signal, emit);\n\t\t\t\ttoolResults.push(...executedToolBatch.messages);\n\t\t\t\thasMoreToolCalls = !executedToolBatch.terminate;\n\n\t\t\t\tfor (const result of toolResults) {\n\t\t\t\t\tcurrentContext.messages.push(result);\n\t\t\t\t\tnewMessages.push(result);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait emit({ type: \"turn_end\", message, toolResults });\n\n\t\t\tconst nextTurnContext = {\n\t\t\t\tmessage,\n\t\t\t\ttoolResults,\n\t\t\t\tcontext: currentContext,\n\t\t\t\tnewMessages,\n\t\t\t};\n\t\t\tconst nextTurnSnapshot = await config.prepareNextTurn?.(nextTurnContext);\n\t\t\tif (nextTurnSnapshot) {\n\t\t\t\tcurrentContext = nextTurnSnapshot.context ?? currentContext;\n\t\t\t\tconfig = {\n\t\t\t\t\t...config,\n\t\t\t\t\tmodel: nextTurnSnapshot.model ?? config.model,\n\t\t\t\t\treasoning:\n\t\t\t\t\t\tnextTurnSnapshot.thinkingLevel === undefined\n\t\t\t\t\t\t\t? config.reasoning\n\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel === \"off\"\n\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tawait config.shouldStopAfterTurn?.({\n\t\t\t\t\tmessage,\n\t\t\t\t\ttoolResults,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t\tnewMessages,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpendingMessages = (await config.getSteeringMessages?.()) || [];\n\t\t}\n\n\t\t// Agent would stop here. Check for follow-up messages.\n\t\tconst followUpMessages = (await config.getFollowUpMessages?.()) || [];\n\t\tif (followUpMessages.length > 0) {\n\t\t\t// Set as pending so inner loop processes them\n\t\t\tpendingMessages = followUpMessages;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// No more messages, exit\n\t\tbreak;\n\t}\n\n\tawait emit({ type: \"agent_end\", messages: newMessages });\n}\n\n/**\n * Stream an assistant response from the LLM.\n * This is where AgentMessage[] gets transformed to Message[] for the LLM.\n */\nasync function streamAssistantResponse(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<AssistantMessage> {\n\t// Apply context transform if configured (AgentMessage[] → AgentMessage[])\n\tlet messages = context.messages;\n\tif (config.transformContext) {\n\t\tmessages = await config.transformContext(messages, signal);\n\t}\n\n\t// Convert to LLM-compatible messages (AgentMessage[] → Message[])\n\tconst llmMessages = await config.convertToLlm(messages);\n\n\t// Build LLM context\n\tconst llmContext: Context = {\n\t\tsystemPrompt: context.systemPrompt,\n\t\tmessages: llmMessages,\n\t\ttools: context.tools,\n\t};\n\n\tconst streamFunction = streamFn || streamSimple;\n\n\t// Resolve API key (important for expiring tokens)\n\tconst resolvedApiKey =\n\t\t(config.getApiKey ? await config.getApiKey(config.model.provider) : undefined) || config.apiKey;\n\n\tconst response = await streamFunction(config.model, llmContext, {\n\t\t...config,\n\t\tapiKey: resolvedApiKey,\n\t\tsignal,\n\t});\n\n\tlet partialMessage: AssistantMessage | null = null;\n\tlet addedPartial = false;\n\n\tfor await (const event of response) {\n\t\tswitch (event.type) {\n\t\t\tcase \"start\":\n\t\t\t\tpartialMessage = event.partial;\n\t\t\t\tcontext.messages.push(partialMessage);\n\t\t\t\taddedPartial = true;\n\t\t\t\tawait emit({ type: \"message_start\", message: { ...partialMessage } });\n\t\t\t\tbreak;\n\n\t\t\tcase \"text_start\":\n\t\t\tcase \"text_delta\":\n\t\t\tcase \"text_end\":\n\t\t\tcase \"thinking_start\":\n\t\t\tcase \"thinking_delta\":\n\t\t\tcase \"thinking_end\":\n\t\t\tcase \"toolcall_start\":\n\t\t\tcase \"toolcall_delta\":\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tif (partialMessage) {\n\t\t\t\t\tpartialMessage = event.partial;\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = partialMessage;\n\t\t\t\t\tawait emit({\n\t\t\t\t\t\ttype: \"message_update\",\n\t\t\t\t\t\tassistantMessageEvent: event,\n\t\t\t\t\t\tmessage: { ...partialMessage },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"done\":\n\t\t\tcase \"error\": {\n\t\t\t\tconst finalMessage = await response.result();\n\t\t\t\tif (addedPartial) {\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t\t\t\t} else {\n\t\t\t\t\tcontext.messages.push(finalMessage);\n\t\t\t\t}\n\t\t\t\tif (!addedPartial) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t\t\t\t}\n\t\t\t\tawait emit({ type: \"message_end\", message: finalMessage });\n\t\t\t\treturn finalMessage;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst finalMessage = await response.result();\n\tif (addedPartial) {\n\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t} else {\n\t\tcontext.messages.push(finalMessage);\n\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t}\n\tawait emit({ type: \"message_end\", message: finalMessage });\n\treturn finalMessage;\n}\n\n/**\n * Execute tool calls from an assistant message.\n */\nasync function executeToolCalls(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst toolCalls = assistantMessage.content.filter((c) => c.type === \"toolCall\");\n\tconst hasSequentialToolCall = toolCalls.some(\n\t\t(tc) => currentContext.tools?.find((t) => t.name === tc.name)?.executionMode === \"sequential\",\n\t);\n\tif (config.toolExecution === \"sequential\" || hasSequentialToolCall) {\n\t\treturn executeToolCallsSequential(currentContext, assistantMessage, toolCalls, config, signal, emit);\n\t}\n\treturn executeToolCallsParallel(currentContext, assistantMessage, toolCalls, config, signal, emit);\n}\n\ntype ExecutedToolCallBatch = {\n\tmessages: ToolResultMessage[];\n\tterminate: boolean;\n};\n\nasync function executeToolCallsSequential(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallOutcome[] = [];\n\tconst messages: ToolResultMessage[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tawait emit({\n\t\t\ttype: \"tool_execution_start\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\targs: toolCall.arguments,\n\t\t});\n\n\t\tconst preparation = await prepareToolCall(currentContext, assistantMessage, toolCall, config, signal);\n\t\tlet finalized: FinalizedToolCallOutcome;\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tfinalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t};\n\t\t} else {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tfinalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t}\n\n\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tfinalizedCalls.push(finalized);\n\t\tmessages.push(toolResultMessage);\n\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(finalizedCalls),\n\t};\n}\n\nasync function executeToolCallsParallel(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallEntry[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tawait emit({\n\t\t\ttype: \"tool_execution_start\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\targs: toolCall.arguments,\n\t\t});\n\n\t\tconst preparation = await prepareToolCall(currentContext, assistantMessage, toolCall, config, signal);\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tconst finalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t} satisfies FinalizedToolCallOutcome;\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\tfinalizedCalls.push(finalized);\n\t\t\tif (signal?.aborted) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tfinalizedCalls.push(async () => {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tconst finalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\treturn finalized;\n\t\t});\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst orderedFinalizedCalls = await Promise.all(\n\t\tfinalizedCalls.map((entry) => (typeof entry === \"function\" ? entry() : Promise.resolve(entry))),\n\t);\n\tconst messages: ToolResultMessage[] = [];\n\tfor (const finalized of orderedFinalizedCalls) {\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tmessages.push(toolResultMessage);\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(orderedFinalizedCalls),\n\t};\n}\n\ntype PreparedToolCall = {\n\tkind: \"prepared\";\n\ttoolCall: AgentToolCall;\n\ttool: AgentTool<any>;\n\targs: unknown;\n};\n\ntype ImmediateToolCallOutcome = {\n\tkind: \"immediate\";\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype ExecutedToolCallOutcome = {\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype FinalizedToolCallOutcome = {\n\ttoolCall: AgentToolCall;\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype FinalizedToolCallEntry = FinalizedToolCallOutcome | (() => Promise<FinalizedToolCallOutcome>);\n\nfunction shouldTerminateToolBatch(finalizedCalls: FinalizedToolCallOutcome[]): boolean {\n\treturn finalizedCalls.length > 0 && finalizedCalls.every((finalized) => finalized.result.terminate === true);\n}\n\nfunction prepareToolCallArguments(tool: AgentTool<any>, toolCall: AgentToolCall): AgentToolCall {\n\tif (!tool.prepareArguments) {\n\t\treturn toolCall;\n\t}\n\tconst preparedArguments = tool.prepareArguments(toolCall.arguments);\n\tif (preparedArguments === toolCall.arguments) {\n\t\treturn toolCall;\n\t}\n\treturn {\n\t\t...toolCall,\n\t\targuments: preparedArguments as Record<string, any>,\n\t};\n}\n\nasync function prepareToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCall: AgentToolCall,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n): Promise<PreparedToolCall | ImmediateToolCallOutcome> {\n\tconst tool = currentContext.tools?.find((t) => t.name === toolCall.name);\n\tif (!tool) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(`Tool ${toolCall.name} not found`),\n\t\t\tisError: true,\n\t\t};\n\t}\n\n\ttry {\n\t\tconst preparedToolCall = prepareToolCallArguments(tool, toolCall);\n\t\tconst validatedArgs = validateToolArguments(tool, preparedToolCall);\n\t\tif (config.beforeToolCall) {\n\t\t\tconst beforeResult = await config.beforeToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall,\n\t\t\t\t\targs: validatedArgs,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (signal?.aborted) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (beforeResult?.block) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(beforeResult.reason || \"Tool execution was blocked\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tif (signal?.aborted) {\n\t\t\treturn {\n\t\t\t\tkind: \"immediate\",\n\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\tisError: true,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tkind: \"prepared\",\n\t\t\ttoolCall,\n\t\t\ttool,\n\t\t\targs: validatedArgs,\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(error instanceof Error ? error.message : String(error)),\n\t\t\tisError: true,\n\t\t};\n\t}\n}\n\nasync function executePreparedToolCall(\n\tprepared: PreparedToolCall,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallOutcome> {\n\tconst updateEvents: Promise<void>[] = [];\n\n\ttry {\n\t\tconst result = await prepared.tool.execute(\n\t\t\tprepared.toolCall.id,\n\t\t\tprepared.args as never,\n\t\t\tsignal,\n\t\t\t(partialResult) => {\n\t\t\t\tupdateEvents.push(\n\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\temit({\n\t\t\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\t\t\ttoolCallId: prepared.toolCall.id,\n\t\t\t\t\t\t\ttoolName: prepared.toolCall.name,\n\t\t\t\t\t\t\targs: prepared.toolCall.arguments,\n\t\t\t\t\t\t\tpartialResult,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t},\n\t\t);\n\t\tawait Promise.all(updateEvents);\n\t\treturn { result, isError: false };\n\t} catch (error) {\n\t\tawait Promise.all(updateEvents);\n\t\treturn {\n\t\t\tresult: createErrorToolResult(error instanceof Error ? error.message : String(error)),\n\t\t\tisError: true,\n\t\t};\n\t}\n}\n\nasync function finalizeExecutedToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tprepared: PreparedToolCall,\n\texecuted: ExecutedToolCallOutcome,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n): Promise<FinalizedToolCallOutcome> {\n\tlet result = executed.result;\n\tlet isError = executed.isError;\n\n\tif (config.afterToolCall) {\n\t\ttry {\n\t\t\tconst afterResult = await config.afterToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall: prepared.toolCall,\n\t\t\t\t\targs: prepared.args,\n\t\t\t\t\tresult,\n\t\t\t\t\tisError,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (afterResult) {\n\t\t\t\tresult = {\n\t\t\t\t\tcontent: afterResult.content ?? result.content,\n\t\t\t\t\tdetails: afterResult.details ?? result.details,\n\t\t\t\t\tterminate: afterResult.terminate ?? result.terminate,\n\t\t\t\t};\n\t\t\t\tisError = afterResult.isError ?? isError;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tresult = createErrorToolResult(error instanceof Error ? error.message : String(error));\n\t\t\tisError = true;\n\t\t}\n\t}\n\n\treturn {\n\t\ttoolCall: prepared.toolCall,\n\t\tresult,\n\t\tisError,\n\t};\n}\n\nfunction createErrorToolResult(message: string): AgentToolResult<any> {\n\treturn {\n\t\tcontent: [{ type: \"text\", text: message }],\n\t\tdetails: {},\n\t};\n}\n\nasync function emitToolExecutionEnd(finalized: FinalizedToolCallOutcome, emit: AgentEventSink): Promise<void> {\n\tawait emit({\n\t\ttype: \"tool_execution_end\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tresult: finalized.result,\n\t\tisError: finalized.isError,\n\t});\n}\n\nfunction createToolResultMessage(finalized: FinalizedToolCallOutcome): ToolResultMessage {\n\treturn {\n\t\trole: \"toolResult\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tcontent: finalized.result.content,\n\t\tdetails: finalized.result.details,\n\t\tisError: finalized.isError,\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nasync function emitToolResultMessage(toolResultMessage: ToolResultMessage, emit: AgentEventSink): Promise<void> {\n\tawait emit({ type: \"message_start\", message: toolResultMessage });\n\tawait emit({ type: \"message_end\", message: toolResultMessage });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-loop.js","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Agent loop that works with AgentMessage throughout.\n * Transforms to Message[] only at the LLM call boundary.\n */\n\nimport {\n\ttype AssistantMessage,\n\ttype Context,\n\tEventStream,\n\tstreamSimple,\n\ttype ToolResultMessage,\n\tvalidateToolArguments,\n} from \"@earendil-works/pi-ai\";\nimport type {\n\tAgentContext,\n\tAgentEvent,\n\tAgentLoopConfig,\n\tAgentMessage,\n\tAgentTool,\n\tAgentToolCall,\n\tAgentToolResult,\n\tStreamFn,\n} from \"./types.ts\";\n\nexport type AgentEventSink = (event: AgentEvent) => Promise<void> | void;\n\n/**\n * Start an agent loop with a new prompt message.\n * The prompt is added to the context and events are emitted for it.\n */\nexport function agentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoop(\n\t\tprompts,\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t).then((messages) => {\n\t\tstream.end(messages);\n\t});\n\n\treturn stream;\n}\n\n/**\n * Continue an agent loop from the current context without adding a new message.\n * Used for retries - context already has user message or tool results.\n *\n * **Important:** The last message in context must convert to a `user` or `toolResult` message\n * via `convertToLlm`. If it doesn't, the LLM provider will reject the request.\n * This cannot be validated here since `convertToLlm` is only called once per turn.\n */\nexport function agentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoopContinue(\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t).then((messages) => {\n\t\tstream.end(messages);\n\t});\n\n\treturn stream;\n}\n\nexport async function runAgentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tconst newMessages: AgentMessage[] = [...prompts];\n\tconst currentContext: AgentContext = {\n\t\t...context,\n\t\tmessages: [...context.messages, ...prompts],\n\t};\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\tfor (const prompt of prompts) {\n\t\tawait emit({ type: \"message_start\", message: prompt });\n\t\tawait emit({ type: \"message_end\", message: prompt });\n\t}\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nexport async function runAgentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst newMessages: AgentMessage[] = [];\n\tconst currentContext: AgentContext = { ...context };\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nfunction createAgentStream(): EventStream<AgentEvent, AgentMessage[]> {\n\treturn new EventStream<AgentEvent, AgentMessage[]>(\n\t\t(event: AgentEvent) => event.type === \"agent_end\",\n\t\t(event: AgentEvent) => (event.type === \"agent_end\" ? event.messages : []),\n\t);\n}\n\n/**\n * Main loop logic shared by agentLoop and agentLoopContinue.\n */\nasync function runLoop(\n\tinitialContext: AgentContext,\n\tnewMessages: AgentMessage[],\n\tinitialConfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<void> {\n\tlet currentContext = initialContext;\n\tlet config = initialConfig;\n\tlet firstTurn = true;\n\t// Check for steering messages at start (user may have typed while waiting)\n\tlet pendingMessages: AgentMessage[] = (await config.getSteeringMessages?.()) || [];\n\n\t// Outer loop: continues when queued follow-up messages arrive after agent would stop\n\twhile (true) {\n\t\tlet hasMoreToolCalls = true;\n\n\t\t// Inner loop: process tool calls and steering messages\n\t\twhile (hasMoreToolCalls || pendingMessages.length > 0) {\n\t\t\tif (!firstTurn) {\n\t\t\t\tawait emit({ type: \"turn_start\" });\n\t\t\t} else {\n\t\t\t\tfirstTurn = false;\n\t\t\t}\n\n\t\t\t// Process pending messages (inject before next assistant response)\n\t\t\tif (pendingMessages.length > 0) {\n\t\t\t\tfor (const message of pendingMessages) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message });\n\t\t\t\t\tawait emit({ type: \"message_end\", message });\n\t\t\t\t\tcurrentContext.messages.push(message);\n\t\t\t\t\tnewMessages.push(message);\n\t\t\t\t}\n\t\t\t\tpendingMessages = [];\n\t\t\t}\n\n\t\t\t// Stream assistant response\n\t\t\tconst message = await streamAssistantResponse(currentContext, config, signal, emit, streamFn);\n\t\t\tnewMessages.push(message);\n\n\t\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\t\t\tawait emit({ type: \"turn_end\", message, toolResults: [] });\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Check for tool calls\n\t\t\tconst toolCalls = message.content.filter((c) => c.type === \"toolCall\");\n\n\t\t\tconst toolResults: ToolResultMessage[] = [];\n\t\t\thasMoreToolCalls = false;\n\t\t\tif (toolCalls.length > 0) {\n\t\t\t\tconst executedToolBatch = await executeToolCalls(currentContext, message, config, signal, emit);\n\t\t\t\ttoolResults.push(...executedToolBatch.messages);\n\t\t\t\thasMoreToolCalls = !executedToolBatch.terminate;\n\n\t\t\t\tfor (const result of toolResults) {\n\t\t\t\t\tcurrentContext.messages.push(result);\n\t\t\t\t\tnewMessages.push(result);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait emit({ type: \"turn_end\", message, toolResults });\n\n\t\t\tconst nextTurnContext = {\n\t\t\t\tmessage,\n\t\t\t\ttoolResults,\n\t\t\t\tcontext: currentContext,\n\t\t\t\tnewMessages,\n\t\t\t};\n\t\t\tconst nextTurnSnapshot = await config.prepareNextTurn?.(nextTurnContext);\n\t\t\tif (nextTurnSnapshot) {\n\t\t\t\tcurrentContext = nextTurnSnapshot.context ?? currentContext;\n\t\t\t\tconfig = {\n\t\t\t\t\t...config,\n\t\t\t\t\tmodel: nextTurnSnapshot.model ?? config.model,\n\t\t\t\t\treasoning:\n\t\t\t\t\t\tnextTurnSnapshot.thinkingLevel === undefined\n\t\t\t\t\t\t\t? config.reasoning\n\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel === \"off\"\n\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tawait config.shouldStopAfterTurn?.({\n\t\t\t\t\tmessage,\n\t\t\t\t\ttoolResults,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t\tnewMessages,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpendingMessages = (await config.getSteeringMessages?.()) || [];\n\t\t}\n\n\t\t// Agent would stop here. Check for follow-up messages.\n\t\tconst followUpMessages = (await config.getFollowUpMessages?.()) || [];\n\t\tif (followUpMessages.length > 0) {\n\t\t\t// Set as pending so inner loop processes them\n\t\t\tpendingMessages = followUpMessages;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// No more messages, exit\n\t\tbreak;\n\t}\n\n\tawait emit({ type: \"agent_end\", messages: newMessages });\n}\n\n/**\n * Stream an assistant response from the LLM.\n * This is where AgentMessage[] gets transformed to Message[] for the LLM.\n */\nasync function streamAssistantResponse(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<AssistantMessage> {\n\t// Apply context transform if configured (AgentMessage[] → AgentMessage[])\n\tlet messages = context.messages;\n\tif (config.transformContext) {\n\t\tmessages = await config.transformContext(messages, signal);\n\t}\n\n\t// Convert to LLM-compatible messages (AgentMessage[] → Message[])\n\tconst llmMessages = await config.convertToLlm(messages);\n\n\t// Build LLM context\n\tconst llmContext: Context = {\n\t\tsystemPrompt: context.systemPrompt,\n\t\tmessages: llmMessages,\n\t\ttools: context.tools,\n\t};\n\n\tconst streamFunction = streamFn || streamSimple;\n\n\t// Resolve API key (important for expiring tokens)\n\tconst resolvedApiKey =\n\t\t(config.getApiKey ? await config.getApiKey(config.model.provider) : undefined) || config.apiKey;\n\n\tconst response = await streamFunction(config.model, llmContext, {\n\t\t...config,\n\t\tapiKey: resolvedApiKey,\n\t\tsignal,\n\t});\n\n\tlet partialMessage: AssistantMessage | null = null;\n\tlet addedPartial = false;\n\n\tfor await (const event of response) {\n\t\tswitch (event.type) {\n\t\t\tcase \"start\":\n\t\t\t\tpartialMessage = event.partial;\n\t\t\t\tcontext.messages.push(partialMessage);\n\t\t\t\taddedPartial = true;\n\t\t\t\tawait emit({ type: \"message_start\", message: { ...partialMessage } });\n\t\t\t\tbreak;\n\n\t\t\tcase \"text_start\":\n\t\t\tcase \"text_delta\":\n\t\t\tcase \"text_end\":\n\t\t\tcase \"thinking_start\":\n\t\t\tcase \"thinking_delta\":\n\t\t\tcase \"thinking_end\":\n\t\t\tcase \"toolcall_start\":\n\t\t\tcase \"toolcall_delta\":\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tif (partialMessage) {\n\t\t\t\t\tpartialMessage = event.partial;\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = partialMessage;\n\t\t\t\t\tawait emit({\n\t\t\t\t\t\ttype: \"message_update\",\n\t\t\t\t\t\tassistantMessageEvent: event,\n\t\t\t\t\t\tmessage: { ...partialMessage },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"done\":\n\t\t\tcase \"error\": {\n\t\t\t\tconst finalMessage = await response.result();\n\t\t\t\tif (addedPartial) {\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t\t\t\t} else {\n\t\t\t\t\tcontext.messages.push(finalMessage);\n\t\t\t\t}\n\t\t\t\tif (!addedPartial) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t\t\t\t}\n\t\t\t\tawait emit({ type: \"message_end\", message: finalMessage });\n\t\t\t\treturn finalMessage;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst finalMessage = await response.result();\n\tif (addedPartial) {\n\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t} else {\n\t\tcontext.messages.push(finalMessage);\n\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t}\n\tawait emit({ type: \"message_end\", message: finalMessage });\n\treturn finalMessage;\n}\n\n/**\n * Execute tool calls from an assistant message.\n */\nasync function executeToolCalls(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst toolCalls = assistantMessage.content.filter((c) => c.type === \"toolCall\");\n\tconst hasSequentialToolCall = toolCalls.some(\n\t\t(tc) => currentContext.tools?.find((t) => t.name === tc.name)?.executionMode === \"sequential\",\n\t);\n\tif (config.toolExecution === \"sequential\" || hasSequentialToolCall) {\n\t\treturn executeToolCallsSequential(currentContext, assistantMessage, toolCalls, config, signal, emit);\n\t}\n\treturn executeToolCallsParallel(currentContext, assistantMessage, toolCalls, config, signal, emit);\n}\n\ntype ExecutedToolCallBatch = {\n\tmessages: ToolResultMessage[];\n\tterminate: boolean;\n};\n\nasync function executeToolCallsSequential(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallOutcome[] = [];\n\tconst messages: ToolResultMessage[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tawait emit({\n\t\t\ttype: \"tool_execution_start\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\targs: toolCall.arguments,\n\t\t});\n\n\t\tconst preparation = await prepareToolCall(currentContext, assistantMessage, toolCall, config, signal);\n\t\tlet finalized: FinalizedToolCallOutcome;\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tfinalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t};\n\t\t} else {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tfinalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t}\n\n\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tfinalizedCalls.push(finalized);\n\t\tmessages.push(toolResultMessage);\n\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(finalizedCalls),\n\t};\n}\n\nasync function executeToolCallsParallel(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallEntry[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tawait emit({\n\t\t\ttype: \"tool_execution_start\",\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\targs: toolCall.arguments,\n\t\t});\n\n\t\tconst preparation = await prepareToolCall(currentContext, assistantMessage, toolCall, config, signal);\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tconst finalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t} satisfies FinalizedToolCallOutcome;\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\tfinalizedCalls.push(finalized);\n\t\t\tif (signal?.aborted) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tfinalizedCalls.push(async () => {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tconst finalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\treturn finalized;\n\t\t});\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst orderedFinalizedCalls = await Promise.all(\n\t\tfinalizedCalls.map((entry) => (typeof entry === \"function\" ? entry() : Promise.resolve(entry))),\n\t);\n\tconst messages: ToolResultMessage[] = [];\n\tfor (const finalized of orderedFinalizedCalls) {\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tmessages.push(toolResultMessage);\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(orderedFinalizedCalls),\n\t};\n}\n\ntype PreparedToolCall = {\n\tkind: \"prepared\";\n\ttoolCall: AgentToolCall;\n\ttool: AgentTool<any>;\n\targs: unknown;\n};\n\ntype ImmediateToolCallOutcome = {\n\tkind: \"immediate\";\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype ExecutedToolCallOutcome = {\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype FinalizedToolCallOutcome = {\n\ttoolCall: AgentToolCall;\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype FinalizedToolCallEntry = FinalizedToolCallOutcome | (() => Promise<FinalizedToolCallOutcome>);\n\nfunction shouldTerminateToolBatch(finalizedCalls: FinalizedToolCallOutcome[]): boolean {\n\treturn finalizedCalls.length > 0 && finalizedCalls.every((finalized) => finalized.result.terminate === true);\n}\n\nfunction prepareToolCallArguments(tool: AgentTool<any>, toolCall: AgentToolCall): AgentToolCall {\n\tif (!tool.prepareArguments) {\n\t\treturn toolCall;\n\t}\n\tconst preparedArguments = tool.prepareArguments(toolCall.arguments);\n\tif (preparedArguments === toolCall.arguments) {\n\t\treturn toolCall;\n\t}\n\treturn {\n\t\t...toolCall,\n\t\targuments: preparedArguments as Record<string, any>,\n\t};\n}\n\nasync function prepareToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCall: AgentToolCall,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n): Promise<PreparedToolCall | ImmediateToolCallOutcome> {\n\tconst tool = currentContext.tools?.find((t) => t.name === toolCall.name);\n\tif (!tool) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(`Tool ${toolCall.name} not found`),\n\t\t\tisError: true,\n\t\t};\n\t}\n\n\ttry {\n\t\tconst preparedToolCall = prepareToolCallArguments(tool, toolCall);\n\t\tconst validatedArgs = validateToolArguments(tool, preparedToolCall);\n\t\tif (config.beforeToolCall) {\n\t\t\tconst beforeResult = await config.beforeToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall,\n\t\t\t\t\targs: validatedArgs,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (signal?.aborted) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (beforeResult?.block) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(beforeResult.reason || \"Tool execution was blocked\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tif (signal?.aborted) {\n\t\t\treturn {\n\t\t\t\tkind: \"immediate\",\n\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\tisError: true,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tkind: \"prepared\",\n\t\t\ttoolCall,\n\t\t\ttool,\n\t\t\targs: validatedArgs,\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(error instanceof Error ? error.message : String(error)),\n\t\t\tisError: true,\n\t\t};\n\t}\n}\n\nasync function executePreparedToolCall(\n\tprepared: PreparedToolCall,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallOutcome> {\n\tconst updateEvents: Promise<void>[] = [];\n\tlet acceptingUpdates = true;\n\n\ttry {\n\t\tconst result = await prepared.tool.execute(\n\t\t\tprepared.toolCall.id,\n\t\t\tprepared.args as never,\n\t\t\tsignal,\n\t\t\t(partialResult) => {\n\t\t\t\tif (!acceptingUpdates) return;\n\t\t\t\tupdateEvents.push(\n\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\temit({\n\t\t\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\t\t\ttoolCallId: prepared.toolCall.id,\n\t\t\t\t\t\t\ttoolName: prepared.toolCall.name,\n\t\t\t\t\t\t\targs: prepared.toolCall.arguments,\n\t\t\t\t\t\t\tpartialResult,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t},\n\t\t);\n\t\tacceptingUpdates = false;\n\t\tawait Promise.all(updateEvents);\n\t\treturn { result, isError: false };\n\t} catch (error) {\n\t\tacceptingUpdates = false;\n\t\tawait Promise.all(updateEvents);\n\t\treturn {\n\t\t\tresult: createErrorToolResult(error instanceof Error ? error.message : String(error)),\n\t\t\tisError: true,\n\t\t};\n\t} finally {\n\t\tacceptingUpdates = false;\n\t}\n}\n\nasync function finalizeExecutedToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tprepared: PreparedToolCall,\n\texecuted: ExecutedToolCallOutcome,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n): Promise<FinalizedToolCallOutcome> {\n\tlet result = executed.result;\n\tlet isError = executed.isError;\n\n\tif (config.afterToolCall) {\n\t\ttry {\n\t\t\tconst afterResult = await config.afterToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall: prepared.toolCall,\n\t\t\t\t\targs: prepared.args,\n\t\t\t\t\tresult,\n\t\t\t\t\tisError,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (afterResult) {\n\t\t\t\tresult = {\n\t\t\t\t\tcontent: afterResult.content ?? result.content,\n\t\t\t\t\tdetails: afterResult.details ?? result.details,\n\t\t\t\t\tterminate: afterResult.terminate ?? result.terminate,\n\t\t\t\t};\n\t\t\t\tisError = afterResult.isError ?? isError;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tresult = createErrorToolResult(error instanceof Error ? error.message : String(error));\n\t\t\tisError = true;\n\t\t}\n\t}\n\n\treturn {\n\t\ttoolCall: prepared.toolCall,\n\t\tresult,\n\t\tisError,\n\t};\n}\n\nfunction createErrorToolResult(message: string): AgentToolResult<any> {\n\treturn {\n\t\tcontent: [{ type: \"text\", text: message }],\n\t\tdetails: {},\n\t};\n}\n\nasync function emitToolExecutionEnd(finalized: FinalizedToolCallOutcome, emit: AgentEventSink): Promise<void> {\n\tawait emit({\n\t\ttype: \"tool_execution_end\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tresult: finalized.result,\n\t\tisError: finalized.isError,\n\t});\n}\n\nfunction createToolResultMessage(finalized: FinalizedToolCallOutcome): ToolResultMessage {\n\treturn {\n\t\trole: \"toolResult\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tcontent: finalized.result.content,\n\t\tdetails: finalized.result.details,\n\t\tisError: finalized.isError,\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nasync function emitToolResultMessage(toolResultMessage: ToolResultMessage, emit: AgentEventSink): Promise<void> {\n\tawait emit({ type: \"message_start\", message: toolResultMessage });\n\tawait emit({ type: \"message_end\", message: toolResultMessage });\n}\n"]}
|
|
@@ -65,7 +65,7 @@ export interface CutPointResult {
|
|
|
65
65
|
}
|
|
66
66
|
/** Find the compaction cut point that keeps approximately the requested recent-token budget. */
|
|
67
67
|
export declare function findCutPoint(entries: SessionTreeEntry[], startIndex: number, endIndex: number, keepRecentTokens: number): CutPointResult;
|
|
68
|
-
export declare const SUMMARIZATION_SYSTEM_PROMPT = "You are a context summarization assistant. Your task is to read a conversation between a user and an AI
|
|
68
|
+
export declare const SUMMARIZATION_SYSTEM_PROMPT = "You are a context summarization assistant. Your task is to read a conversation between a user and an AI assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.";
|
|
69
69
|
/** Generate or update a conversation summary for compaction. */
|
|
70
70
|
export declare function generateSummary(currentMessages: AgentMessage[], model: Model<any>, reserveTokens: number, apiKey: string, headers?: Record<string, string>, signal?: AbortSignal, customInstructions?: string, previousSummary?: string, thinkingLevel?: ThinkingLevel): Promise<Result<string, CompactionError>>;
|
|
71
71
|
/** Prepared inputs for a compaction run. */
|