gsd-pi 2.77.0 → 2.78.0-dev.aeeb2ca00
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/README.md +51 -33
- package/dist/claude-cli-check.js +46 -10
- package/dist/cli-web-branch.d.ts +1 -0
- package/dist/cli-web-branch.js +3 -0
- package/dist/cli.js +38 -2
- package/dist/extension-discovery.d.ts +6 -0
- package/dist/extension-discovery.js +37 -0
- package/dist/extension-registry.d.ts +3 -0
- package/dist/extension-sort.d.ts +18 -0
- package/dist/extension-sort.js +114 -0
- package/dist/extension-validator.d.ts +47 -0
- package/dist/extension-validator.js +127 -0
- package/dist/headless.js +49 -4
- package/dist/loader.js +35 -7
- package/dist/provider-migrations.d.ts +18 -0
- package/dist/provider-migrations.js +14 -0
- package/dist/resource-loader.d.ts +40 -0
- package/dist/resource-loader.js +32 -13
- package/dist/resources/extensions/browser-tools/capture.js +9 -0
- package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
- package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
- package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
- package/dist/resources/extensions/browser-tools/tools/forms.js +5 -1
- package/dist/resources/extensions/browser-tools/tools/intent.js +5 -1
- package/dist/resources/extensions/claude-code-cli/readiness.js +72 -16
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +552 -67
- package/dist/resources/extensions/cmux/index.js +20 -0
- package/dist/resources/extensions/github-sync/templates.js +103 -0
- package/dist/resources/extensions/google-search/extension-manifest.json +5 -4
- package/dist/resources/extensions/google-search/index.js +3 -375
- package/dist/resources/extensions/gsd/abandon-detect.js +44 -0
- package/dist/resources/extensions/gsd/auto/loop.js +124 -2
- package/dist/resources/extensions/gsd/auto/phases.js +57 -39
- package/dist/resources/extensions/gsd/auto/resolve.js +24 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +10 -2
- package/dist/resources/extensions/gsd/auto/session.js +6 -2
- package/dist/resources/extensions/gsd/auto/turn-epoch.js +95 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +201 -38
- package/dist/resources/extensions/gsd/auto-loop.js +1 -1
- package/dist/resources/extensions/gsd/auto-model-selection.js +124 -4
- package/dist/resources/extensions/gsd/auto-post-unit.js +215 -64
- package/dist/resources/extensions/gsd/auto-prompts.js +372 -104
- package/dist/resources/extensions/gsd/auto-recovery.js +210 -24
- package/dist/resources/extensions/gsd/auto-start.js +122 -30
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +11 -5
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +47 -7
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +11 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +180 -34
- package/dist/resources/extensions/gsd/auto.js +107 -35
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +19 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +209 -0
- package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +5 -6
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +11 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -3
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +11 -6
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +127 -9
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +31 -4
- package/dist/resources/extensions/gsd/commands-cmux.js +9 -6
- package/dist/resources/extensions/gsd/commands-extensions.js +634 -43
- package/dist/resources/extensions/gsd/component-loader.js +447 -0
- package/dist/resources/extensions/gsd/component-types.js +69 -0
- package/dist/resources/extensions/gsd/context-store.js +23 -7
- package/dist/resources/extensions/gsd/detection.js +49 -1
- package/dist/resources/extensions/gsd/dispatch-guard.js +29 -3
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/file-lock.js +49 -9
- package/dist/resources/extensions/gsd/forensics.js +106 -0
- package/dist/resources/extensions/gsd/gate-registry.js +2 -2
- package/dist/resources/extensions/gsd/git-constants.js +28 -1
- package/dist/resources/extensions/gsd/git-self-heal.js +27 -0
- package/dist/resources/extensions/gsd/git-service.js +127 -2
- package/dist/resources/extensions/gsd/gitignore.js +1 -0
- package/dist/resources/extensions/gsd/gsd-db.js +6 -3
- package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -1
- package/dist/resources/extensions/gsd/guided-flow.js +39 -13
- package/dist/resources/extensions/gsd/journal.js +17 -2
- package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
- package/dist/resources/extensions/gsd/milestone-actions.js +15 -0
- package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
- package/dist/resources/extensions/gsd/milestone-summary-classifier.js +37 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
- package/dist/resources/extensions/gsd/model-router.js +6 -0
- package/dist/resources/extensions/gsd/native-git-bridge.js +34 -4
- package/dist/resources/extensions/gsd/notifications.js +30 -16
- package/dist/resources/extensions/gsd/preferences-validation.js +23 -0
- package/dist/resources/extensions/gsd/prompt-cache-optimizer.js +4 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
- package/dist/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -0
- package/dist/resources/extensions/gsd/reports.js +5 -4
- package/dist/resources/extensions/gsd/safety/git-checkpoint.js +11 -0
- package/dist/resources/extensions/gsd/service-tier.js +5 -2
- package/dist/resources/extensions/gsd/session-lock.js +19 -10
- package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
- package/dist/resources/extensions/gsd/slice-cadence.js +238 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +278 -8
- package/dist/resources/extensions/gsd/state-transition-matrix.js +118 -0
- package/dist/resources/extensions/gsd/state.js +69 -58
- package/dist/resources/extensions/gsd/sync-lock.js +98 -42
- package/dist/resources/extensions/gsd/tools/complete-slice.js +21 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +31 -0
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +7 -2
- package/dist/resources/extensions/gsd/unit-context-composer.js +147 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +370 -0
- package/dist/resources/extensions/gsd/uok/audit.js +18 -2
- package/dist/resources/extensions/gsd/uok/dispatch-envelope.js +33 -0
- package/dist/resources/extensions/gsd/uok/execution-graph.js +10 -0
- package/dist/resources/extensions/gsd/uok/gate-runner.js +53 -5
- package/dist/resources/extensions/gsd/uok/gitops.js +2 -1
- package/dist/resources/extensions/gsd/uok/loop-adapter.js +37 -10
- package/dist/resources/extensions/gsd/uok/parity-report.js +58 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +10 -4
- package/dist/resources/extensions/gsd/uok/writer.js +82 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +10 -2
- package/dist/resources/extensions/gsd/workflow-mcp.js +6 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +86 -8
- package/dist/resources/extensions/gsd/worktree-resolver.js +86 -7
- package/dist/resources/extensions/gsd/worktree-telemetry.js +198 -0
- package/dist/resources/extensions/mcp-client/auth.js +10 -1
- package/dist/resources/extensions/mcp-client/index.js +121 -10
- package/dist/resources/extensions/ollama/index.js +5 -1
- package/dist/resources/extensions/remote-questions/manager.js +11 -5
- package/dist/resources/extensions/shared/cmux-events.js +12 -0
- package/dist/resources/extensions/shared/rtk-session-stats.js +1 -2
- package/dist/resources/skills/create-skill/SKILL.md +2 -2
- package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
- package/dist/resources/skills/create-skill/workflows/audit-skill.md +4 -4
- package/dist/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
- package/dist/web/standalone/.next/server/chunks/1926.js +1 -0
- package/dist/web/standalone/.next/server/chunks/63.js +3 -3
- package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +11 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-5b113fd32bc2a1c3.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-5fc74f13a25fa1bb.js → webpack-2e68521d7c82f7c2.js} +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +17 -16
- package/packages/daemon/package.json +2 -2
- package/packages/daemon/src/logger.ts +4 -3
- package/packages/mcp-server/README.md +3 -3
- package/packages/mcp-server/dist/env-writer.d.ts +1 -0
- package/packages/mcp-server/dist/env-writer.d.ts.map +1 -1
- package/packages/mcp-server/dist/env-writer.js +74 -6
- package/packages/mcp-server/dist/env-writer.js.map +1 -1
- package/packages/mcp-server/dist/server.d.ts +24 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +111 -87
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +15 -6
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +7 -2
- package/packages/mcp-server/src/env-writer.test.ts +79 -1
- package/packages/mcp-server/src/env-writer.ts +76 -6
- package/packages/mcp-server/src/mcp-server.test.ts +25 -3
- package/packages/mcp-server/src/readers/graph.test.ts +87 -15
- package/packages/mcp-server/src/readers/readers.test.ts +5 -1
- package/packages/mcp-server/src/secure-env-collect.test.ts +232 -237
- package/packages/mcp-server/src/server.ts +158 -105
- package/packages/mcp-server/src/workflow-tools.test.ts +85 -0
- package/packages/mcp-server/src/workflow-tools.ts +19 -6
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +7 -2
- package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
- package/packages/native/src/__tests__/clipboard.test.mjs +69 -23
- package/packages/native/src/__tests__/module-compat.test.mjs +59 -27
- package/packages/native/src/__tests__/ps.test.mjs +14 -8
- package/packages/native/src/__tests__/stream-process.test.mjs +23 -2
- package/packages/native/src/__tests__/truncate.test.mjs +17 -2
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/package.json +6 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +226 -31
- package/packages/pi-agent-core/src/agent.test.ts +96 -102
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/capability-patches.js +9 -2
- package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
- package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai.js +17 -0
- package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.test.js +43 -70
- package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
- package/packages/pi-ai/dist/models.test.js +36 -11
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- package/packages/pi-ai/package.json +6 -1
- package/packages/pi-ai/scripts/generate-models.ts +44 -0
- package/packages/pi-ai/src/models/capability-patches.ts +10 -2
- package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
- package/packages/pi-ai/src/models/generated/openai.ts +17 -0
- package/packages/pi-ai/src/models.generated.test.ts +46 -73
- package/packages/pi-ai/src/models.test.ts +48 -11
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js +75 -12
- package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +25 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +105 -6
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +230 -28
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +30 -2
- package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/utils.js +113 -12
- package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +29 -18
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js +130 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js +56 -1
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +8 -15
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts +25 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js +109 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts +67 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js +167 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +8 -2
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +85 -8
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +7 -0
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +41 -4
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +19 -2
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +76 -18
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +2 -6
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +5 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts +18 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.js +18 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +4 -1
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.js +19 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +20 -0
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +19 -5
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/path-utils.test.js +2 -1
- package/packages/pi-coding-agent/dist/core/tools/path-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -0
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js +15 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +36 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +20 -13
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts +7 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +31 -9
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +30 -12
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +18 -3
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +139 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +105 -13
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
- package/packages/pi-coding-agent/package.json +6 -1
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
- package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +368 -28
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +122 -6
- package/packages/pi-coding-agent/src/core/compaction/utils.ts +111 -13
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.test.ts +154 -0
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +32 -18
- package/packages/pi-coding-agent/src/core/compaction-utils.test.ts +68 -1
- package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +9 -18
- package/packages/pi-coding-agent/src/core/extensions/extension-discovery.ts +119 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-registry.ts +222 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +82 -11
- package/packages/pi-coding-agent/src/core/extensions/types.ts +8 -0
- package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +48 -4
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +22 -2
- package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
- package/packages/pi-coding-agent/src/core/resource-loader.ts +1 -1
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +5 -1
- package/packages/pi-coding-agent/src/core/retry-handler.ts +2 -8
- package/packages/pi-coding-agent/src/core/retryable-error-regex.ts +18 -0
- package/packages/pi-coding-agent/src/core/sdk.test.ts +25 -1
- package/packages/pi-coding-agent/src/core/sdk.ts +10 -3
- package/packages/pi-coding-agent/src/core/system-prompt.ts +38 -4
- package/packages/pi-coding-agent/src/core/tools/path-utils.test.ts +2 -1
- package/packages/pi-coding-agent/src/index.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/provider-display-name.test.ts +17 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +49 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +14 -5
- package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +45 -11
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +48 -9
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +160 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +20 -3
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +2 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +119 -13
- package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js +31 -14
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +128 -17
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +51 -6
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
- package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
- package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
- package/packages/pi-tui/dist/components/editor.d.ts +14 -0
- package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/editor.js +19 -0
- package/packages/pi-tui/dist/components/editor.js.map +1 -1
- package/packages/pi-tui/dist/components/image.test.js +6 -5
- package/packages/pi-tui/dist/components/image.test.js.map +1 -1
- package/packages/pi-tui/dist/editor-component.d.ts +2 -0
- package/packages/pi-tui/dist/editor-component.d.ts.map +1 -1
- package/packages/pi-tui/dist/editor-component.js.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.d.ts +7 -0
- package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.js +20 -0
- package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/packages/pi-tui/package.json +6 -1
- package/packages/pi-tui/src/__tests__/autocomplete.test.ts +46 -15
- package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
- package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +62 -6
- package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
- package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
- package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
- package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
- package/packages/pi-tui/src/components/editor.ts +22 -0
- package/packages/pi-tui/src/components/image.test.ts +10 -5
- package/packages/pi-tui/src/editor-component.ts +3 -0
- package/packages/pi-tui/src/stdin-buffer.ts +26 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/dist/rpc-client.test.js +101 -51
- package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
- package/packages/rpc-client/package.json +6 -1
- package/packages/rpc-client/src/rpc-client.test.ts +109 -52
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +1 -1
- package/scripts/install.js +526 -0
- package/scripts/lib/workspace-manifest.cjs +86 -0
- package/scripts/link-workspace-packages.cjs +5 -17
- package/scripts/postinstall.js +9 -178
- package/src/resources/extensions/browser-tools/capture.ts +12 -0
- package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
- package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
- package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
- package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
- package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
- package/src/resources/extensions/claude-code-cli/readiness.ts +75 -16
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +602 -73
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +1028 -91
- package/src/resources/extensions/cmux/index.ts +35 -10
- package/src/resources/extensions/github-sync/templates.ts +151 -0
- package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
- package/src/resources/extensions/github-sync/tests/templates.test.ts +92 -1
- package/src/resources/extensions/google-search/extension-manifest.json +5 -4
- package/src/resources/extensions/google-search/index.ts +9 -470
- package/src/resources/extensions/gsd/abandon-detect.ts +62 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -1
- package/src/resources/extensions/gsd/auto/loop.ts +142 -2
- package/src/resources/extensions/gsd/auto/phases.ts +62 -38
- package/src/resources/extensions/gsd/auto/resolve.ts +29 -0
- package/src/resources/extensions/gsd/auto/run-unit.ts +16 -2
- package/src/resources/extensions/gsd/auto/session.ts +7 -2
- package/src/resources/extensions/gsd/auto/turn-epoch.ts +108 -0
- package/src/resources/extensions/gsd/auto/types.ts +1 -1
- package/src/resources/extensions/gsd/auto-dispatch.ts +214 -37
- package/src/resources/extensions/gsd/auto-loop.ts +1 -1
- package/src/resources/extensions/gsd/auto-model-selection.ts +131 -4
- package/src/resources/extensions/gsd/auto-post-unit.ts +226 -73
- package/src/resources/extensions/gsd/auto-prompts.ts +385 -93
- package/src/resources/extensions/gsd/auto-recovery.ts +240 -25
- package/src/resources/extensions/gsd/auto-start.ts +146 -14
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -5
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +51 -7
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +14 -3
- package/src/resources/extensions/gsd/auto-worktree.ts +190 -31
- package/src/resources/extensions/gsd/auto.ts +127 -41
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +20 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +221 -0
- package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +6 -6
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +11 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -3
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +13 -9
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +158 -9
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +27 -8
- package/src/resources/extensions/gsd/commands-cmux.ts +10 -6
- package/src/resources/extensions/gsd/commands-extensions.ts +747 -41
- package/src/resources/extensions/gsd/component-loader.ts +598 -0
- package/src/resources/extensions/gsd/component-types.ts +362 -0
- package/src/resources/extensions/gsd/context-store.ts +25 -8
- package/src/resources/extensions/gsd/detection.ts +58 -1
- package/src/resources/extensions/gsd/dispatch-guard.ts +26 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/file-lock.ts +84 -11
- package/src/resources/extensions/gsd/forensics.ts +118 -1
- package/src/resources/extensions/gsd/gate-registry.ts +2 -2
- package/src/resources/extensions/gsd/git-constants.ts +30 -1
- package/src/resources/extensions/gsd/git-self-heal.ts +31 -0
- package/src/resources/extensions/gsd/git-service.ts +150 -2
- package/src/resources/extensions/gsd/gitignore.ts +1 -0
- package/src/resources/extensions/gsd/gsd-db.ts +6 -3
- package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -1
- package/src/resources/extensions/gsd/guided-flow.ts +57 -14
- package/src/resources/extensions/gsd/journal.ts +38 -3
- package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
- package/src/resources/extensions/gsd/milestone-actions.ts +18 -0
- package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
- package/src/resources/extensions/gsd/milestone-summary-classifier.ts +42 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
- package/src/resources/extensions/gsd/model-router.ts +6 -0
- package/src/resources/extensions/gsd/native-git-bridge.ts +34 -4
- package/src/resources/extensions/gsd/notifications.ts +27 -15
- package/src/resources/extensions/gsd/preferences-validation.ts +21 -0
- package/src/resources/extensions/gsd/prompt-cache-optimizer.ts +4 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
- package/src/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
- package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -0
- package/src/resources/extensions/gsd/reports.ts +5 -4
- package/src/resources/extensions/gsd/safety/git-checkpoint.ts +15 -0
- package/src/resources/extensions/gsd/service-tier.ts +5 -2
- package/src/resources/extensions/gsd/session-lock.ts +20 -10
- package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
- package/src/resources/extensions/gsd/slice-cadence.ts +299 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +309 -8
- package/src/resources/extensions/gsd/state-transition-matrix.ts +152 -0
- package/src/resources/extensions/gsd/state.ts +76 -66
- package/src/resources/extensions/gsd/sync-lock.ts +97 -39
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +270 -0
- package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +341 -0
- package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +264 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +135 -285
- package/src/resources/extensions/gsd/tests/auto-mode-guards.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +742 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +61 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +166 -0
- package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -194
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
- package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
- package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/cmux.test.ts +5 -9
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +16 -8
- package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
- package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/context-store.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +50 -1
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +159 -0
- package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +91 -3
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +14 -9
- package/src/resources/extensions/gsd/tests/dispatch-guard-summary-db-mismatch.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +173 -0
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
- package/src/resources/extensions/gsd/tests/file-lock.test.ts +86 -12
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +8 -104
- package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +131 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
- package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -56
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +144 -7
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -16
- package/src/resources/extensions/gsd/tests/integration/worktree-e2e.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +9 -3
- package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +93 -1
- package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -55
- package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
- package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/milestone-summary-classifier.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
- package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +6 -48
- package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +59 -2
- package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -130
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/prompt-cache-optimizer.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +15 -4
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +54 -41
- package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +213 -0
- package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +4 -5
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +13 -7
- package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +75 -2
- package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
- package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
- package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +170 -0
- package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/rewrite-docs-abandon-detect.test.ts +195 -0
- package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
- package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +158 -0
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
- package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +164 -1
- package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +7 -6
- package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/test-helpers.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/test-helpers.ts +153 -0
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +61 -1
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +50 -2
- package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +162 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +258 -0
- package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
- package/src/resources/extensions/gsd/tests/uok-loop-adapter-writer.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/uok-parity-report.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +19 -2
- package/src/resources/extensions/gsd/tests/uok-writer.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/validate-extension-package.test.ts +168 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +139 -5
- package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -80
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -54
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +342 -277
- package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +37 -29
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +25 -2
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
- package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
- package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +210 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +262 -0
- package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
- package/src/resources/extensions/gsd/tools/complete-slice.ts +38 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +49 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +8 -2
- package/src/resources/extensions/gsd/types.ts +3 -3
- package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +574 -0
- package/src/resources/extensions/gsd/uok/audit.ts +20 -2
- package/src/resources/extensions/gsd/uok/contracts.ts +65 -0
- package/src/resources/extensions/gsd/uok/dispatch-envelope.ts +56 -0
- package/src/resources/extensions/gsd/uok/execution-graph.ts +22 -0
- package/src/resources/extensions/gsd/uok/gate-runner.ts +65 -5
- package/src/resources/extensions/gsd/uok/gitops.ts +6 -1
- package/src/resources/extensions/gsd/uok/loop-adapter.ts +45 -10
- package/src/resources/extensions/gsd/uok/parity-report.ts +84 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +13 -5
- package/src/resources/extensions/gsd/uok/writer.ts +113 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +22 -3
- package/src/resources/extensions/gsd/workflow-mcp.ts +6 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +109 -7
- package/src/resources/extensions/gsd/worktree-resolver.ts +96 -9
- package/src/resources/extensions/gsd/worktree-telemetry.ts +322 -0
- package/src/resources/extensions/mcp-client/auth.ts +12 -1
- package/src/resources/extensions/mcp-client/index.ts +132 -11
- package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +70 -36
- package/src/resources/extensions/ollama/index.ts +5 -1
- package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +123 -15
- package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +206 -19
- package/src/resources/extensions/remote-questions/manager.ts +36 -4
- package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +200 -190
- package/src/resources/extensions/shared/cmux-events.ts +59 -0
- package/src/resources/extensions/shared/rtk-session-stats.ts +1 -2
- package/src/resources/extensions/shared/tests/interview-preview.test.ts +11 -3
- package/src/resources/extensions/voice/tests/linux-ready.test.ts +129 -113
- package/src/resources/skills/create-skill/SKILL.md +2 -2
- package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
- package/src/resources/skills/create-skill/workflows/audit-skill.md +4 -4
- package/src/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
- package/dist/web/standalone/.next/server/chunks/7461.js +0 -1
- package/dist/web/standalone/.next/static/chunks/2826.e59e8578e2e28639.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +0 -2
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +0 -1
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +0 -289
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +0 -1
- package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +0 -363
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -143
- package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +0 -142
- package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +0 -107
- package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +0 -48
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -159
- package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
- package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +0 -74
- package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +0 -38
- package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +0 -73
- package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -125
- package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -42
- /package/dist/web/standalone/.next/static/{pV-mPo7rYGb5JBC09C8GG → cAJH99yNS1UPbeSEiNRrV}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{pV-mPo7rYGb5JBC09C8GG → cAJH99yNS1UPbeSEiNRrV}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry-handler.test.js","sourceRoot":"","sources":["../../src/core/retry-handler.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RetryHandler tests — long-context entitlement 429 error handling (#2803)\n *\n * Verifies that \"Extra usage is required for long context requests\" errors\n * are classified as quota_exhausted (not rate_limit) and trigger a model\n * downgrade from [1m] to base when no cross-provider fallback exists.\n */\n\nimport { describe, it, beforeEach, mock, type Mock } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { RetryHandler, type RetryHandlerDeps } from \"./retry-handler.js\";\nimport type { Api, AssistantMessage, Model } from \"@gsd/pi-ai\";\nimport type { FallbackResolver } from \"./fallback-resolver.js\";\nimport type { ModelRegistry } from \"./model-registry.js\";\nimport type { SettingsManager } from \"./settings-manager.js\";\n\n// ─── Helpers ────────────────────────────────────────────────────────────────\n\nfunction createMockModel(provider: string, id: string): Model<Api> {\n\treturn {\n\t\tid,\n\t\tname: id,\n\t\tapi: \"anthropic\" as Api,\n\t\tprovider,\n\t\tbaseUrl: \"https://api.anthropic.com\",\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcontextWindow: 1_000_000,\n\t\tmaxTokens: 16384,\n\t} as Model<Api>;\n}\n\nfunction errorMessage(msg: string): AssistantMessage {\n\treturn {\n\t\trole: \"assistant\",\n\t\tcontent: [],\n\t\tapi: \"anthropic-messages\",\n\t\tprovider: \"anthropic\",\n\t\tmodel: \"claude-opus-4-6[1m]\",\n\t\tusage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },\n\t\tstopReason: \"error\",\n\t\terrorMessage: msg,\n\t\ttimestamp: Date.now(),\n\t} as AssistantMessage;\n}\n\ninterface MockDeps {\n\tdeps: RetryHandlerDeps;\n\temittedEvents: Array<Record<string, any>>;\n\tcontinueFn: Mock<() => Promise<void>>;\n\tonModelChangeFn: Mock<(model: Model<any>) => void>;\n\tmarkUsageLimitReached: Mock<(...args: any[]) => boolean>;\n\tfindFallback: Mock<(...args: any[]) => Promise<any>>;\n\tfindModel: Mock<(provider: string, modelId: string) => Model<Api> | undefined>;\n}\n\nfunction createMockDeps(overrides?: {\n\tmodel?: Model<Api>;\n\tretryEnabled?: boolean;\n\tmarkUsageLimitReachedResult?: boolean;\n\tfallbackResult?: any;\n\tfindModelResult?: (provider: string, modelId: string) => Model<Api> | undefined;\n\tretrySettings?: {\n\t\tmaxRetries?: number;\n\t\tbaseDelayMs?: number;\n\t\tmaxDelayMs?: number;\n\t};\n}): MockDeps {\n\tconst model = overrides?.model ?? createMockModel(\"anthropic\", \"claude-opus-4-6[1m]\");\n\tconst emittedEvents: Array<Record<string, any>> = [];\n\tconst continueFn = mock.fn(async () => {});\n\tconst onModelChangeFn = mock.fn((_model: Model<any>) => {});\n\tconst markUsageLimitReached = mock.fn(\n\t\t() => overrides?.markUsageLimitReachedResult ?? false,\n\t);\n\tconst findFallback = mock.fn(async () => overrides?.fallbackResult ?? null);\n\tconst findModel = mock.fn(\n\t\toverrides?.findModelResult ?? ((_provider: string, _modelId: string) => undefined),\n\t);\n\n\tconst messages: Array<{ role: string } & Record<string, any>> = [];\n\n\tconst deps: RetryHandlerDeps = {\n\t\tagent: {\n\t\t\tcontinue: continueFn,\n\t\t\tstate: { messages },\n\t\t\tsetModel: mock.fn(),\n\t\t\treplaceMessages: mock.fn((newMessages: any[]) => {\n\t\t\t\tmessages.length = 0;\n\t\t\t\tmessages.push(...newMessages);\n\t\t\t}),\n\t\t} as any,\n\t\tsettingsManager: {\n\t\t\tgetRetryEnabled: () => overrides?.retryEnabled ?? true,\n\t\t\tgetRetrySettings: () => ({\n\t\t\t\tenabled: overrides?.retryEnabled ?? true,\n\t\t\t\tmaxRetries: overrides?.retrySettings?.maxRetries ?? 5,\n\t\t\t\tbaseDelayMs: overrides?.retrySettings?.baseDelayMs ?? 1000,\n\t\t\t\tmaxDelayMs: overrides?.retrySettings?.maxDelayMs ?? 30000,\n\t\t\t}),\n\t\t} as unknown as SettingsManager,\n\t\tmodelRegistry: {\n\t\t\tauthStorage: {\n\t\t\t\tmarkUsageLimitReached,\n\t\t\t},\n\t\t\tfind: findModel,\n\t\t} as unknown as ModelRegistry,\n\t\tfallbackResolver: {\n\t\t\tfindFallback,\n\t\t} as unknown as FallbackResolver,\n\t\tgetModel: () => model,\n\t\tgetSessionId: () => \"test-session\",\n\t\temit: (event: any) => emittedEvents.push(event),\n\t\tonModelChange: onModelChangeFn,\n\t};\n\n\treturn { deps, emittedEvents, continueFn, onModelChangeFn, markUsageLimitReached, findFallback, findModel };\n}\n\n// ─── _classifyErrorType (tested via handleRetryableError behavior) ──────────\n\ndescribe(\"RetryHandler — long-context entitlement 429 (#2803)\", () => {\n\n\tdescribe(\"error classification\", () => {\n\t\tit(\"classifies 'Extra usage is required for long context requests' as quota_exhausted, not rate_limit\", async () => {\n\t\t\t// When the error is classified as quota_exhausted AND no alternate credentials\n\t\t\t// AND no fallback, the handler should emit fallback_chain_exhausted and stop.\n\t\t\t// If misclassified as rate_limit, it would enter the backoff loop instead.\n\t\t\tconst { deps, emittedEvents, findModel } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6[1m]\"),\n\t\t\t\tmarkUsageLimitReachedResult: false, // no alternate credentials\n\t\t\t\tfallbackResult: null, // no cross-provider fallback\n\t\t\t\tfindModelResult: () => undefined, // no base model either\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\n\t\t\t\t'429 {\"type\":\"error\",\"error\":{\"type\":\"rate_limit_error\",\"message\":\"Extra usage is required for long context requests.\"}}'\n\t\t\t);\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\t// Should NOT retry (would be true if misclassified as rate_limit entering backoff)\n\t\t\tassert.equal(result, false);\n\n\t\t\t// Should emit fallback_chain_exhausted (quota_exhausted path), NOT auto_retry_start (backoff path)\n\t\t\tconst chainExhausted = emittedEvents.find((e) => e.type === \"fallback_chain_exhausted\");\n\t\t\tassert.ok(chainExhausted, \"Expected fallback_chain_exhausted event for entitlement error\");\n\n\t\t\tconst retryStart = emittedEvents.find((e) => e.type === \"auto_retry_start\");\n\t\t\tassert.equal(retryStart, undefined, \"Should NOT emit auto_retry_start for entitlement error\");\n\t\t});\n\n\t\tit(\"still classifies regular 429 rate limits as rate_limit\", async () => {\n\t\t\t// A normal \"rate limit\" 429 should still be classified as rate_limit\n\t\t\tconst { deps, emittedEvents } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"429 Too Many Requests\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\t// Should enter the backoff loop (rate_limit path, not quota_exhausted)\n\t\t\tassert.equal(result, true);\n\n\t\t\tconst retryStart = emittedEvents.find((e) => e.type === \"auto_retry_start\");\n\t\t\tassert.ok(retryStart, \"Regular 429 should enter backoff retry\");\n\t\t});\n\n\t\tit(\"classifies OpenRouter credit affordability errors as quota_exhausted\", async () => {\n\t\t\tconst { deps, emittedEvents } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"openrouter\", \"openai/gpt-5-pro\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\n\t\t\t\t\"402 This request requires more credits, or fewer max_tokens. You requested up to 32000 tokens, but can only afford 329.\",\n\t\t\t);\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(result, true, \"affordability error should trigger credit-aware retry\");\n\t\t\tconst retryStart = emittedEvents.find((e) => e.type === \"auto_retry_start\");\n\t\t\tassert.ok(retryStart, \"Expected immediate retry after reducing max tokens\");\n\t\t});\n\t});\n\n\tdescribe(\"long-context model downgrade\", () => {\n\t\tit(\"downgrades from [1m] to base model when entitlement error and no fallback\", async () => {\n\t\t\tconst baseModel = createMockModel(\"anthropic\", \"claude-opus-4-6\");\n\t\t\tconst { deps, emittedEvents, onModelChangeFn, continueFn } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6[1m]\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t\tfindModelResult: (provider: string, modelId: string) => {\n\t\t\t\t\tif (provider === \"anthropic\" && modelId === \"claude-opus-4-6\") return baseModel;\n\t\t\t\t\treturn undefined;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"Extra usage is required for long context requests.\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(result, true, \"Should retry after downgrade\");\n\n\t\t\t// Should have called setModel with the base model\n\t\t\tconst setModelCalls = (deps.agent.setModel as any).mock.calls;\n\t\t\tassert.equal(setModelCalls.length, 1);\n\t\t\tassert.equal(setModelCalls[0].arguments[0].id, \"claude-opus-4-6\");\n\n\t\t\t// Should have notified about model change\n\t\t\tassert.equal(onModelChangeFn.mock.calls.length, 1);\n\n\t\t\t// Should emit a fallback_provider_switch event indicating downgrade\n\t\t\tconst switchEvent = emittedEvents.find((e) => e.type === \"fallback_provider_switch\");\n\t\t\tassert.ok(switchEvent, \"Expected fallback_provider_switch event for downgrade\");\n\t\t\tassert.ok(switchEvent!.reason.includes(\"long context downgrade\"), `reason should mention downgrade: ${switchEvent!.reason}`);\n\t\t});\n\n\t\tit(\"emits fallback_chain_exhausted when base model is also unavailable\", async () => {\n\t\t\tconst { deps, emittedEvents } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6[1m]\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t\tfindModelResult: () => undefined, // base model not found\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"Extra usage is required for long context requests.\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(result, false);\n\t\t\tconst chainExhausted = emittedEvents.find((e) => e.type === \"fallback_chain_exhausted\");\n\t\t\tassert.ok(chainExhausted, \"Expected fallback_chain_exhausted when base model unavailable\");\n\t\t});\n\n\t\tit(\"does not attempt downgrade for non-[1m] models\", async () => {\n\t\t\t// When a regular model (no [1m] suffix) gets a quota_exhausted error\n\t\t\t// with no fallback, it should just stop — no downgrade attempt.\n\t\t\tconst { deps, emittedEvents } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"Extra usage is required for long context requests.\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(result, false);\n\t\t\tconst chainExhausted = emittedEvents.find((e) => e.type === \"fallback_chain_exhausted\");\n\t\t\tassert.ok(chainExhausted);\n\n\t\t\t// No downgrade switch should occur\n\t\t\tconst switchEvent = emittedEvents.find((e) => e.type === \"fallback_provider_switch\");\n\t\t\tassert.equal(switchEvent, undefined, \"Should not switch for non-[1m] models\");\n\t\t});\n\t});\n\n\tdescribe(\"retry cancellation\", () => {\n\t\tit(\"cancels queued immediate continue callbacks when retry is aborted\", async () => {\n\t\t\tconst { deps, emittedEvents, continueFn } = createMockDeps({\n\t\t\t\tmarkUsageLimitReachedResult: true,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"429 Too Many Requests\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\t\t\tassert.equal(result, true, \"retry should be initiated\");\n\n\t\t\thandler.abortRetry();\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 10));\n\n\t\t\tassert.equal(continueFn.mock.calls.length, 0, \"cancelled retry must not continue after explicit abort\");\n\t\t\tconst endEvents = emittedEvents.filter((e) => e.type === \"auto_retry_end\");\n\t\t\tassert.equal(endEvents.length, 1, \"retry cancellation should emit a single auto_retry_end event\");\n\t\t\tassert.equal(endEvents[0]?.finalError, \"Retry cancelled\");\n\t\t});\n\t});\n\n\tdescribe(\"credit-aware maxTokens retry\", () => {\n\t\tit(\"reduces maxTokens on same model when provider reports affordable cap\", async () => {\n\t\t\tconst expensiveModel = createMockModel(\"openrouter\", \"openai/gpt-5-pro\");\n\t\t\texpensiveModel.maxTokens = 128000;\n\n\t\t\tconst { deps, emittedEvents, onModelChangeFn } = createMockDeps({\n\t\t\t\tmodel: expensiveModel,\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\n\t\t\t\t\"402 This request requires more credits, or fewer max_tokens. You requested up to 32000 tokens, but can only afford 329.\",\n\t\t\t);\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\t\t\tassert.equal(result, true, \"should retry after reducing maxTokens\");\n\n\t\t\tconst setModelCalls = (deps.agent.setModel as any).mock.calls;\n\t\t\tassert.equal(setModelCalls.length, 1, \"should apply one model downgrade\");\n\t\t\tconst downgraded = setModelCalls[0].arguments[0] as Model<Api>;\n\t\t\tassert.equal(downgraded.provider, \"openrouter\");\n\t\t\tassert.equal(downgraded.id, \"openai/gpt-5-pro\");\n\t\t\tassert.equal(downgraded.maxTokens, 297, \"expected affordability cap with safety buffer\");\n\n\t\t\tassert.equal(onModelChangeFn.mock.calls.length, 1, \"should notify about model update\");\n\t\t\tconst switchEvent = emittedEvents.find((e) => e.type === \"fallback_provider_switch\");\n\t\t\tassert.ok(switchEvent, \"should emit model-adjustment event\");\n\t\t\tassert.ok(\n\t\t\t\tString(switchEvent?.reason || \"\").includes(\"credit-aware retry\"),\n\t\t\t\t\"switch reason should mention credit-aware retry\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"does not mark credentials in cooldown for affordability quota errors\", async () => {\n\t\t\tconst expensiveModel = createMockModel(\"openrouter\", \"openai/gpt-5-pro\");\n\t\t\texpensiveModel.maxTokens = 128000;\n\n\t\t\tconst { deps, markUsageLimitReached } = createMockDeps({\n\t\t\t\tmodel: expensiveModel,\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\n\t\t\t\t\"402 This request requires more credits, or fewer max_tokens. You requested up to 32000 tokens, but can only afford 329.\",\n\t\t\t);\n\n\t\t\tawait handler.handleRetryableError(msg);\n\t\t\tassert.equal(markUsageLimitReached.mock.calls.length, 0, \"quota error should skip credential cooldown\");\n\t\t});\n\t});\n\n\tdescribe(\"isRetryableError\", () => {\n\t\tit(\"considers long-context entitlement error as retryable\", () => {\n\t\t\tconst { deps } = createMockDeps();\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"Extra usage is required for long context requests.\");\n\t\t\tassert.equal(handler.isRetryableError(msg), true);\n\t\t});\n\n\t\tit(\"does NOT consider credential cooldown error as retryable (#3429)\", () => {\n\t\t\t// The credential cooldown message from getApiKey() must not re-enter\n\t\t\t// the retry handler. Re-entry creates cascading empty error entries\n\t\t\t// in the session file that break resume.\n\t\t\tconst { deps } = createMockDeps();\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\n\t\t\t\t'All credentials for \"anthropic\" are in a cooldown window. ' +\n\t\t\t\t'Please wait a moment and try again, or switch to a different provider.',\n\t\t\t);\n\t\t\tassert.equal(handler.isRetryableError(msg), false);\n\t\t});\n\n\t\tit(\"considers OpenRouter affordability credit errors as retryable\", () => {\n\t\t\tconst { deps } = createMockDeps();\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\n\t\t\t\t\"402 This request requires more credits, or fewer max_tokens. You requested up to 32000 tokens, but can only afford 329.\",\n\t\t\t);\n\t\t\tassert.equal(handler.isRetryableError(msg), true);\n\t\t});\n\t});\n\n\tdescribe(\"third-party block claude-code fallback (#3772)\", () => {\n\t\tit(\"switches to claude-code provider when current provider is anthropic\", async () => {\n\t\t\tconst ccModel = createMockModel(\"claude-code\", \"claude-opus-4-6\");\n\t\t\tconst { deps, emittedEvents, onModelChangeFn } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6\"),\n\t\t\t\tfindModelResult: (provider: string, modelId: string) => {\n\t\t\t\t\tif (provider === \"claude-code\" && modelId === \"claude-opus-4-6\") return ccModel;\n\t\t\t\t\treturn undefined;\n\t\t\t\t},\n\t\t\t});\n\t\t\tdeps.isClaudeCodeReady = () => true;\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"third-party apps cannot draw from extra usage\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(result, true, \"should retry via claude-code fallback\");\n\t\t\tconst switchEvent = emittedEvents.find((e) => e.type === \"fallback_provider_switch\");\n\t\t\tassert.ok(switchEvent, \"Expected fallback_provider_switch event\");\n\t\t\tassert.ok(switchEvent!.to.startsWith(\"claude-code/\"), \"Should switch to claude-code provider\");\n\t\t});\n\n\t\tit(\"switches to claude-code on 'out of extra usage' error (#3772)\", async () => {\n\t\t\tconst ccModel = createMockModel(\"claude-code\", \"claude-opus-4-6\");\n\t\t\tconst { deps, emittedEvents } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6\"),\n\t\t\t\tfindModelResult: (provider: string, modelId: string) => {\n\t\t\t\t\tif (provider === \"claude-code\" && modelId === \"claude-opus-4-6\") return ccModel;\n\t\t\t\t\treturn undefined;\n\t\t\t\t},\n\t\t\t});\n\t\t\tdeps.isClaudeCodeReady = () => true;\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"You're out of extra usage. Add more at claude.ai/settings/usage and keep going.\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(result, true, \"should retry via claude-code fallback\");\n\t\t\tconst switchEvent = emittedEvents.find((e) => e.type === \"fallback_provider_switch\");\n\t\t\tassert.ok(switchEvent, \"Expected fallback_provider_switch event\");\n\t\t\tassert.ok(switchEvent!.to.startsWith(\"claude-code/\"), \"Should switch to claude-code provider\");\n\t\t});\n\n\t\tit(\"does NOT switch to claude-code when current provider is not anthropic\", async () => {\n\t\t\tconst ccModel = createMockModel(\"claude-code\", \"gpt-4o\");\n\t\t\tconst { deps, emittedEvents } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"openai\", \"gpt-4o\"),\n\t\t\t\tfindModelResult: (provider: string, modelId: string) => {\n\t\t\t\t\tif (provider === \"claude-code\" && modelId === \"gpt-4o\") return ccModel;\n\t\t\t\t\treturn undefined;\n\t\t\t\t},\n\t\t\t});\n\t\t\tdeps.isClaudeCodeReady = () => true;\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"third-party apps are not supported for this plan\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\t// Should NOT have triggered the claude-code fallback\n\t\t\tconst switchEvent = emittedEvents.find(\n\t\t\t\t(e) => e.type === \"fallback_provider_switch\" && e.to?.startsWith(\"claude-code/\"),\n\t\t\t);\n\t\t\tassert.equal(switchEvent, undefined, \"Should NOT switch non-anthropic provider to claude-code\");\n\t\t});\n\t});\n\n\tdescribe(\"quota_exhausted credential backoff (#3430)\", () => {\n\t\tit(\"does NOT call markUsageLimitReached for quota_exhausted errors\", async () => {\n\t\t\t// \"Extra usage is required\" is an account-level billing gate.\n\t\t\t// Backing off the credential for 30 minutes blocks all provider\n\t\t\t// requests and has no effect on the billing condition.\n\t\t\tconst { deps, markUsageLimitReached } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6[1m]\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t\tfindModelResult: () => undefined,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\n\t\t\t\t'429 {\"type\":\"error\",\"error\":{\"type\":\"rate_limit_error\",\"message\":\"Extra usage is required for long context requests.\"}}',\n\t\t\t);\n\n\t\t\tawait handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(\n\t\t\t\tmarkUsageLimitReached.mock.calls.length,\n\t\t\t\t0,\n\t\t\t\t\"markUsageLimitReached must NOT be called for quota_exhausted errors\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"still calls markUsageLimitReached for regular rate_limit errors\", async () => {\n\t\t\tconst { deps, markUsageLimitReached } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"429 Too Many Requests\");\n\n\t\t\tawait handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(\n\t\t\t\tmarkUsageLimitReached.mock.calls.length,\n\t\t\t\t1,\n\t\t\t\t\"markUsageLimitReached should be called for rate_limit errors\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"still tries cross-provider fallback for quota_exhausted without credential backoff\", async () => {\n\t\t\tconst fallbackModel = createMockModel(\"openai\", \"gpt-4o\");\n\t\t\tconst { deps, markUsageLimitReached, continueFn } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6[1m]\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: { model: fallbackModel, reason: \"cross-provider fallback\" },\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"Extra usage is required for long context requests.\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(result, true, \"should retry with fallback provider\");\n\t\t\tassert.equal(\n\t\t\t\tmarkUsageLimitReached.mock.calls.length,\n\t\t\t\t0,\n\t\t\t\t\"should NOT back off credentials before trying fallback\",\n\t\t\t);\n\t\t});\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"retry-handler.test.js","sourceRoot":"","sources":["../../src/core/retry-handler.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RetryHandler tests — long-context entitlement 429 error handling (#2803)\n *\n * Verifies that \"Extra usage is required for long context requests\" errors\n * are classified as quota_exhausted (not rate_limit) and trigger a model\n * downgrade from [1m] to base when no cross-provider fallback exists.\n */\n\nimport { describe, it, beforeEach, mock, type Mock } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { RetryHandler, type RetryHandlerDeps } from \"./retry-handler.js\";\nimport type { Api, AssistantMessage, Model } from \"@gsd/pi-ai\";\nimport type { FallbackResolver } from \"./fallback-resolver.js\";\nimport type { ModelRegistry } from \"./model-registry.js\";\nimport type { SettingsManager } from \"./settings-manager.js\";\n\n// ─── Helpers ────────────────────────────────────────────────────────────────\n\nfunction createMockModel(provider: string, id: string): Model<Api> {\n\treturn {\n\t\tid,\n\t\tname: id,\n\t\tapi: \"anthropic\" as Api,\n\t\tprovider,\n\t\tbaseUrl: \"https://api.anthropic.com\",\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcontextWindow: 1_000_000,\n\t\tmaxTokens: 16384,\n\t} as Model<Api>;\n}\n\nfunction errorMessage(msg: string): AssistantMessage {\n\treturn {\n\t\trole: \"assistant\",\n\t\tcontent: [],\n\t\tapi: \"anthropic-messages\",\n\t\tprovider: \"anthropic\",\n\t\tmodel: \"claude-opus-4-6[1m]\",\n\t\tusage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },\n\t\tstopReason: \"error\",\n\t\terrorMessage: msg,\n\t\ttimestamp: Date.now(),\n\t} as AssistantMessage;\n}\n\ninterface MockDeps {\n\tdeps: RetryHandlerDeps;\n\temittedEvents: Array<Record<string, any>>;\n\tcontinueFn: Mock<() => Promise<void>>;\n\tonModelChangeFn: Mock<(model: Model<any>) => void>;\n\tmarkUsageLimitReached: Mock<(...args: any[]) => boolean>;\n\tfindFallback: Mock<(...args: any[]) => Promise<any>>;\n\tfindModel: Mock<(provider: string, modelId: string) => Model<Api> | undefined>;\n}\n\nfunction createMockDeps(overrides?: {\n\tmodel?: Model<Api>;\n\tretryEnabled?: boolean;\n\tmarkUsageLimitReachedResult?: boolean;\n\tfallbackResult?: any;\n\tfindModelResult?: (provider: string, modelId: string) => Model<Api> | undefined;\n\tretrySettings?: {\n\t\tmaxRetries?: number;\n\t\tbaseDelayMs?: number;\n\t\tmaxDelayMs?: number;\n\t};\n}): MockDeps {\n\tconst model = overrides?.model ?? createMockModel(\"anthropic\", \"claude-opus-4-6[1m]\");\n\tconst emittedEvents: Array<Record<string, any>> = [];\n\tconst continueFn = mock.fn(async () => {});\n\tconst onModelChangeFn = mock.fn((_model: Model<any>) => {});\n\tconst markUsageLimitReached = mock.fn(\n\t\t() => overrides?.markUsageLimitReachedResult ?? false,\n\t);\n\tconst findFallback = mock.fn(async () => overrides?.fallbackResult ?? null);\n\tconst findModel = mock.fn(\n\t\toverrides?.findModelResult ?? ((_provider: string, _modelId: string) => undefined),\n\t);\n\n\tconst messages: Array<{ role: string } & Record<string, any>> = [];\n\n\tconst deps: RetryHandlerDeps = {\n\t\tagent: {\n\t\t\tcontinue: continueFn,\n\t\t\tstate: { messages },\n\t\t\tsetModel: mock.fn(),\n\t\t\treplaceMessages: mock.fn((newMessages: any[]) => {\n\t\t\t\tmessages.length = 0;\n\t\t\t\tmessages.push(...newMessages);\n\t\t\t}),\n\t\t} as any,\n\t\tsettingsManager: {\n\t\t\tgetRetryEnabled: () => overrides?.retryEnabled ?? true,\n\t\t\tgetRetrySettings: () => ({\n\t\t\t\tenabled: overrides?.retryEnabled ?? true,\n\t\t\t\tmaxRetries: overrides?.retrySettings?.maxRetries ?? 5,\n\t\t\t\tbaseDelayMs: overrides?.retrySettings?.baseDelayMs ?? 1000,\n\t\t\t\tmaxDelayMs: overrides?.retrySettings?.maxDelayMs ?? 30000,\n\t\t\t}),\n\t\t} as unknown as SettingsManager,\n\t\tmodelRegistry: {\n\t\t\tauthStorage: {\n\t\t\t\tmarkUsageLimitReached,\n\t\t\t},\n\t\t\tfind: findModel,\n\t\t} as unknown as ModelRegistry,\n\t\tfallbackResolver: {\n\t\t\tfindFallback,\n\t\t} as unknown as FallbackResolver,\n\t\tgetModel: () => model,\n\t\tgetSessionId: () => \"test-session\",\n\t\temit: (event: any) => emittedEvents.push(event),\n\t\tonModelChange: onModelChangeFn,\n\t};\n\n\treturn { deps, emittedEvents, continueFn, onModelChangeFn, markUsageLimitReached, findFallback, findModel };\n}\n\n// ─── _classifyErrorType (tested via handleRetryableError behavior) ──────────\n\ndescribe(\"RetryHandler — long-context entitlement 429 (#2803)\", () => {\n\n\tdescribe(\"error classification\", () => {\n\t\tit(\"classifies 'Extra usage is required for long context requests' as quota_exhausted, not rate_limit\", async () => {\n\t\t\t// When the error is classified as quota_exhausted AND no alternate credentials\n\t\t\t// AND no fallback, the handler should emit fallback_chain_exhausted and stop.\n\t\t\t// If misclassified as rate_limit, it would enter the backoff loop instead.\n\t\t\tconst { deps, emittedEvents, findModel } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6[1m]\"),\n\t\t\t\tmarkUsageLimitReachedResult: false, // no alternate credentials\n\t\t\t\tfallbackResult: null, // no cross-provider fallback\n\t\t\t\tfindModelResult: () => undefined, // no base model either\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\n\t\t\t\t'429 {\"type\":\"error\",\"error\":{\"type\":\"rate_limit_error\",\"message\":\"Extra usage is required for long context requests.\"}}'\n\t\t\t);\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\t// Should NOT retry (would be true if misclassified as rate_limit entering backoff)\n\t\t\tassert.equal(result, false);\n\n\t\t\t// Should emit fallback_chain_exhausted (quota_exhausted path), NOT auto_retry_start (backoff path)\n\t\t\tconst chainExhausted = emittedEvents.find((e) => e.type === \"fallback_chain_exhausted\");\n\t\t\tassert.ok(chainExhausted, \"Expected fallback_chain_exhausted event for entitlement error\");\n\n\t\t\tconst retryStart = emittedEvents.find((e) => e.type === \"auto_retry_start\");\n\t\t\tassert.equal(retryStart, undefined, \"Should NOT emit auto_retry_start for entitlement error\");\n\t\t});\n\n\t\tit(\"still classifies regular 429 rate limits as rate_limit\", async () => {\n\t\t\t// A normal \"rate limit\" 429 should still be classified as rate_limit\n\t\t\tconst { deps, emittedEvents } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"429 Too Many Requests\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\t// Should enter the backoff loop (rate_limit path, not quota_exhausted)\n\t\t\tassert.equal(result, true);\n\n\t\t\tconst retryStart = emittedEvents.find((e) => e.type === \"auto_retry_start\");\n\t\t\tassert.ok(retryStart, \"Regular 429 should enter backoff retry\");\n\t\t});\n\n\t\tit(\"classifies OpenRouter credit affordability errors as quota_exhausted\", async () => {\n\t\t\tconst { deps, emittedEvents } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"openrouter\", \"openai/gpt-5-pro\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\n\t\t\t\t\"402 This request requires more credits, or fewer max_tokens. You requested up to 32000 tokens, but can only afford 329.\",\n\t\t\t);\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(result, true, \"affordability error should trigger credit-aware retry\");\n\t\t\tconst retryStart = emittedEvents.find((e) => e.type === \"auto_retry_start\");\n\t\t\tassert.ok(retryStart, \"Expected immediate retry after reducing max tokens\");\n\t\t});\n\t});\n\n\tdescribe(\"long-context model downgrade\", () => {\n\t\tit(\"downgrades from [1m] to base model when entitlement error and no fallback\", async () => {\n\t\t\tconst baseModel = createMockModel(\"anthropic\", \"claude-opus-4-6\");\n\t\t\tconst { deps, emittedEvents, onModelChangeFn, continueFn } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6[1m]\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t\tfindModelResult: (provider: string, modelId: string) => {\n\t\t\t\t\tif (provider === \"anthropic\" && modelId === \"claude-opus-4-6\") return baseModel;\n\t\t\t\t\treturn undefined;\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"Extra usage is required for long context requests.\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(result, true, \"Should retry after downgrade\");\n\n\t\t\t// Should have called setModel with the base model\n\t\t\tconst setModelCalls = (deps.agent.setModel as any).mock.calls;\n\t\t\tassert.equal(setModelCalls.length, 1);\n\t\t\tassert.equal(setModelCalls[0].arguments[0].id, \"claude-opus-4-6\");\n\n\t\t\t// Should have notified about model change\n\t\t\tassert.equal(onModelChangeFn.mock.calls.length, 1);\n\n\t\t\t// Should emit a fallback_provider_switch event indicating downgrade\n\t\t\tconst switchEvent = emittedEvents.find((e) => e.type === \"fallback_provider_switch\");\n\t\t\tassert.ok(switchEvent, \"Expected fallback_provider_switch event for downgrade\");\n\t\t\tassert.ok(switchEvent!.reason.includes(\"long context downgrade\"), `reason should mention downgrade: ${switchEvent!.reason}`);\n\t\t});\n\n\t\tit(\"emits fallback_chain_exhausted when base model is also unavailable\", async () => {\n\t\t\tconst { deps, emittedEvents } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6[1m]\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t\tfindModelResult: () => undefined, // base model not found\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"Extra usage is required for long context requests.\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(result, false);\n\t\t\tconst chainExhausted = emittedEvents.find((e) => e.type === \"fallback_chain_exhausted\");\n\t\t\tassert.ok(chainExhausted, \"Expected fallback_chain_exhausted when base model unavailable\");\n\t\t});\n\n\t\tit(\"does not attempt downgrade for non-[1m] models\", async () => {\n\t\t\t// When a regular model (no [1m] suffix) gets a quota_exhausted error\n\t\t\t// with no fallback, it should just stop — no downgrade attempt.\n\t\t\tconst { deps, emittedEvents } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"Extra usage is required for long context requests.\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(result, false);\n\t\t\tconst chainExhausted = emittedEvents.find((e) => e.type === \"fallback_chain_exhausted\");\n\t\t\tassert.ok(chainExhausted);\n\n\t\t\t// No downgrade switch should occur\n\t\t\tconst switchEvent = emittedEvents.find((e) => e.type === \"fallback_provider_switch\");\n\t\t\tassert.equal(switchEvent, undefined, \"Should not switch for non-[1m] models\");\n\t\t});\n\t});\n\n\tdescribe(\"retry cancellation\", () => {\n\t\tit(\"cancels queued immediate continue callbacks when retry is aborted\", async () => {\n\t\t\tconst { deps, emittedEvents, continueFn } = createMockDeps({\n\t\t\t\tmarkUsageLimitReachedResult: true,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"429 Too Many Requests\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\t\t\tassert.equal(result, true, \"retry should be initiated\");\n\n\t\t\thandler.abortRetry();\n\t\t\t// Yield the microtask queue so any synchronous continuation\n\t\t\t// scheduled by abortRetry() settles before we assert. This is\n\t\t\t// deterministic — no magic-sleep dependency (#4798 / #4784).\n\t\t\tawait Promise.resolve();\n\t\t\tawait Promise.resolve();\n\n\t\t\tassert.equal(continueFn.mock.calls.length, 0, \"cancelled retry must not continue after explicit abort\");\n\t\t\tconst endEvents = emittedEvents.filter((e) => e.type === \"auto_retry_end\");\n\t\t\tassert.equal(endEvents.length, 1, \"retry cancellation should emit a single auto_retry_end event\");\n\t\t\tassert.equal(endEvents[0]?.finalError, \"Retry cancelled\");\n\t\t});\n\t});\n\n\tdescribe(\"credit-aware maxTokens retry\", () => {\n\t\tit(\"reduces maxTokens on same model when provider reports affordable cap\", async () => {\n\t\t\tconst expensiveModel = createMockModel(\"openrouter\", \"openai/gpt-5-pro\");\n\t\t\texpensiveModel.maxTokens = 128000;\n\n\t\t\tconst { deps, emittedEvents, onModelChangeFn } = createMockDeps({\n\t\t\t\tmodel: expensiveModel,\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\n\t\t\t\t\"402 This request requires more credits, or fewer max_tokens. You requested up to 32000 tokens, but can only afford 329.\",\n\t\t\t);\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\t\t\tassert.equal(result, true, \"should retry after reducing maxTokens\");\n\n\t\t\tconst setModelCalls = (deps.agent.setModel as any).mock.calls;\n\t\t\tassert.equal(setModelCalls.length, 1, \"should apply one model downgrade\");\n\t\t\tconst downgraded = setModelCalls[0].arguments[0] as Model<Api>;\n\t\t\tassert.equal(downgraded.provider, \"openrouter\");\n\t\t\tassert.equal(downgraded.id, \"openai/gpt-5-pro\");\n\t\t\tassert.equal(downgraded.maxTokens, 297, \"expected affordability cap with safety buffer\");\n\n\t\t\tassert.equal(onModelChangeFn.mock.calls.length, 1, \"should notify about model update\");\n\t\t\tconst switchEvent = emittedEvents.find((e) => e.type === \"fallback_provider_switch\");\n\t\t\tassert.ok(switchEvent, \"should emit model-adjustment event\");\n\t\t\tassert.ok(\n\t\t\t\tString(switchEvent?.reason || \"\").includes(\"credit-aware retry\"),\n\t\t\t\t\"switch reason should mention credit-aware retry\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"does not mark credentials in cooldown for affordability quota errors\", async () => {\n\t\t\tconst expensiveModel = createMockModel(\"openrouter\", \"openai/gpt-5-pro\");\n\t\t\texpensiveModel.maxTokens = 128000;\n\n\t\t\tconst { deps, markUsageLimitReached } = createMockDeps({\n\t\t\t\tmodel: expensiveModel,\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\n\t\t\t\t\"402 This request requires more credits, or fewer max_tokens. You requested up to 32000 tokens, but can only afford 329.\",\n\t\t\t);\n\n\t\t\tawait handler.handleRetryableError(msg);\n\t\t\tassert.equal(markUsageLimitReached.mock.calls.length, 0, \"quota error should skip credential cooldown\");\n\t\t});\n\t});\n\n\tdescribe(\"isRetryableError\", () => {\n\t\tit(\"considers long-context entitlement error as retryable\", () => {\n\t\t\tconst { deps } = createMockDeps();\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"Extra usage is required for long context requests.\");\n\t\t\tassert.equal(handler.isRetryableError(msg), true);\n\t\t});\n\n\t\tit(\"does NOT consider credential cooldown error as retryable (#3429)\", () => {\n\t\t\t// The credential cooldown message from getApiKey() must not re-enter\n\t\t\t// the retry handler. Re-entry creates cascading empty error entries\n\t\t\t// in the session file that break resume.\n\t\t\tconst { deps } = createMockDeps();\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\n\t\t\t\t'All credentials for \"anthropic\" are in a cooldown window. ' +\n\t\t\t\t'Please wait a moment and try again, or switch to a different provider.',\n\t\t\t);\n\t\t\tassert.equal(handler.isRetryableError(msg), false);\n\t\t});\n\n\t\tit(\"considers OpenRouter affordability credit errors as retryable\", () => {\n\t\t\tconst { deps } = createMockDeps();\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\n\t\t\t\t\"402 This request requires more credits, or fewer max_tokens. You requested up to 32000 tokens, but can only afford 329.\",\n\t\t\t);\n\t\t\tassert.equal(handler.isRetryableError(msg), true);\n\t\t});\n\t});\n\n\tdescribe(\"third-party block claude-code fallback (#3772)\", () => {\n\t\tit(\"switches to claude-code provider when current provider is anthropic\", async () => {\n\t\t\tconst ccModel = createMockModel(\"claude-code\", \"claude-opus-4-6\");\n\t\t\tconst { deps, emittedEvents, onModelChangeFn } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6\"),\n\t\t\t\tfindModelResult: (provider: string, modelId: string) => {\n\t\t\t\t\tif (provider === \"claude-code\" && modelId === \"claude-opus-4-6\") return ccModel;\n\t\t\t\t\treturn undefined;\n\t\t\t\t},\n\t\t\t});\n\t\t\tdeps.isClaudeCodeReady = () => true;\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"third-party apps cannot draw from extra usage\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(result, true, \"should retry via claude-code fallback\");\n\t\t\tconst switchEvent = emittedEvents.find((e) => e.type === \"fallback_provider_switch\");\n\t\t\tassert.ok(switchEvent, \"Expected fallback_provider_switch event\");\n\t\t\tassert.ok(switchEvent!.to.startsWith(\"claude-code/\"), \"Should switch to claude-code provider\");\n\t\t});\n\n\t\tit(\"switches to claude-code on 'out of extra usage' error (#3772)\", async () => {\n\t\t\tconst ccModel = createMockModel(\"claude-code\", \"claude-opus-4-6\");\n\t\t\tconst { deps, emittedEvents } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6\"),\n\t\t\t\tfindModelResult: (provider: string, modelId: string) => {\n\t\t\t\t\tif (provider === \"claude-code\" && modelId === \"claude-opus-4-6\") return ccModel;\n\t\t\t\t\treturn undefined;\n\t\t\t\t},\n\t\t\t});\n\t\t\tdeps.isClaudeCodeReady = () => true;\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"You're out of extra usage. Add more at claude.ai/settings/usage and keep going.\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(result, true, \"should retry via claude-code fallback\");\n\t\t\tconst switchEvent = emittedEvents.find((e) => e.type === \"fallback_provider_switch\");\n\t\t\tassert.ok(switchEvent, \"Expected fallback_provider_switch event\");\n\t\t\tassert.ok(switchEvent!.to.startsWith(\"claude-code/\"), \"Should switch to claude-code provider\");\n\t\t});\n\n\t\tit(\"does NOT switch to claude-code when current provider is not anthropic\", async () => {\n\t\t\tconst ccModel = createMockModel(\"claude-code\", \"gpt-4o\");\n\t\t\tconst { deps, emittedEvents } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"openai\", \"gpt-4o\"),\n\t\t\t\tfindModelResult: (provider: string, modelId: string) => {\n\t\t\t\t\tif (provider === \"claude-code\" && modelId === \"gpt-4o\") return ccModel;\n\t\t\t\t\treturn undefined;\n\t\t\t\t},\n\t\t\t});\n\t\t\tdeps.isClaudeCodeReady = () => true;\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"third-party apps are not supported for this plan\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\t// Should NOT have triggered the claude-code fallback\n\t\t\tconst switchEvent = emittedEvents.find(\n\t\t\t\t(e) => e.type === \"fallback_provider_switch\" && e.to?.startsWith(\"claude-code/\"),\n\t\t\t);\n\t\t\tassert.equal(switchEvent, undefined, \"Should NOT switch non-anthropic provider to claude-code\");\n\t\t});\n\t});\n\n\tdescribe(\"quota_exhausted credential backoff (#3430)\", () => {\n\t\tit(\"does NOT call markUsageLimitReached for quota_exhausted errors\", async () => {\n\t\t\t// \"Extra usage is required\" is an account-level billing gate.\n\t\t\t// Backing off the credential for 30 minutes blocks all provider\n\t\t\t// requests and has no effect on the billing condition.\n\t\t\tconst { deps, markUsageLimitReached } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6[1m]\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t\tfindModelResult: () => undefined,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\n\t\t\t\t'429 {\"type\":\"error\",\"error\":{\"type\":\"rate_limit_error\",\"message\":\"Extra usage is required for long context requests.\"}}',\n\t\t\t);\n\n\t\t\tawait handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(\n\t\t\t\tmarkUsageLimitReached.mock.calls.length,\n\t\t\t\t0,\n\t\t\t\t\"markUsageLimitReached must NOT be called for quota_exhausted errors\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"still calls markUsageLimitReached for regular rate_limit errors\", async () => {\n\t\t\tconst { deps, markUsageLimitReached } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: null,\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"429 Too Many Requests\");\n\n\t\t\tawait handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(\n\t\t\t\tmarkUsageLimitReached.mock.calls.length,\n\t\t\t\t1,\n\t\t\t\t\"markUsageLimitReached should be called for rate_limit errors\",\n\t\t\t);\n\t\t});\n\n\t\tit(\"still tries cross-provider fallback for quota_exhausted without credential backoff\", async () => {\n\t\t\tconst fallbackModel = createMockModel(\"openai\", \"gpt-4o\");\n\t\t\tconst { deps, markUsageLimitReached, continueFn } = createMockDeps({\n\t\t\t\tmodel: createMockModel(\"anthropic\", \"claude-opus-4-6[1m]\"),\n\t\t\t\tmarkUsageLimitReachedResult: false,\n\t\t\t\tfallbackResult: { model: fallbackModel, reason: \"cross-provider fallback\" },\n\t\t\t});\n\n\t\t\tconst handler = new RetryHandler(deps);\n\t\t\tconst msg = errorMessage(\"Extra usage is required for long context requests.\");\n\n\t\t\tconst result = await handler.handleRetryableError(msg);\n\n\t\t\tassert.equal(result, true, \"should retry with fallback provider\");\n\t\t\tassert.equal(\n\t\t\t\tmarkUsageLimitReached.mock.calls.length,\n\t\t\t\t0,\n\t\t\t\t\"should NOT back off credentials before trying fallback\",\n\t\t\t);\n\t\t});\n\t});\n});\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regex matching retryable provider errors — overloaded, rate limits, transient
|
|
3
|
+
* server/connection failures, credential-backoff, quota/credit issues.
|
|
4
|
+
*
|
|
5
|
+
* Kept in its own zero-import module so tests can consume the live pattern
|
|
6
|
+
* without pulling in the full RetryHandler dependency graph (Agent /
|
|
7
|
+
* FallbackResolver / ModelRegistry / @gsd/pi-ai …). The test in
|
|
8
|
+
* `src/resources/extensions/gsd/tests/provider-errors.test.ts` previously
|
|
9
|
+
* redefined this regex inline, which meant runtime and test could drift
|
|
10
|
+
* silently on every edit (see #4837).
|
|
11
|
+
*
|
|
12
|
+
* "temporarily backed off" is intentionally excluded: it is an internally-
|
|
13
|
+
* generated error from getApiKey() when credentials are in a backoff window.
|
|
14
|
+
* Re-entering the retry handler for that message creates a cascade of empty
|
|
15
|
+
* error entries in the session file, breaking resume (#3429).
|
|
16
|
+
*/
|
|
17
|
+
export declare const RETRYABLE_ERROR_RE: RegExp;
|
|
18
|
+
//# sourceMappingURL=retryable-error-regex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retryable-error-regex.d.ts","sourceRoot":"","sources":["../../src/core/retryable-error-regex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,kBAAkB,QACwc,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regex matching retryable provider errors — overloaded, rate limits, transient
|
|
3
|
+
* server/connection failures, credential-backoff, quota/credit issues.
|
|
4
|
+
*
|
|
5
|
+
* Kept in its own zero-import module so tests can consume the live pattern
|
|
6
|
+
* without pulling in the full RetryHandler dependency graph (Agent /
|
|
7
|
+
* FallbackResolver / ModelRegistry / @gsd/pi-ai …). The test in
|
|
8
|
+
* `src/resources/extensions/gsd/tests/provider-errors.test.ts` previously
|
|
9
|
+
* redefined this regex inline, which meant runtime and test could drift
|
|
10
|
+
* silently on every edit (see #4837).
|
|
11
|
+
*
|
|
12
|
+
* "temporarily backed off" is intentionally excluded: it is an internally-
|
|
13
|
+
* generated error from getApiKey() when credentials are in a backoff window.
|
|
14
|
+
* Re-entering the retry handler for that message creates a cascade of empty
|
|
15
|
+
* error entries in the session file, breaking resume (#3429).
|
|
16
|
+
*/
|
|
17
|
+
export const RETRYABLE_ERROR_RE = /overloaded|rate.?limit|too many requests|402|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated|retry delay|network.?(?:is\s+)?unavailable|credentials.*expired|requires more credits|can only afford|insufficient credits|not enough credits|extra usage is required|(?:out of|no) extra usage|third.party.*draw from extra|third.party.*not.*available/i;
|
|
18
|
+
//# sourceMappingURL=retryable-error-regex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retryable-error-regex.js","sourceRoot":"","sources":["../../src/core/retryable-error-regex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAC9B,seAAse,CAAC","sourcesContent":["/**\n * Regex matching retryable provider errors — overloaded, rate limits, transient\n * server/connection failures, credential-backoff, quota/credit issues.\n *\n * Kept in its own zero-import module so tests can consume the live pattern\n * without pulling in the full RetryHandler dependency graph (Agent /\n * FallbackResolver / ModelRegistry / @gsd/pi-ai …). The test in\n * `src/resources/extensions/gsd/tests/provider-errors.test.ts` previously\n * redefined this regex inline, which meant runtime and test could drift\n * silently on every edit (see #4837).\n *\n * \"temporarily backed off\" is intentionally excluded: it is an internally-\n * generated error from getApiKey() when credentials are in a backoff window.\n * Re-entering the retry handler for that message creates a cascade of empty\n * error entries in the session file, breaking resume (#3429).\n */\nexport const RETRYABLE_ERROR_RE =\n\t/overloaded|rate.?limit|too many requests|402|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated|retry delay|network.?(?:is\\s+)?unavailable|credentials.*expired|requires more credits|can only afford|insufficient credits|not enough credits|extra usage is required|(?:out of|no) extra usage|third.party.*draw from extra|third.party.*not.*available/i;\n"]}
|
|
@@ -9,6 +9,7 @@ export declare class CredentialCooldownError extends Error {
|
|
|
9
9
|
readonly retryAfterMs: number | undefined;
|
|
10
10
|
constructor(provider: string, retryAfterMs?: number);
|
|
11
11
|
}
|
|
12
|
+
export declare function canRestoreSessionModel(modelRegistry: Pick<ModelRegistry, "isProviderRequestReady">, model: Model<any>): boolean;
|
|
12
13
|
import { type ThinkingLevel } from "@gsd/pi-agent-core";
|
|
13
14
|
import type { Model } from "@gsd/pi-ai";
|
|
14
15
|
import { AgentSession } from "./agent-session.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,9 @@ export class CredentialCooldownError extends Error {
|
|
|
24
24
|
this.retryAfterMs = retryAfterMs;
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
+
export function canRestoreSessionModel(modelRegistry, model) {
|
|
28
|
+
return modelRegistry.isProviderRequestReady(model.provider);
|
|
29
|
+
}
|
|
27
30
|
import { Agent } from "@gsd/pi-agent-core";
|
|
28
31
|
import { getAgentDir, getDocsPath } from "../config.js";
|
|
29
32
|
import { AgentSession } from "./agent-session.js";
|
|
@@ -117,7 +120,7 @@ export async function createAgentSession(options = {}) {
|
|
|
117
120
|
// If session has data, try to restore model from it
|
|
118
121
|
if (!model && hasExistingSession && existingSession.model) {
|
|
119
122
|
const restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);
|
|
120
|
-
if (restoredModel && (
|
|
123
|
+
if (restoredModel && canRestoreSessionModel(modelRegistry, restoredModel)) {
|
|
121
124
|
model = restoredModel;
|
|
122
125
|
}
|
|
123
126
|
if (!model) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/**\n * Lightweight PATH scan for the `claude` binary — no subprocess, no network.\n * Mirrors the check in src/resources/extensions/gsd/doctor-providers.ts so the\n * legacy Anthropic OAuth self-heal path can only trigger when the user has a\n * working Claude Code CLI to fall back to.\n */\nfunction isClaudeCodeBinaryInPath(): boolean {\n\tconst pathDirs = (process.env.PATH ?? \"\").split(\":\");\n\treturn pathDirs.some((dir) => dir && existsSync(join(dir, \"claude\")));\n}\n\n/**\n * Structured error thrown when all credentials for a provider are in a\n * backoff window. Carries typed metadata so callers (e.g. the auto-loop)\n * can make informed retry decisions instead of string-matching the message.\n */\nexport class CredentialCooldownError extends Error {\n\treadonly code = \"AUTH_COOLDOWN\" as const;\n\t/** Milliseconds until the earliest credential becomes available, or undefined if unknown. */\n\treadonly retryAfterMs: number | undefined;\n\n\tconstructor(provider: string, retryAfterMs?: number) {\n\t\tsuper(\n\t\t\t`All credentials for \"${provider}\" are in a cooldown window. ` +\n\t\t\t\t`Please wait a moment and try again, or switch to a different provider.`,\n\t\t);\n\t\tthis.name = \"CredentialCooldownError\";\n\t\tthis.retryAfterMs = retryAfterMs;\n\t}\n}\nimport { Agent, type AgentMessage, type ThinkingLevel } from \"@gsd/pi-agent-core\";\nimport type { Message, Model } from \"@gsd/pi-ai\";\nimport { getAgentDir, getDocsPath } from \"../config.js\";\nimport { AgentSession } from \"./agent-session.js\";\nimport { AuthStorage } from \"./auth-storage.js\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.js\";\nimport type { ExtensionRunner, LoadExtensionsResult, ToolDefinition } from \"./extensions/index.js\";\nimport { convertToLlm } from \"./messages.js\";\nimport { ModelRegistry } from \"./model-registry.js\";\nimport { findInitialModel } from \"./model-resolver.js\";\nimport type { ResourceLoader } from \"./resource-loader.js\";\nimport { DefaultResourceLoader } from \"./resource-loader.js\";\nimport { SessionManager } from \"./session-manager.js\";\nimport { SettingsManager } from \"./settings-manager.js\";\nimport { time } from \"./timings.js\";\nimport {\n\tallTools,\n\tbashTool,\n\tcodingTools,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\teditTool,\n\tfindTool,\n\tgrepTool,\n\thashlineCodingTools,\n\thashlineEditTool,\n\thashlineReadTool,\n\tcreateHashlineCodingTools,\n\tcreateHashlineEditTool,\n\tcreateHashlineReadTool,\n\tlsTool,\n\treadOnlyTools,\n\treadTool,\n\ttype Tool,\n\ttype ToolName,\n\twriteTool,\n} from \"./tools/index.js\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.pi/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: new ModelRegistry(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\n\t/** Built-in tools to use. Default: codingTools [read, bash, edit, write] */\n\ttools?: Tool[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\t/**\n\t * Additional tool names to activate after extensions/MCP servers register.\n\t * Names that are not registered by any extension are silently ignored\n\t * by AgentSession.setActiveToolsByName.\n\t *\n\t * Used by --tools to forward names that don't match a built-in (likely\n\t * extension- or MCP-provided), so subagents whose frontmatter declares\n\t * extension tools don't end up with an empty tool list.\n\t */\n\textraActiveToolNames?: string[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\n\t/** Optional: check if the claude-code CLI provider is ready (installed + authed).\n\t * Passed to RetryHandler for third-party block recovery (#3772). */\n\tisClaudeCodeReady?: () => boolean;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandLocation,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.js\";\nexport type { PromptTemplate } from \"./prompt-templates.js\";\nexport type { Skill } from \"./skills.js\";\nexport type { Tool } from \"./tools/index.js\";\n\nexport {\n\t// Pre-built tools (use process.cwd())\n\treadTool,\n\tbashTool,\n\teditTool,\n\twriteTool,\n\tgrepTool,\n\tfindTool,\n\tlsTool,\n\tcodingTools,\n\treadOnlyTools,\n\tallTools as allBuiltInTools,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n\t// Hashline edit mode\n\thashlineCodingTools,\n\thashlineEditTool,\n\thashlineReadTool,\n\tcreateHashlineCodingTools,\n\tcreateHashlineEditTool,\n\tcreateHashlineReadTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from '@gsd/pi-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [readTool, bashTool],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tconst agentDir = options.agentDir ?? getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? new ModelRegistry(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd);\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Flush provider registrations queued during extension loading so that\n\t// extension models (e.g. pi-claude-cli) are visible in the registry before\n\t// findInitialModel() runs. bindCore() repeats this flush as a safety net\n\t// for any late-arriving registrations.\n\tconst { runtime: extensionRuntime } = resourceLoader.getExtensions();\n\tfor (const { name, config } of extensionRuntime.pendingProviderRegistrations) {\n\t\tmodelRegistry.registerProvider(name, config);\n\t}\n\textensionRuntime.pendingProviderRegistrations = [];\n\n\t// Check if session has existing data to restore\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && (await modelRegistry.getApiKey(restoredModel))) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// Flush extension provider registrations so extension-provided models (e.g. claude-code/*)\n\t// are available in the registry before model resolution. Without this, findInitialModel()\n\t// cannot find extension models and falls back to built-in providers (#3534).\n\tconst extensionsForModelResolution = resourceLoader.getExtensions();\n\tfor (const { name, config } of extensionsForModelResolution.runtime.pendingProviderRegistrations) {\n\t\tmodelRegistry.registerProvider(name, config);\n\t}\n\t// Clear the queue so bindCore() doesn't re-register the same providers.\n\textensionsForModelResolution.runtime.pendingProviderRegistrations = [];\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `No models available. Use /login or set an API key environment variable. See ${join(getDocsPath(), \"providers.md\")}. Then use /model to select a model.`;\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model || !model.reasoning) {\n\t\tthinkingLevel = \"off\";\n\t}\n\n\tconst editMode = settingsManager.getEditMode();\n\tconst defaultActiveToolNames: ToolName[] = editMode === \"hashline\"\n\t\t? [\"hashline_read\", \"bash\", \"hashline_edit\", \"write\", \"lsp\"]\n\t\t: [\"read\", \"bash\", \"edit\", \"write\", \"lsp\"];\n\tconst builtinActiveToolNames: ToolName[] = options.tools\n\t\t? options.tools.map((t) => t.name).filter((n): n is ToolName => n in allTools)\n\t\t: defaultActiveToolNames;\n\t// Merge in extension/MCP tool names from --tools that didn't match a built-in.\n\t// AgentSession.setActiveToolsByName silently drops names that aren't in the\n\t// registry, so unknown names are harmless here.\n\tconst initialActiveToolNames: string[] = options.extraActiveToolNames\n\t\t? [...builtinActiveToolNames, ...options.extraActiveToolNames]\n\t\t: builtinActiveToolNames;\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tonPayload: async (payload, currentModel) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload, currentModel);\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getRetrySettings().maxDelayMs,\n\t\texternalToolExecution: (m) => modelRegistry.getProviderAuthMode(m.provider) === \"externalCli\",\n\t\tgetProviderOptions: async (currentModel) => {\n\t\t\tif (currentModel.provider !== \"claude-code\") return undefined;\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasUI()) return undefined;\n\t\t\treturn {\n\t\t\t\textensionUIContext: runner.getUIContext(),\n\t\t\t};\n\t\t},\n\t\tgetApiKey: async (provider) => {\n\t\t\t// Use the provider argument from the in-flight request;\n\t\t\t// agent.state.model may already be switched mid-turn.\n\t\t\tconst resolvedProvider = provider || agent.state.model?.provider;\n\t\t\tif (!resolvedProvider) {\n\t\t\t\tthrow new Error(\"No model selected\");\n\t\t\t}\n\t\t\tconst authMode = modelRegistry.getProviderAuthMode(resolvedProvider);\n\t\t\tif (authMode === \"externalCli\" || authMode === \"none\") {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\t// Retry key resolution with backoff to handle transient network failures\n\t\t\t// (e.g., OAuth token refresh failing due to brief connectivity loss).\n\t\t\t// When credentials are in a cooldown window (e.g., after a 429), wait\n\t\t\t// for the backoff to expire instead of using fixed delays that are\n\t\t\t// shorter than the cooldown duration.\n\t\t\tconst maxAttempts = 3;\n\t\t\tconst baseDelayMs = 2000;\n\t\t\tconst maxCooldownWaitMs = 60_000; // Don't wait longer than 60s (skip quota-exhausted 30min backoffs)\n\t\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\t\tconst key = await modelRegistry.getApiKeyForProvider(resolvedProvider);\n\t\t\t\tif (key) return key;\n\n\t\t\t\t// On the last attempt, fall through to error handling below\n\t\t\t\tif (attempt >= maxAttempts) break;\n\n\t\t\t\t// Only retry if credentials exist (network issue) — no point retrying\n\t\t\t\t// when there are genuinely no credentials configured.\n\t\t\t\tconst hasAuth = modelRegistry.authStorage.hasAuth(resolvedProvider);\n\t\t\t\tconst model = agent.state.model;\n\t\t\t\tconst isOAuth = model && modelRegistry.isUsingOAuth(model);\n\t\t\t\tif (!hasAuth && !isOAuth) break;\n\n\t\t\t\t// If credentials are in a cooldown window, wait for the earliest\n\t\t\t\t// one to expire rather than using a fixed delay that's too short.\n\t\t\t\tconst backoffExpiry = modelRegistry.authStorage.getEarliestBackoffExpiry(resolvedProvider);\n\t\t\t\tif (backoffExpiry !== undefined) {\n\t\t\t\t\tconst waitMs = backoffExpiry - Date.now() + 500; // 500ms buffer\n\t\t\t\t\tif (waitMs > 0 && waitMs <= maxCooldownWaitMs) {\n\t\t\t\t\t\tawait new Promise(resolve => setTimeout(resolve, waitMs));\n\t\t\t\t\t\tcontinue; // Retry immediately after cooldown clears\n\t\t\t\t\t}\n\t\t\t\t\tif (waitMs > maxCooldownWaitMs) {\n\t\t\t\t\t\tbreak; // Quota-exhausted or very long backoff — don't block\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Standard exponential backoff for non-cooldown transient failures\n\t\t\t\tawait new Promise(resolve => setTimeout(resolve, baseDelayMs * attempt));\n\t\t\t}\n\n\t\t\t// All retries exhausted — throw descriptive error.\n\t\t\t// Check if credentials exist but are temporarily in a backoff window\n\t\t\t// (e.g., after a 429). This message intentionally avoids phrases like\n\t\t\t// \"rate limit\" / \"429\" to prevent isRetryableError() from re-entering\n\t\t\t// the retry handler and creating cascading error entries (#3429).\n\t\t\tconst hasAuth = modelRegistry.authStorage.hasAuth(resolvedProvider);\n\t\t\tif (hasAuth) {\n\t\t\t\t// Anthropic OAuth was removed in v2.74.0 for TOS compliance (#3952).\n\t\t\t\t// Users who upgraded from an older version may still have OAuth\n\t\t\t\t// credentials in auth.json that will never resolve to a valid API key.\n\t\t\t\tif (\n\t\t\t\t\tresolvedProvider === \"anthropic\" &&\n\t\t\t\t\tmodelRegistry.authStorage.hasLegacyOAuthCredential(resolvedProvider)\n\t\t\t\t) {\n\t\t\t\t\t// Self-heal: strip the stale oauth entry so hasAuth() stops lying\n\t\t\t\t\t// about anthropic being configured. This preserves any api_key\n\t\t\t\t\t// credentials alongside it.\n\t\t\t\t\tconst removed = modelRegistry.authStorage.removeLegacyOAuthCredential(resolvedProvider);\n\t\t\t\t\tif (removed) {\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`[auth] Removed unsupported Anthropic OAuth credential from auth.json (#3952).`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif (isClaudeCodeBinaryInPath()) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Removed stale Anthropic OAuth credential (OAuth support removed in v2.74.0). ` +\n\t\t\t\t\t\t\t\t`Your current model's provider is set to \"anthropic\" but the local Claude Code CLI ` +\n\t\t\t\t\t\t\t\t`is available — switch the model's provider to \"claude-code\" in your preferences ` +\n\t\t\t\t\t\t\t\t`to use it, or set ANTHROPIC_API_KEY to continue with the Anthropic API directly.`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Removed stale Anthropic OAuth credential (OAuth support removed in v2.74.0). ` +\n\t\t\t\t\t\t\t`Set ANTHROPIC_API_KEY, run '/login' and paste an API key, or switch to a different provider.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst expiry = modelRegistry.authStorage.getEarliestBackoffExpiry(resolvedProvider);\n\t\t\t\tconst retryAfterMs = expiry !== undefined ? Math.max(0, expiry - Date.now()) : undefined;\n\t\t\t\tthrow new CredentialCooldownError(resolvedProvider, retryAfterMs);\n\t\t\t}\n\t\t\tconst model = agent.state.model;\n\t\t\tconst isOAuth = model && modelRegistry.isUsingOAuth(model);\n\t\t\tif (isOAuth) {\n\t\t\t\t// If credentials exist but are all in a backoff window (quota / rate-limit),\n\t\t\t\t// surface a specific message instead of the misleading \"Authentication failed\".\n\t\t\t\tif (modelRegistry.authStorage.areAllCredentialsBackedOff(resolvedProvider)) {\n\t\t\t\t\tconst expiry = modelRegistry.authStorage.getEarliestBackoffExpiry(resolvedProvider);\n\t\t\t\t\tconst retryAfterMs = expiry !== undefined ? Math.max(0, expiry - Date.now()) : undefined;\n\t\t\t\t\tthrow new CredentialCooldownError(resolvedProvider, retryAfterMs);\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Authentication failed for \"${resolvedProvider}\". ` +\n\t\t\t\t\t\t`Credentials may have expired or network is unavailable. ` +\n\t\t\t\t\t\t`Run '/login ${resolvedProvider}' to re-authenticate.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new Error(\n\t\t\t\t`No API key found for \"${resolvedProvider}\". ` +\n\t\t\t\t\t`Set an API key environment variable or run '/login ${resolvedProvider}'.`,\n\t\t\t);\n\t\t},\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.replaceMessages(existingSession.messages);\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\textensionRunnerRef,\n\t\tisClaudeCodeReady: options.isClaudeCodeReady,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/**\n * Lightweight PATH scan for the `claude` binary — no subprocess, no network.\n * Mirrors the check in src/resources/extensions/gsd/doctor-providers.ts so the\n * legacy Anthropic OAuth self-heal path can only trigger when the user has a\n * working Claude Code CLI to fall back to.\n */\nfunction isClaudeCodeBinaryInPath(): boolean {\n\tconst pathDirs = (process.env.PATH ?? \"\").split(\":\");\n\treturn pathDirs.some((dir) => dir && existsSync(join(dir, \"claude\")));\n}\n\n/**\n * Structured error thrown when all credentials for a provider are in a\n * backoff window. Carries typed metadata so callers (e.g. the auto-loop)\n * can make informed retry decisions instead of string-matching the message.\n */\nexport class CredentialCooldownError extends Error {\n\treadonly code = \"AUTH_COOLDOWN\" as const;\n\t/** Milliseconds until the earliest credential becomes available, or undefined if unknown. */\n\treadonly retryAfterMs: number | undefined;\n\n\tconstructor(provider: string, retryAfterMs?: number) {\n\t\tsuper(\n\t\t\t`All credentials for \"${provider}\" are in a cooldown window. ` +\n\t\t\t\t`Please wait a moment and try again, or switch to a different provider.`,\n\t\t);\n\t\tthis.name = \"CredentialCooldownError\";\n\t\tthis.retryAfterMs = retryAfterMs;\n\t}\n}\n\nexport function canRestoreSessionModel(\n\tmodelRegistry: Pick<ModelRegistry, \"isProviderRequestReady\">,\n\tmodel: Model<any>,\n): boolean {\n\treturn modelRegistry.isProviderRequestReady(model.provider);\n}\nimport { Agent, type AgentMessage, type ThinkingLevel } from \"@gsd/pi-agent-core\";\nimport type { Message, Model } from \"@gsd/pi-ai\";\nimport { getAgentDir, getDocsPath } from \"../config.js\";\nimport { AgentSession } from \"./agent-session.js\";\nimport { AuthStorage } from \"./auth-storage.js\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.js\";\nimport type { ExtensionRunner, LoadExtensionsResult, ToolDefinition } from \"./extensions/index.js\";\nimport { convertToLlm } from \"./messages.js\";\nimport { ModelRegistry } from \"./model-registry.js\";\nimport { findInitialModel } from \"./model-resolver.js\";\nimport type { ResourceLoader } from \"./resource-loader.js\";\nimport { DefaultResourceLoader } from \"./resource-loader.js\";\nimport { SessionManager } from \"./session-manager.js\";\nimport { SettingsManager } from \"./settings-manager.js\";\nimport { time } from \"./timings.js\";\nimport {\n\tallTools,\n\tbashTool,\n\tcodingTools,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\teditTool,\n\tfindTool,\n\tgrepTool,\n\thashlineCodingTools,\n\thashlineEditTool,\n\thashlineReadTool,\n\tcreateHashlineCodingTools,\n\tcreateHashlineEditTool,\n\tcreateHashlineReadTool,\n\tlsTool,\n\treadOnlyTools,\n\treadTool,\n\ttype Tool,\n\ttype ToolName,\n\twriteTool,\n} from \"./tools/index.js\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.pi/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: new ModelRegistry(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\n\t/** Built-in tools to use. Default: codingTools [read, bash, edit, write] */\n\ttools?: Tool[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\t/**\n\t * Additional tool names to activate after extensions/MCP servers register.\n\t * Names that are not registered by any extension are silently ignored\n\t * by AgentSession.setActiveToolsByName.\n\t *\n\t * Used by --tools to forward names that don't match a built-in (likely\n\t * extension- or MCP-provided), so subagents whose frontmatter declares\n\t * extension tools don't end up with an empty tool list.\n\t */\n\textraActiveToolNames?: string[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\n\t/** Optional: check if the claude-code CLI provider is ready (installed + authed).\n\t * Passed to RetryHandler for third-party block recovery (#3772). */\n\tisClaudeCodeReady?: () => boolean;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandLocation,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.js\";\nexport type { PromptTemplate } from \"./prompt-templates.js\";\nexport type { Skill } from \"./skills.js\";\nexport type { Tool } from \"./tools/index.js\";\n\nexport {\n\t// Pre-built tools (use process.cwd())\n\treadTool,\n\tbashTool,\n\teditTool,\n\twriteTool,\n\tgrepTool,\n\tfindTool,\n\tlsTool,\n\tcodingTools,\n\treadOnlyTools,\n\tallTools as allBuiltInTools,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n\t// Hashline edit mode\n\thashlineCodingTools,\n\thashlineEditTool,\n\thashlineReadTool,\n\tcreateHashlineCodingTools,\n\tcreateHashlineEditTool,\n\tcreateHashlineReadTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from '@gsd/pi-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [readTool, bashTool],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = options.cwd ?? process.cwd();\n\tconst agentDir = options.agentDir ?? getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? new ModelRegistry(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd);\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Flush provider registrations queued during extension loading so that\n\t// extension models (e.g. pi-claude-cli) are visible in the registry before\n\t// findInitialModel() runs. bindCore() repeats this flush as a safety net\n\t// for any late-arriving registrations.\n\tconst { runtime: extensionRuntime } = resourceLoader.getExtensions();\n\tfor (const { name, config } of extensionRuntime.pendingProviderRegistrations) {\n\t\tmodelRegistry.registerProvider(name, config);\n\t}\n\textensionRuntime.pendingProviderRegistrations = [];\n\n\t// Check if session has existing data to restore\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\t\tif (restoredModel && canRestoreSessionModel(modelRegistry, restoredModel)) {\n\t\t\t\tmodel = restoredModel;\n\t\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// Flush extension provider registrations so extension-provided models (e.g. claude-code/*)\n\t// are available in the registry before model resolution. Without this, findInitialModel()\n\t// cannot find extension models and falls back to built-in providers (#3534).\n\tconst extensionsForModelResolution = resourceLoader.getExtensions();\n\tfor (const { name, config } of extensionsForModelResolution.runtime.pendingProviderRegistrations) {\n\t\tmodelRegistry.registerProvider(name, config);\n\t}\n\t// Clear the queue so bindCore() doesn't re-register the same providers.\n\textensionsForModelResolution.runtime.pendingProviderRegistrations = [];\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `No models available. Use /login or set an API key environment variable. See ${join(getDocsPath(), \"providers.md\")}. Then use /model to select a model.`;\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model || !model.reasoning) {\n\t\tthinkingLevel = \"off\";\n\t}\n\n\tconst editMode = settingsManager.getEditMode();\n\tconst defaultActiveToolNames: ToolName[] = editMode === \"hashline\"\n\t\t? [\"hashline_read\", \"bash\", \"hashline_edit\", \"write\", \"lsp\"]\n\t\t: [\"read\", \"bash\", \"edit\", \"write\", \"lsp\"];\n\tconst builtinActiveToolNames: ToolName[] = options.tools\n\t\t? options.tools.map((t) => t.name).filter((n): n is ToolName => n in allTools)\n\t\t: defaultActiveToolNames;\n\t// Merge in extension/MCP tool names from --tools that didn't match a built-in.\n\t// AgentSession.setActiveToolsByName silently drops names that aren't in the\n\t// registry, so unknown names are harmless here.\n\tconst initialActiveToolNames: string[] = options.extraActiveToolNames\n\t\t? [...builtinActiveToolNames, ...options.extraActiveToolNames]\n\t\t: builtinActiveToolNames;\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tonPayload: async (payload, currentModel) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload, currentModel);\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getRetrySettings().maxDelayMs,\n\t\texternalToolExecution: (m) => modelRegistry.getProviderAuthMode(m.provider) === \"externalCli\",\n\t\tgetProviderOptions: async (currentModel) => {\n\t\t\tif (currentModel.provider !== \"claude-code\") return undefined;\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasUI()) return undefined;\n\t\t\treturn {\n\t\t\t\textensionUIContext: runner.getUIContext(),\n\t\t\t};\n\t\t},\n\t\tgetApiKey: async (provider) => {\n\t\t\t// Use the provider argument from the in-flight request;\n\t\t\t// agent.state.model may already be switched mid-turn.\n\t\t\tconst resolvedProvider = provider || agent.state.model?.provider;\n\t\t\tif (!resolvedProvider) {\n\t\t\t\tthrow new Error(\"No model selected\");\n\t\t\t}\n\t\t\tconst authMode = modelRegistry.getProviderAuthMode(resolvedProvider);\n\t\t\tif (authMode === \"externalCli\" || authMode === \"none\") {\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\t// Retry key resolution with backoff to handle transient network failures\n\t\t\t// (e.g., OAuth token refresh failing due to brief connectivity loss).\n\t\t\t// When credentials are in a cooldown window (e.g., after a 429), wait\n\t\t\t// for the backoff to expire instead of using fixed delays that are\n\t\t\t// shorter than the cooldown duration.\n\t\t\tconst maxAttempts = 3;\n\t\t\tconst baseDelayMs = 2000;\n\t\t\tconst maxCooldownWaitMs = 60_000; // Don't wait longer than 60s (skip quota-exhausted 30min backoffs)\n\t\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\t\tconst key = await modelRegistry.getApiKeyForProvider(resolvedProvider);\n\t\t\t\tif (key) return key;\n\n\t\t\t\t// On the last attempt, fall through to error handling below\n\t\t\t\tif (attempt >= maxAttempts) break;\n\n\t\t\t\t// Only retry if credentials exist (network issue) — no point retrying\n\t\t\t\t// when there are genuinely no credentials configured.\n\t\t\t\tconst hasAuth = modelRegistry.authStorage.hasAuth(resolvedProvider);\n\t\t\t\tconst model = agent.state.model;\n\t\t\t\tconst isOAuth = model && modelRegistry.isUsingOAuth(model);\n\t\t\t\tif (!hasAuth && !isOAuth) break;\n\n\t\t\t\t// If credentials are in a cooldown window, wait for the earliest\n\t\t\t\t// one to expire rather than using a fixed delay that's too short.\n\t\t\t\tconst backoffExpiry = modelRegistry.authStorage.getEarliestBackoffExpiry(resolvedProvider);\n\t\t\t\tif (backoffExpiry !== undefined) {\n\t\t\t\t\tconst waitMs = backoffExpiry - Date.now() + 500; // 500ms buffer\n\t\t\t\t\tif (waitMs > 0 && waitMs <= maxCooldownWaitMs) {\n\t\t\t\t\t\tawait new Promise(resolve => setTimeout(resolve, waitMs));\n\t\t\t\t\t\tcontinue; // Retry immediately after cooldown clears\n\t\t\t\t\t}\n\t\t\t\t\tif (waitMs > maxCooldownWaitMs) {\n\t\t\t\t\t\tbreak; // Quota-exhausted or very long backoff — don't block\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Standard exponential backoff for non-cooldown transient failures\n\t\t\t\tawait new Promise(resolve => setTimeout(resolve, baseDelayMs * attempt));\n\t\t\t}\n\n\t\t\t// All retries exhausted — throw descriptive error.\n\t\t\t// Check if credentials exist but are temporarily in a backoff window\n\t\t\t// (e.g., after a 429). This message intentionally avoids phrases like\n\t\t\t// \"rate limit\" / \"429\" to prevent isRetryableError() from re-entering\n\t\t\t// the retry handler and creating cascading error entries (#3429).\n\t\t\tconst hasAuth = modelRegistry.authStorage.hasAuth(resolvedProvider);\n\t\t\tif (hasAuth) {\n\t\t\t\t// Anthropic OAuth was removed in v2.74.0 for TOS compliance (#3952).\n\t\t\t\t// Users who upgraded from an older version may still have OAuth\n\t\t\t\t// credentials in auth.json that will never resolve to a valid API key.\n\t\t\t\tif (\n\t\t\t\t\tresolvedProvider === \"anthropic\" &&\n\t\t\t\t\tmodelRegistry.authStorage.hasLegacyOAuthCredential(resolvedProvider)\n\t\t\t\t) {\n\t\t\t\t\t// Self-heal: strip the stale oauth entry so hasAuth() stops lying\n\t\t\t\t\t// about anthropic being configured. This preserves any api_key\n\t\t\t\t\t// credentials alongside it.\n\t\t\t\t\tconst removed = modelRegistry.authStorage.removeLegacyOAuthCredential(resolvedProvider);\n\t\t\t\t\tif (removed) {\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`[auth] Removed unsupported Anthropic OAuth credential from auth.json (#3952).`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif (isClaudeCodeBinaryInPath()) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Removed stale Anthropic OAuth credential (OAuth support removed in v2.74.0). ` +\n\t\t\t\t\t\t\t\t`Your current model's provider is set to \"anthropic\" but the local Claude Code CLI ` +\n\t\t\t\t\t\t\t\t`is available — switch the model's provider to \"claude-code\" in your preferences ` +\n\t\t\t\t\t\t\t\t`to use it, or set ANTHROPIC_API_KEY to continue with the Anthropic API directly.`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Removed stale Anthropic OAuth credential (OAuth support removed in v2.74.0). ` +\n\t\t\t\t\t\t\t`Set ANTHROPIC_API_KEY, run '/login' and paste an API key, or switch to a different provider.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst expiry = modelRegistry.authStorage.getEarliestBackoffExpiry(resolvedProvider);\n\t\t\t\tconst retryAfterMs = expiry !== undefined ? Math.max(0, expiry - Date.now()) : undefined;\n\t\t\t\tthrow new CredentialCooldownError(resolvedProvider, retryAfterMs);\n\t\t\t}\n\t\t\tconst model = agent.state.model;\n\t\t\tconst isOAuth = model && modelRegistry.isUsingOAuth(model);\n\t\t\tif (isOAuth) {\n\t\t\t\t// If credentials exist but are all in a backoff window (quota / rate-limit),\n\t\t\t\t// surface a specific message instead of the misleading \"Authentication failed\".\n\t\t\t\tif (modelRegistry.authStorage.areAllCredentialsBackedOff(resolvedProvider)) {\n\t\t\t\t\tconst expiry = modelRegistry.authStorage.getEarliestBackoffExpiry(resolvedProvider);\n\t\t\t\t\tconst retryAfterMs = expiry !== undefined ? Math.max(0, expiry - Date.now()) : undefined;\n\t\t\t\t\tthrow new CredentialCooldownError(resolvedProvider, retryAfterMs);\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Authentication failed for \"${resolvedProvider}\". ` +\n\t\t\t\t\t\t`Credentials may have expired or network is unavailable. ` +\n\t\t\t\t\t\t`Run '/login ${resolvedProvider}' to re-authenticate.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new Error(\n\t\t\t\t`No API key found for \"${resolvedProvider}\". ` +\n\t\t\t\t\t`Set an API key environment variable or run '/login ${resolvedProvider}'.`,\n\t\t\t);\n\t\t},\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.replaceMessages(existingSession.messages);\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\textensionRunnerRef,\n\t\tisClaudeCodeReady: options.isClaudeCodeReady,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
3
3
|
import { describe, it } from "node:test";
|
|
4
4
|
import assert from "node:assert/strict";
|
|
5
|
-
import { CredentialCooldownError } from "./sdk.js";
|
|
5
|
+
import { canRestoreSessionModel, CredentialCooldownError } from "./sdk.js";
|
|
6
6
|
// ─── CredentialCooldownError ──────────────────────────────────────────────────
|
|
7
7
|
describe("CredentialCooldownError", () => {
|
|
8
8
|
it("is an instance of Error", () => {
|
|
@@ -68,4 +68,22 @@ describe("CredentialCooldownError", () => {
|
|
|
68
68
|
assert.equal(plain.retryAfterMs, 15_000);
|
|
69
69
|
});
|
|
70
70
|
});
|
|
71
|
+
describe("canRestoreSessionModel", () => {
|
|
72
|
+
const model = {
|
|
73
|
+
provider: "claude-code",
|
|
74
|
+
id: "claude-sonnet",
|
|
75
|
+
};
|
|
76
|
+
it("allows keyless external providers when the provider is request-ready", () => {
|
|
77
|
+
const registry = {
|
|
78
|
+
isProviderRequestReady: (provider) => provider === "claude-code",
|
|
79
|
+
};
|
|
80
|
+
assert.equal(canRestoreSessionModel(registry, model), true);
|
|
81
|
+
});
|
|
82
|
+
it("blocks restore when the provider is not request-ready", () => {
|
|
83
|
+
const registry = {
|
|
84
|
+
isProviderRequestReady: () => false,
|
|
85
|
+
};
|
|
86
|
+
assert.equal(canRestoreSessionModel(registry, model), false);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
71
89
|
//# sourceMappingURL=sdk.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.test.js","sourceRoot":"","sources":["../../src/core/sdk.test.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,4DAA4D;AAE5D,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"sdk.test.js","sourceRoot":"","sources":["../../src/core/sdk.test.ts"],"names":[],"mappings":"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","sourcesContent":["// pi-coding-agent / CredentialCooldownError unit tests\n// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>\n\nimport { describe, it } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { canRestoreSessionModel, CredentialCooldownError } from \"./sdk.js\";\nimport type { Model } from \"@gsd/pi-ai\";\n\n// ─── CredentialCooldownError ──────────────────────────────────────────────────\n\ndescribe(\"CredentialCooldownError\", () => {\n\tit(\"is an instance of Error\", () => {\n\t\tconst err = new CredentialCooldownError(\"anthropic\");\n\t\tassert.ok(err instanceof Error);\n\t});\n\n\tit(\"has name set to CredentialCooldownError\", () => {\n\t\tconst err = new CredentialCooldownError(\"anthropic\");\n\t\tassert.equal(err.name, \"CredentialCooldownError\");\n\t});\n\n\tit(\"has code set to AUTH_COOLDOWN\", () => {\n\t\tconst err = new CredentialCooldownError(\"anthropic\");\n\t\tassert.equal(err.code, \"AUTH_COOLDOWN\");\n\t});\n\n\tit(\"message includes the provider name\", () => {\n\t\tconst err = new CredentialCooldownError(\"openai\");\n\t\tassert.ok(\n\t\t\terr.message.includes(\"openai\"),\n\t\t\t`Expected message to include provider \"openai\", got: ${err.message}`,\n\t\t);\n\t});\n\n\tit(\"message mentions cooldown window\", () => {\n\t\tconst err = new CredentialCooldownError(\"anthropic\");\n\t\tassert.ok(\n\t\t\t/cooldown window/i.test(err.message),\n\t\t\t`Expected message to mention \"cooldown window\", got: ${err.message}`,\n\t\t);\n\t});\n\n\tit(\"retryAfterMs is undefined when not provided\", () => {\n\t\tconst err = new CredentialCooldownError(\"anthropic\");\n\t\tassert.equal(err.retryAfterMs, undefined);\n\t});\n\n\tit(\"retryAfterMs holds the provided value when specified\", () => {\n\t\tconst err = new CredentialCooldownError(\"anthropic\", 30_000);\n\t\tassert.equal(err.retryAfterMs, 30_000);\n\t});\n\n\tit(\"retryAfterMs is 0 when explicitly passed as 0\", () => {\n\t\tconst err = new CredentialCooldownError(\"anthropic\", 0);\n\t\tassert.equal(err.retryAfterMs, 0);\n\t});\n\n\tit(\"code property is readonly and always AUTH_COOLDOWN regardless of provider\", () => {\n\t\tfor (const provider of [\"anthropic\", \"openai\", \"google\", \"openrouter\"]) {\n\t\t\tconst err = new CredentialCooldownError(provider);\n\t\t\tassert.equal(err.code, \"AUTH_COOLDOWN\", `code should be AUTH_COOLDOWN for provider \"${provider}\"`);\n\t\t}\n\t});\n\n\tit(\"different providers produce different messages\", () => {\n\t\tconst err1 = new CredentialCooldownError(\"anthropic\");\n\t\tconst err2 = new CredentialCooldownError(\"openai\");\n\t\tassert.notEqual(err1.message, err2.message);\n\t});\n\n\tit(\"can be caught as an Error in a try/catch\", () => {\n\t\tlet caught: unknown;\n\t\ttry {\n\t\t\tthrow new CredentialCooldownError(\"anthropic\", 5_000);\n\t\t} catch (e) {\n\t\t\tcaught = e;\n\t\t}\n\t\tassert.ok(caught instanceof Error);\n\t\tassert.ok(caught instanceof CredentialCooldownError);\n\t\tassert.equal((caught as CredentialCooldownError).retryAfterMs, 5_000);\n\t});\n\n\tit(\"code property is detectable via plain object check (cross-process pattern)\", () => {\n\t\tconst err = new CredentialCooldownError(\"anthropic\", 15_000);\n\t\t// Simulate cross-process serialization: only plain properties survive JSON round-trip\n\t\tconst plain = { code: err.code, retryAfterMs: err.retryAfterMs, message: err.message };\n\t\tassert.equal(plain.code, \"AUTH_COOLDOWN\");\n\t\tassert.equal(plain.retryAfterMs, 15_000);\n\t});\n});\n\ndescribe(\"canRestoreSessionModel\", () => {\n\tconst model = {\n\t\tprovider: \"claude-code\",\n\t\tid: \"claude-sonnet\",\n\t} as Model<any>;\n\n\tit(\"allows keyless external providers when the provider is request-ready\", () => {\n\t\tconst registry = {\n\t\t\tisProviderRequestReady: (provider: string) => provider === \"claude-code\",\n\t\t};\n\n\t\tassert.equal(canRestoreSessionModel(registry, model), true);\n\t});\n\n\tit(\"blocks restore when the provider is not request-ready\", () => {\n\t\tconst registry = {\n\t\t\tisProviderRequestReady: () => false,\n\t\t};\n\n\t\tassert.equal(canRestoreSessionModel(registry, model), false);\n\t});\n});\n"]}
|
|
@@ -22,6 +22,26 @@ export interface BuildSystemPromptOptions {
|
|
|
22
22
|
}>;
|
|
23
23
|
/** Pre-loaded skills. */
|
|
24
24
|
skills?: Skill[];
|
|
25
|
+
/**
|
|
26
|
+
* Optional predicate applied to the `skills` list before rendering the
|
|
27
|
+
* <available_skills> catalog. Returning `false` omits a skill from the
|
|
28
|
+
* prompt (the skill remains loaded and invocable by name — only the
|
|
29
|
+
* catalog listing is suppressed).
|
|
30
|
+
*
|
|
31
|
+
* Intended for consumers that can narrow the relevant skill surface
|
|
32
|
+
* (e.g. per-unit-type manifests) to reduce cached system-prompt bloat.
|
|
33
|
+
* When omitted, all non-`disableModelInvocation` skills render — i.e.
|
|
34
|
+
* behavior is unchanged from before this option existed.
|
|
35
|
+
*
|
|
36
|
+
* Contract: the predicate must be **pure and synchronous**. It may be
|
|
37
|
+
* invoked on every system-prompt rebuild (tool-set changes and
|
|
38
|
+
* runtime resource-loader extensions both trigger one), so any state
|
|
39
|
+
* the closure captures should be stable across the rebuild window.
|
|
40
|
+
* If the predicate throws, `buildSystemPrompt` logs a warning and
|
|
41
|
+
* falls back to the unfiltered skill list — callers never see the
|
|
42
|
+
* exception and the session stays consistent.
|
|
43
|
+
*/
|
|
44
|
+
skillFilter?: (skill: Skill) => boolean;
|
|
25
45
|
}
|
|
26
46
|
/** Build the system prompt with tools, guidelines, and context */
|
|
27
47
|
export declare function buildSystemPrompt(options?: BuildSystemPromptOptions): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAchE,MAAM,WAAW,wBAAwB;IACxC,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,uCAAuC;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,yBAAyB;IACzB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAchE,MAAM,WAAW,wBAAwB;IACxC,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,uCAAuC;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,yBAAyB;IACzB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;IACjB;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC;CACxC;AAED,kEAAkE;AAClE,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,MAAM,CA2NhF"}
|