gsd-pi 2.74.0-dev.2b524c3 → 2.74.0-dev.658744a
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/dist/cli.js +85 -0
- package/dist/headless-query.js +4 -1
- package/dist/help-text.js +23 -0
- package/dist/resources/extensions/gsd/activity-log.js +16 -0
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +11 -4
- package/dist/resources/extensions/gsd/auto/loop.js +147 -10
- package/dist/resources/extensions/gsd/auto/phases.js +209 -10
- package/dist/resources/extensions/gsd/auto/session.js +10 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +11 -1
- package/dist/resources/extensions/gsd/auto-model-selection.js +54 -8
- package/dist/resources/extensions/gsd/auto-post-unit.js +220 -17
- package/dist/resources/extensions/gsd/auto-prompts.js +12 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +24 -10
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +18 -0
- package/dist/resources/extensions/gsd/auto-verification.js +100 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +2 -0
- package/dist/resources/extensions/gsd/auto.js +36 -4
- package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +5 -3
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +30 -8
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +61 -9
- package/dist/resources/extensions/gsd/cache.js +16 -5
- package/dist/resources/extensions/gsd/commands/catalog.js +31 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +5 -1
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +25 -0
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +68 -9
- package/dist/resources/extensions/gsd/commands-add-tests.js +111 -0
- package/dist/resources/extensions/gsd/commands-backlog.js +140 -0
- package/dist/resources/extensions/gsd/commands-do.js +79 -0
- package/dist/resources/extensions/gsd/commands-extract-learnings.js +225 -0
- package/dist/resources/extensions/gsd/commands-maintenance.js +6 -6
- package/dist/resources/extensions/gsd/commands-pr-branch.js +180 -0
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +51 -4
- package/dist/resources/extensions/gsd/commands-session-report.js +82 -0
- package/dist/resources/extensions/gsd/commands-ship.js +187 -0
- package/dist/resources/extensions/gsd/db-writer.js +3 -5
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +16 -1
- package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +144 -0
- package/dist/resources/extensions/gsd/ecosystem/loader.js +145 -0
- package/dist/resources/extensions/gsd/git-service.js +49 -1
- package/dist/resources/extensions/gsd/graph-context.js +157 -0
- package/dist/resources/extensions/gsd/gsd-db.js +581 -2
- package/dist/resources/extensions/gsd/guided-flow.js +31 -6
- package/dist/resources/extensions/gsd/index.js +15 -2
- package/dist/resources/extensions/gsd/init-wizard.js +1 -0
- package/dist/resources/extensions/gsd/journal.js +27 -0
- package/dist/resources/extensions/gsd/md-importer.js +3 -4
- package/dist/resources/extensions/gsd/memory-store.js +19 -51
- package/dist/resources/extensions/gsd/metrics.js +19 -0
- package/dist/resources/extensions/gsd/milestone-validation-gates.js +13 -12
- package/dist/resources/extensions/gsd/native-git-bridge.js +7 -4
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +33 -1
- package/dist/resources/extensions/gsd/preferences-models.js +20 -3
- package/dist/resources/extensions/gsd/preferences-types.js +2 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +118 -2
- package/dist/resources/extensions/gsd/preferences.js +31 -0
- package/dist/resources/extensions/gsd/prompts/add-tests.md +35 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +15 -30
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +12 -2
- package/dist/resources/extensions/gsd/state.js +5 -1
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +19 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +20 -0
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +39 -4
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +3 -14
- package/dist/resources/extensions/gsd/triage-resolution.js +2 -5
- package/dist/resources/extensions/gsd/unit-ownership.js +1 -1
- package/dist/resources/extensions/gsd/uok/audit-toggle.js +7 -0
- package/dist/resources/extensions/gsd/uok/audit.js +40 -0
- package/dist/resources/extensions/gsd/uok/contracts.js +1 -0
- package/dist/resources/extensions/gsd/uok/execution-graph.js +179 -0
- package/dist/resources/extensions/gsd/uok/flags.js +29 -0
- package/dist/resources/extensions/gsd/uok/gate-runner.js +109 -0
- package/dist/resources/extensions/gsd/uok/gitops.js +53 -0
- package/dist/resources/extensions/gsd/uok/kernel.js +80 -0
- package/dist/resources/extensions/gsd/uok/loop-adapter.js +133 -0
- package/dist/resources/extensions/gsd/uok/model-policy.js +66 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +132 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +22 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +8 -69
- package/dist/resources/extensions/gsd/workflow-migration.js +21 -22
- package/dist/resources/extensions/gsd/workflow-projections.js +4 -1
- package/dist/resources/extensions/gsd/workflow-reconcile.js +14 -11
- package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
- package/dist/tsconfig.extensions.tsbuildinfo +1 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- 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.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
- 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/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/package.json +3 -2
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/dist/index.d.ts +3 -0
- package/packages/mcp-server/dist/index.d.ts.map +1 -1
- package/packages/mcp-server/dist/index.js +3 -0
- package/packages/mcp-server/dist/index.js.map +1 -1
- package/packages/mcp-server/dist/readers/graph.d.ts +87 -0
- package/packages/mcp-server/dist/readers/graph.d.ts.map +1 -0
- package/packages/mcp-server/dist/readers/graph.js +655 -0
- package/packages/mcp-server/dist/readers/graph.js.map +1 -0
- package/packages/mcp-server/dist/readers/index.d.ts +2 -0
- package/packages/mcp-server/dist/readers/index.d.ts.map +1 -1
- package/packages/mcp-server/dist/readers/index.js +1 -0
- package/packages/mcp-server/dist/readers/index.js.map +1 -1
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +65 -0
- 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 +88 -6
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/index.ts +15 -0
- package/packages/mcp-server/src/readers/graph.test.ts +604 -0
- package/packages/mcp-server/src/readers/graph.ts +855 -0
- package/packages/mcp-server/src/readers/index.ts +12 -0
- package/packages/mcp-server/src/server.ts +83 -0
- package/packages/mcp-server/src/workflow-tools.ts +95 -10
- package/packages/mcp-server/tsconfig.json +1 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -0
- package/packages/native/package.json +2 -2
- package/packages/native/tsconfig.tsbuildinfo +1 -0
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/tsconfig.json +1 -0
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -0
- package/packages/pi-ai/dist/index.d.ts +1 -9
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -9
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/models/capability-patches.d.ts +19 -0
- package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/capability-patches.js +36 -0
- package/packages/pi-ai/dist/models/capability-patches.js.map +1 -0
- package/packages/pi-ai/dist/{models.custom.d.ts → models/custom.d.ts} +1 -1
- package/packages/pi-ai/dist/models/custom.d.ts.map +1 -0
- package/packages/pi-ai/dist/{models.custom.js → models/custom.js} +4 -4
- package/packages/pi-ai/dist/models/custom.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +1482 -0
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +1484 -0
- package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/anthropic.d.ts +377 -0
- package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/anthropic.js +379 -0
- package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts +700 -0
- package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/azure-openai-responses.js +702 -0
- package/packages/pi-ai/dist/models/generated/azure-openai-responses.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/cerebras.d.ts +71 -0
- package/packages/pi-ai/dist/models/generated/cerebras.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/cerebras.js +73 -0
- package/packages/pi-ai/dist/models/generated/cerebras.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/github-copilot.d.ts +590 -0
- package/packages/pi-ai/dist/models/generated/github-copilot.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/github-copilot.js +444 -0
- package/packages/pi-ai/dist/models/generated/github-copilot.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +156 -0
- package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-antigravity.js +158 -0
- package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts +105 -0
- package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-gemini-cli.js +107 -0
- package/packages/pi-ai/dist/models/generated/google-gemini-cli.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-vertex.d.ts +207 -0
- package/packages/pi-ai/dist/models/generated/google-vertex.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/google-vertex.js +209 -0
- package/packages/pi-ai/dist/models/generated/google-vertex.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/google.d.ts +462 -0
- package/packages/pi-ai/dist/models/generated/google.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/google.js +464 -0
- package/packages/pi-ai/dist/models/generated/google.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/groq.d.ts +309 -0
- package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/groq.js +311 -0
- package/packages/pi-ai/dist/models/generated/groq.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/huggingface.d.ts +383 -0
- package/packages/pi-ai/dist/models/generated/huggingface.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/huggingface.js +347 -0
- package/packages/pi-ai/dist/models/generated/huggingface.js.map +1 -0
- package/packages/pi-ai/dist/{models.generated.d.ts → models/generated/index.d.ts} +1 -1
- package/packages/pi-ai/dist/{models.generated.d.ts.map → models/generated/index.d.ts.map} +1 -1
- package/packages/pi-ai/dist/models/generated/index.js +51 -0
- package/packages/pi-ai/dist/models/generated/index.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts +37 -0
- package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/kimi-coding.js +39 -0
- package/packages/pi-ai/dist/models/generated/kimi-coding.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts +105 -0
- package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/minimax-cn.js +107 -0
- package/packages/pi-ai/dist/models/generated/minimax-cn.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/minimax.d.ts +105 -0
- package/packages/pi-ai/dist/models/generated/minimax.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/minimax.js +107 -0
- package/packages/pi-ai/dist/models/generated/minimax.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/mistral.d.ts +445 -0
- package/packages/pi-ai/dist/models/generated/mistral.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/mistral.js +447 -0
- package/packages/pi-ai/dist/models/generated/mistral.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +139 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.js +141 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/openai.d.ts +700 -0
- package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/openai.js +702 -0
- package/packages/pi-ai/dist/models/generated/openai.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/opencode-go.d.ts +122 -0
- package/packages/pi-ai/dist/models/generated/opencode-go.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/opencode-go.js +124 -0
- package/packages/pi-ai/dist/models/generated/opencode-go.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/opencode.d.ts +530 -0
- package/packages/pi-ai/dist/models/generated/opencode.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/opencode.js +532 -0
- package/packages/pi-ai/dist/models/generated/opencode.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/openrouter.d.ts +4270 -0
- package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/openrouter.js +4272 -0
- package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts +2604 -0
- package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js +2606 -0
- package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/xai.d.ts +411 -0
- package/packages/pi-ai/dist/models/generated/xai.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/xai.js +413 -0
- package/packages/pi-ai/dist/models/generated/xai.js.map +1 -0
- package/packages/pi-ai/dist/models/generated/zai.d.ts +276 -0
- package/packages/pi-ai/dist/models/generated/zai.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/generated/zai.js +239 -0
- package/packages/pi-ai/dist/models/generated/zai.js.map +1 -0
- package/packages/pi-ai/dist/models/index.d.ts +27 -0
- package/packages/pi-ai/dist/models/index.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/index.js +80 -0
- package/packages/pi-ai/dist/models/index.js.map +1 -0
- package/packages/pi-ai/dist/models.d.ts +1 -36
- package/packages/pi-ai/dist/models.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.test.js +1 -2
- package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
- package/packages/pi-ai/dist/models.js +3 -112
- package/packages/pi-ai/dist/models.js.map +1 -1
- package/packages/pi-ai/dist/models.test.js +6 -5
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/scripts/generate-models.ts +74 -40
- package/packages/pi-ai/src/index.ts +1 -9
- package/packages/pi-ai/src/models/capability-patches.ts +40 -0
- package/packages/pi-ai/src/{models.custom.ts → models/custom.ts} +4 -4
- package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +1486 -0
- package/packages/pi-ai/src/models/generated/anthropic.ts +381 -0
- package/packages/pi-ai/src/models/generated/azure-openai-responses.ts +704 -0
- package/packages/pi-ai/src/models/generated/cerebras.ts +75 -0
- package/packages/pi-ai/src/models/generated/github-copilot.ts +446 -0
- package/packages/pi-ai/src/models/generated/google-antigravity.ts +160 -0
- package/packages/pi-ai/src/models/generated/google-gemini-cli.ts +109 -0
- package/packages/pi-ai/src/models/generated/google-vertex.ts +211 -0
- package/packages/pi-ai/src/models/generated/google.ts +466 -0
- package/packages/pi-ai/src/models/generated/groq.ts +313 -0
- package/packages/pi-ai/src/models/generated/huggingface.ts +349 -0
- package/packages/pi-ai/src/models/generated/index.ts +52 -0
- package/packages/pi-ai/src/models/generated/kimi-coding.ts +41 -0
- package/packages/pi-ai/src/models/generated/minimax-cn.ts +109 -0
- package/packages/pi-ai/src/models/generated/minimax.ts +109 -0
- package/packages/pi-ai/src/models/generated/mistral.ts +449 -0
- package/packages/pi-ai/src/models/generated/openai-codex.ts +143 -0
- package/packages/pi-ai/src/models/generated/openai.ts +704 -0
- package/packages/pi-ai/src/models/generated/opencode-go.ts +126 -0
- package/packages/pi-ai/src/models/generated/opencode.ts +534 -0
- package/packages/pi-ai/src/models/generated/openrouter.ts +4274 -0
- package/packages/pi-ai/src/models/generated/vercel-ai-gateway.ts +2608 -0
- package/packages/pi-ai/src/models/generated/xai.ts +415 -0
- package/packages/pi-ai/src/models/generated/zai.ts +241 -0
- package/packages/pi-ai/src/models/index.ts +106 -0
- package/packages/pi-ai/src/models.generated.test.ts +1 -2
- package/packages/pi-ai/src/models.test.ts +6 -5
- package/packages/pi-ai/src/models.ts +3 -153
- package/packages/pi-ai/tsconfig.json +1 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +8 -2
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +472 -0
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js +52 -0
- package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +11 -0
- 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/assistant-message.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +23 -9
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +47 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +8 -0
- 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 +68 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +22 -22
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +232 -18
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +38 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +14 -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 +70 -6
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +12 -6
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +612 -0
- package/packages/pi-coding-agent/src/core/model-registry-env-fallback.test.ts +59 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +19 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +25 -10
- package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +67 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +83 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +23 -26
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +298 -41
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +44 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +92 -6
- package/packages/pi-coding-agent/src/types/ambient-modules.d.ts +69 -0
- package/packages/pi-coding-agent/tsconfig.json +3 -2
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -0
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/tsconfig.json +1 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -0
- package/packages/rpc-client/package.json +1 -1
- package/packages/rpc-client/tsconfig.json +1 -0
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -0
- package/src/resources/extensions/gsd/activity-log.ts +21 -0
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +12 -4
- package/src/resources/extensions/gsd/auto/loop-deps.ts +10 -0
- package/src/resources/extensions/gsd/auto/loop.ts +159 -10
- package/src/resources/extensions/gsd/auto/phases.ts +261 -10
- package/src/resources/extensions/gsd/auto/session.ts +10 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +16 -6
- package/src/resources/extensions/gsd/auto-model-selection.ts +69 -8
- package/src/resources/extensions/gsd/auto-post-unit.ts +238 -18
- package/src/resources/extensions/gsd/auto-prompts.ts +13 -0
- package/src/resources/extensions/gsd/auto-recovery.ts +29 -9
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +25 -1
- package/src/resources/extensions/gsd/auto-verification.ts +129 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +1 -0
- package/src/resources/extensions/gsd/auto.ts +41 -2
- package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +5 -3
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +38 -8
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +72 -8
- package/src/resources/extensions/gsd/cache.ts +16 -5
- package/src/resources/extensions/gsd/commands/catalog.ts +31 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +5 -1
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +25 -0
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +74 -9
- package/src/resources/extensions/gsd/commands-add-tests.ts +137 -0
- package/src/resources/extensions/gsd/commands-backlog.ts +182 -0
- package/src/resources/extensions/gsd/commands-do.ts +109 -0
- package/src/resources/extensions/gsd/commands-extract-learnings.ts +304 -0
- package/src/resources/extensions/gsd/commands-maintenance.ts +6 -6
- package/src/resources/extensions/gsd/commands-pr-branch.ts +234 -0
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +58 -4
- package/src/resources/extensions/gsd/commands-session-report.ts +101 -0
- package/src/resources/extensions/gsd/commands-ship.ts +219 -0
- package/src/resources/extensions/gsd/db-writer.ts +3 -5
- package/src/resources/extensions/gsd/docs/preferences-reference.md +16 -1
- package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +228 -0
- package/src/resources/extensions/gsd/ecosystem/loader.ts +201 -0
- package/src/resources/extensions/gsd/git-service.ts +68 -0
- package/src/resources/extensions/gsd/graph-context.ts +212 -0
- package/src/resources/extensions/gsd/gsd-db.ts +788 -3
- package/src/resources/extensions/gsd/guided-flow.ts +36 -2
- package/src/resources/extensions/gsd/index.ts +18 -2
- package/src/resources/extensions/gsd/init-wizard.ts +3 -2
- package/src/resources/extensions/gsd/journal.ts +30 -0
- package/src/resources/extensions/gsd/md-importer.ts +3 -5
- package/src/resources/extensions/gsd/memory-store.ts +31 -62
- package/src/resources/extensions/gsd/metrics.ts +26 -0
- package/src/resources/extensions/gsd/milestone-validation-gates.ts +13 -14
- package/src/resources/extensions/gsd/native-git-bridge.ts +11 -12
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +40 -1
- package/src/resources/extensions/gsd/preferences-models.ts +20 -3
- package/src/resources/extensions/gsd/preferences-types.ts +38 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +117 -2
- package/src/resources/extensions/gsd/preferences.ts +34 -0
- package/src/resources/extensions/gsd/prompts/add-tests.md +35 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +15 -31
- package/src/resources/extensions/gsd/session-lock.ts +14 -2
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +20 -1
- package/src/resources/extensions/gsd/state.ts +9 -2
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +19 -0
- package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +177 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +272 -0
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +6 -2
- package/src/resources/extensions/gsd/tests/commands-backlog.test.ts +158 -0
- package/src/resources/extensions/gsd/tests/commands-do.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +340 -0
- package/src/resources/extensions/gsd/tests/commands-pr-branch.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/commands-session-report.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/commands-ship.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +154 -0
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +10 -7
- package/src/resources/extensions/gsd/tests/graph-context.test.ts +337 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +71 -4
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -2
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +40 -1
- package/src/resources/extensions/gsd/tests/preferences.test.ts +145 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +57 -2
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +180 -0
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -5
- package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/uok-flags.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/uok-preferences.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +223 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +26 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +48 -3
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +3 -11
- package/src/resources/extensions/gsd/triage-resolution.ts +2 -7
- package/src/resources/extensions/gsd/types.ts +14 -1
- package/src/resources/extensions/gsd/unit-ownership.ts +2 -2
- package/src/resources/extensions/gsd/uok/audit-toggle.ts +9 -0
- package/src/resources/extensions/gsd/uok/audit.ts +51 -0
- package/src/resources/extensions/gsd/uok/contracts.ts +135 -0
- package/src/resources/extensions/gsd/uok/execution-graph.ts +241 -0
- package/src/resources/extensions/gsd/uok/flags.ts +45 -0
- package/src/resources/extensions/gsd/uok/gate-runner.ts +146 -0
- package/src/resources/extensions/gsd/uok/gitops.ts +75 -0
- package/src/resources/extensions/gsd/uok/kernel.ts +105 -0
- package/src/resources/extensions/gsd/uok/loop-adapter.ts +162 -0
- package/src/resources/extensions/gsd/uok/model-policy.ts +112 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +156 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +27 -1
- package/src/resources/extensions/gsd/workflow-manifest.ts +9 -104
- package/src/resources/extensions/gsd/workflow-migration.ts +21 -29
- package/src/resources/extensions/gsd/workflow-projections.ts +8 -1
- package/src/resources/extensions/gsd/workflow-reconcile.ts +15 -15
- package/src/resources/extensions/ttsr/ttsr-manager.ts +10 -5
- package/packages/pi-ai/dist/models.custom.d.ts.map +0 -1
- package/packages/pi-ai/dist/models.custom.js.map +0 -1
- package/packages/pi-ai/dist/models.generated.js +0 -14343
- package/packages/pi-ai/dist/models.generated.js.map +0 -1
- package/packages/pi-ai/src/models.generated.ts +0 -14345
- /package/dist/web/standalone/.next/static/{YzIEI9sxJy4t5xgClF08g → Es_JWCfFZjIvYZShmjyye}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{YzIEI9sxJy4t5xgClF08g → Es_JWCfFZjIvYZShmjyye}/_ssgManifest.js +0 -0
|
@@ -12,6 +12,7 @@ import { importExtensionModule, type ExtensionAPI, type ExtensionContext } from
|
|
|
12
12
|
import type { AutoSession, SidecarItem } from "./session.js";
|
|
13
13
|
import type { LoopDeps } from "./loop-deps.js";
|
|
14
14
|
import type { PostUnitContext, PreVerificationOpts } from "../auto-post-unit.js";
|
|
15
|
+
import type { Phase } from "../types.js";
|
|
15
16
|
import {
|
|
16
17
|
MAX_RECOVERY_CHARS,
|
|
17
18
|
BUDGET_THRESHOLDS,
|
|
@@ -28,9 +29,19 @@ import { debugLog } from "../debug-logger.js";
|
|
|
28
29
|
import { PROJECT_FILES } from "../detection.js";
|
|
29
30
|
import { MergeConflictError } from "../git-service.js";
|
|
30
31
|
import { setCurrentPhase, clearCurrentPhase } from "../../shared/gsd-phase-state.js";
|
|
32
|
+
import { pauseAutoForProviderError } from "../provider-error-pause.js";
|
|
33
|
+
import { resumeAutoAfterProviderDelay } from "../bootstrap/provider-error-resume.js";
|
|
31
34
|
import { join, basename, dirname, parse as parsePath } from "node:path";
|
|
32
35
|
import { existsSync, cpSync, readdirSync } from "node:fs";
|
|
33
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
logWarning,
|
|
38
|
+
logError,
|
|
39
|
+
_resetLogs,
|
|
40
|
+
drainLogs,
|
|
41
|
+
drainAndSummarize,
|
|
42
|
+
formatForNotification,
|
|
43
|
+
hasAnyIssues,
|
|
44
|
+
} from "../workflow-logger.js";
|
|
34
45
|
import { gsdRoot } from "../paths.js";
|
|
35
46
|
import { atomicWriteSync } from "../atomic-write.js";
|
|
36
47
|
import { verifyExpectedArtifact, diagnoseExpectedArtifact, buildLoopRemediationSteps } from "../auto-recovery.js";
|
|
@@ -39,6 +50,9 @@ import { withTimeout, FINALIZE_PRE_TIMEOUT_MS, FINALIZE_POST_TIMEOUT_MS } from "
|
|
|
39
50
|
import { getEligibleSlices } from "../slice-parallel-eligibility.js";
|
|
40
51
|
import { startSliceParallel } from "../slice-parallel-orchestrator.js";
|
|
41
52
|
import { isDbAvailable, getMilestoneSlices } from "../gsd-db.js";
|
|
53
|
+
import { ensurePlanV2Graph } from "../uok/plan-v2.js";
|
|
54
|
+
import { resolveUokFlags } from "../uok/flags.js";
|
|
55
|
+
import { UokGateRunner } from "../uok/gate-runner.js";
|
|
42
56
|
import { resetEvidence } from "../safety/evidence-collector.js";
|
|
43
57
|
import { createCheckpoint, cleanupCheckpoint, rollbackToCheckpoint } from "../safety/git-checkpoint.js";
|
|
44
58
|
import { resolveSafetyHarnessConfig } from "../safety/safety-harness.js";
|
|
@@ -47,6 +61,15 @@ import {
|
|
|
47
61
|
getRequiredWorkflowToolsForAutoUnit,
|
|
48
62
|
} from "../workflow-mcp.js";
|
|
49
63
|
|
|
64
|
+
// ─── Session timeout auto-resume state ────────────────────────────────────────
|
|
65
|
+
|
|
66
|
+
let consecutiveSessionTimeouts = 0;
|
|
67
|
+
const MAX_SESSION_TIMEOUT_AUTO_RESUMES = 3;
|
|
68
|
+
|
|
69
|
+
export function resetSessionTimeoutState(): void {
|
|
70
|
+
consecutiveSessionTimeouts = 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
50
73
|
// ─── generateMilestoneReport ──────────────────────────────────────────────────
|
|
51
74
|
|
|
52
75
|
/**
|
|
@@ -69,6 +92,17 @@ export function _resolveDispatchGuardBasePath(
|
|
|
69
92
|
return s.originalBasePath || s.basePath;
|
|
70
93
|
}
|
|
71
94
|
|
|
95
|
+
const PLAN_V2_GATE_PHASES: ReadonlySet<Phase> = new Set([
|
|
96
|
+
"executing",
|
|
97
|
+
"summarizing",
|
|
98
|
+
"validating-milestone",
|
|
99
|
+
"completing-milestone",
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
function shouldRunPlanV2Gate(phase: Phase): boolean {
|
|
103
|
+
return PLAN_V2_GATE_PHASES.has(phase);
|
|
104
|
+
}
|
|
105
|
+
|
|
72
106
|
/**
|
|
73
107
|
* Generate and write an HTML milestone report snapshot.
|
|
74
108
|
* Extracted from the milestone-transition block in autoLoop.
|
|
@@ -159,6 +193,29 @@ async function closeoutAndStop(
|
|
|
159
193
|
await deps.stopAuto(ctx, pi, reason);
|
|
160
194
|
}
|
|
161
195
|
|
|
196
|
+
async function emitCancelledUnitEnd(
|
|
197
|
+
ic: IterationContext,
|
|
198
|
+
unitType: string,
|
|
199
|
+
unitId: string,
|
|
200
|
+
unitStartSeq: number,
|
|
201
|
+
errorContext?: { message: string; category: string; stopReason?: string; isTransient?: boolean; retryAfterMs?: number },
|
|
202
|
+
): Promise<void> {
|
|
203
|
+
ic.deps.emitJournalEvent({
|
|
204
|
+
ts: new Date().toISOString(),
|
|
205
|
+
flowId: ic.flowId,
|
|
206
|
+
seq: ic.nextSeq(),
|
|
207
|
+
eventType: "unit-end",
|
|
208
|
+
data: {
|
|
209
|
+
unitType,
|
|
210
|
+
unitId,
|
|
211
|
+
status: "cancelled",
|
|
212
|
+
artifactVerified: false,
|
|
213
|
+
...(errorContext ? { errorContext } : {}),
|
|
214
|
+
},
|
|
215
|
+
causedBy: { flowId: ic.flowId, seq: unitStartSeq },
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
162
219
|
// ─── runPreDispatch ───────────────────────────────────────────────────────────
|
|
163
220
|
|
|
164
221
|
/**
|
|
@@ -171,14 +228,60 @@ export async function runPreDispatch(
|
|
|
171
228
|
loopState: LoopState,
|
|
172
229
|
): Promise<PhaseResult<PreDispatchData>> {
|
|
173
230
|
const { ctx, pi, s, deps, prefs } = ic;
|
|
231
|
+
const uokFlags = resolveUokFlags(prefs);
|
|
232
|
+
const runPreDispatchGate = async (input: {
|
|
233
|
+
gateId: string;
|
|
234
|
+
gateType: string;
|
|
235
|
+
outcome: "pass" | "fail" | "retry" | "manual-attention";
|
|
236
|
+
failureClass: "none" | "policy" | "input" | "execution" | "artifact" | "verification" | "closeout" | "git" | "timeout" | "manual-attention" | "unknown";
|
|
237
|
+
rationale: string;
|
|
238
|
+
findings?: string;
|
|
239
|
+
milestoneId?: string;
|
|
240
|
+
}): Promise<void> => {
|
|
241
|
+
if (!uokFlags.gates) return;
|
|
242
|
+
const gateRunner = new UokGateRunner();
|
|
243
|
+
gateRunner.register({
|
|
244
|
+
id: input.gateId,
|
|
245
|
+
type: input.gateType,
|
|
246
|
+
execute: async () => ({
|
|
247
|
+
outcome: input.outcome,
|
|
248
|
+
failureClass: input.failureClass,
|
|
249
|
+
rationale: input.rationale,
|
|
250
|
+
findings: input.findings ?? "",
|
|
251
|
+
}),
|
|
252
|
+
});
|
|
253
|
+
await gateRunner.run(input.gateId, {
|
|
254
|
+
basePath: s.basePath,
|
|
255
|
+
traceId: `pre-dispatch:${ic.flowId}`,
|
|
256
|
+
turnId: `iter-${ic.iteration}`,
|
|
257
|
+
milestoneId: input.milestoneId ?? s.currentMilestoneId ?? undefined,
|
|
258
|
+
unitType: "pre-dispatch",
|
|
259
|
+
unitId: `iter-${ic.iteration}`,
|
|
260
|
+
});
|
|
261
|
+
};
|
|
174
262
|
|
|
175
263
|
// Resource version guard
|
|
176
264
|
const staleMsg = deps.checkResourcesStale(s.resourceVersionOnStart);
|
|
177
265
|
if (staleMsg) {
|
|
266
|
+
await runPreDispatchGate({
|
|
267
|
+
gateId: "resource-version-guard",
|
|
268
|
+
gateType: "policy",
|
|
269
|
+
outcome: "fail",
|
|
270
|
+
failureClass: "policy",
|
|
271
|
+
rationale: "resource version guard blocked dispatch",
|
|
272
|
+
findings: staleMsg,
|
|
273
|
+
});
|
|
178
274
|
await deps.stopAuto(ctx, pi, staleMsg);
|
|
179
275
|
debugLog("autoLoop", { phase: "exit", reason: "resources-stale" });
|
|
180
276
|
return { action: "break", reason: "resources-stale" };
|
|
181
277
|
}
|
|
278
|
+
await runPreDispatchGate({
|
|
279
|
+
gateId: "resource-version-guard",
|
|
280
|
+
gateType: "policy",
|
|
281
|
+
outcome: "pass",
|
|
282
|
+
failureClass: "none",
|
|
283
|
+
rationale: "resource version guard passed",
|
|
284
|
+
});
|
|
182
285
|
|
|
183
286
|
deps.invalidateAllCaches();
|
|
184
287
|
s.lastPromptCharCount = undefined;
|
|
@@ -194,6 +297,14 @@ export async function runPreDispatch(
|
|
|
194
297
|
);
|
|
195
298
|
}
|
|
196
299
|
if (!healthGate.proceed) {
|
|
300
|
+
await runPreDispatchGate({
|
|
301
|
+
gateId: "pre-dispatch-health-gate",
|
|
302
|
+
gateType: "execution",
|
|
303
|
+
outcome: "manual-attention",
|
|
304
|
+
failureClass: "manual-attention",
|
|
305
|
+
rationale: "pre-dispatch health gate blocked dispatch",
|
|
306
|
+
findings: healthGate.reason,
|
|
307
|
+
});
|
|
197
308
|
ctx.ui.notify(
|
|
198
309
|
healthGate.reason || "Pre-dispatch health check failed — run /gsd doctor for details.",
|
|
199
310
|
"error",
|
|
@@ -202,7 +313,23 @@ export async function runPreDispatch(
|
|
|
202
313
|
debugLog("autoLoop", { phase: "exit", reason: "health-gate-failed" });
|
|
203
314
|
return { action: "break", reason: "health-gate-failed" };
|
|
204
315
|
}
|
|
316
|
+
await runPreDispatchGate({
|
|
317
|
+
gateId: "pre-dispatch-health-gate",
|
|
318
|
+
gateType: "execution",
|
|
319
|
+
outcome: "pass",
|
|
320
|
+
failureClass: "none",
|
|
321
|
+
rationale: "pre-dispatch health gate passed",
|
|
322
|
+
findings: healthGate.fixesApplied.length > 0 ? healthGate.fixesApplied.join(", ") : "",
|
|
323
|
+
});
|
|
205
324
|
} catch (e) {
|
|
325
|
+
await runPreDispatchGate({
|
|
326
|
+
gateId: "pre-dispatch-health-gate",
|
|
327
|
+
gateType: "execution",
|
|
328
|
+
outcome: "manual-attention",
|
|
329
|
+
failureClass: "manual-attention",
|
|
330
|
+
rationale: "pre-dispatch health gate threw unexpectedly",
|
|
331
|
+
findings: String(e),
|
|
332
|
+
});
|
|
206
333
|
logWarning("engine", "Pre-dispatch health gate threw unexpectedly", { error: String(e) });
|
|
207
334
|
}
|
|
208
335
|
|
|
@@ -221,6 +348,32 @@ export async function runPreDispatch(
|
|
|
221
348
|
|
|
222
349
|
// Derive state
|
|
223
350
|
let state = await deps.deriveState(s.basePath);
|
|
351
|
+
if (prefs?.uok?.plan_v2?.enabled && shouldRunPlanV2Gate(state.phase)) {
|
|
352
|
+
const compiled = ensurePlanV2Graph(s.basePath, state);
|
|
353
|
+
if (!compiled.ok) {
|
|
354
|
+
const reason = compiled.reason ?? "Plan v2 compilation failed";
|
|
355
|
+
await runPreDispatchGate({
|
|
356
|
+
gateId: "plan-v2-gate",
|
|
357
|
+
gateType: "policy",
|
|
358
|
+
outcome: "manual-attention",
|
|
359
|
+
failureClass: "manual-attention",
|
|
360
|
+
rationale: "plan v2 compile gate failed",
|
|
361
|
+
findings: reason,
|
|
362
|
+
milestoneId: state.activeMilestone?.id ?? undefined,
|
|
363
|
+
});
|
|
364
|
+
ctx.ui.notify(`Plan gate failed-closed: ${reason}`, "error");
|
|
365
|
+
await deps.pauseAuto(ctx, pi);
|
|
366
|
+
return { action: "break", reason: "plan-v2-gate-failed" };
|
|
367
|
+
}
|
|
368
|
+
await runPreDispatchGate({
|
|
369
|
+
gateId: "plan-v2-gate",
|
|
370
|
+
gateType: "policy",
|
|
371
|
+
outcome: "pass",
|
|
372
|
+
failureClass: "none",
|
|
373
|
+
rationale: "plan v2 compile gate passed",
|
|
374
|
+
milestoneId: state.activeMilestone?.id ?? undefined,
|
|
375
|
+
});
|
|
376
|
+
}
|
|
224
377
|
deps.syncCmuxSidebar(prefs, state);
|
|
225
378
|
let mid = state.activeMilestone?.id;
|
|
226
379
|
let midTitle = state.activeMilestone?.title;
|
|
@@ -266,7 +419,10 @@ export async function runPreDispatch(
|
|
|
266
419
|
s.basePath,
|
|
267
420
|
mid,
|
|
268
421
|
eligible,
|
|
269
|
-
{
|
|
422
|
+
{
|
|
423
|
+
maxWorkers: prefs.slice_parallel.max_workers ?? 2,
|
|
424
|
+
useExecutionGraph: uokFlags.executionGraph,
|
|
425
|
+
},
|
|
270
426
|
);
|
|
271
427
|
if (result.started.length > 0) {
|
|
272
428
|
ctx.ui.notify(
|
|
@@ -1081,7 +1237,13 @@ export async function runUnitPhase(
|
|
|
1081
1237
|
);
|
|
1082
1238
|
const previousTier = s.currentUnitRouting?.tier;
|
|
1083
1239
|
|
|
1240
|
+
// Scope workflow-logger buffer to this unit so post-finalize drains are
|
|
1241
|
+
// per-unit. Without this, the module-level _buffer accumulates across every
|
|
1242
|
+
// unit in the same Node process (see workflow-logger.ts module header).
|
|
1243
|
+
_resetLogs();
|
|
1084
1244
|
s.currentUnit = { type: unitType, id: unitId, startedAt: Date.now() };
|
|
1245
|
+
s.lastGitActionFailure = null;
|
|
1246
|
+
s.lastGitActionStatus = null;
|
|
1085
1247
|
setCurrentPhase(unitType);
|
|
1086
1248
|
s.lastToolInvocationError = null; // #2883: clear stale error from previous unit
|
|
1087
1249
|
const unitStartSeq = ic.nextSeq();
|
|
@@ -1347,27 +1509,93 @@ export async function runUnitPhase(
|
|
|
1347
1509
|
// Provider-error pause: pauseAuto already handled cleanup and scheduled
|
|
1348
1510
|
// recovery. Don't hard-stop — just break out of the loop (#2762).
|
|
1349
1511
|
if (unitResult.errorContext?.category === "provider") {
|
|
1512
|
+
await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
|
|
1350
1513
|
debugLog("autoLoop", { phase: "exit", reason: "provider-pause", isTransient: unitResult.errorContext.isTransient });
|
|
1351
1514
|
return { action: "break", reason: "provider-pause" };
|
|
1352
1515
|
}
|
|
1353
|
-
//
|
|
1354
|
-
//
|
|
1355
|
-
//
|
|
1516
|
+
// Timeout category covers two distinct scenarios:
|
|
1517
|
+
// 1. Session creation timeout (120s) — transient, auto-resume with backoff
|
|
1518
|
+
// 2. Unit hard timeout (30min+) — stuck agent, pause for manual review
|
|
1356
1519
|
// Structural errors (TypeError, is not a function) are NOT transient
|
|
1357
1520
|
// and must hard-stop to avoid infinite retry loops.
|
|
1358
1521
|
if (
|
|
1359
1522
|
unitResult.errorContext?.isTransient &&
|
|
1360
1523
|
unitResult.errorContext?.category === "timeout"
|
|
1361
1524
|
) {
|
|
1525
|
+
const isSessionCreationTimeout = unitResult.errorContext.message?.includes("Session creation timed out");
|
|
1526
|
+
|
|
1527
|
+
if (isSessionCreationTimeout) {
|
|
1528
|
+
consecutiveSessionTimeouts += 1;
|
|
1529
|
+
const baseRetryAfterMs = 30_000;
|
|
1530
|
+
const retryAfterMs = baseRetryAfterMs * 2 ** Math.max(0, consecutiveSessionTimeouts - 1);
|
|
1531
|
+
const allowAutoResume = consecutiveSessionTimeouts <= MAX_SESSION_TIMEOUT_AUTO_RESUMES;
|
|
1532
|
+
|
|
1533
|
+
if (!allowAutoResume) {
|
|
1534
|
+
ctx.ui.notify(
|
|
1535
|
+
`Session creation timed out ${consecutiveSessionTimeouts} consecutive times for ${unitType} ${unitId}. Pausing for manual review.`,
|
|
1536
|
+
"warning",
|
|
1537
|
+
);
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
debugLog("autoLoop", {
|
|
1541
|
+
phase: "session-timeout-pause",
|
|
1542
|
+
unitType, unitId,
|
|
1543
|
+
consecutiveSessionTimeouts,
|
|
1544
|
+
retryAfterMs,
|
|
1545
|
+
allowAutoResume,
|
|
1546
|
+
});
|
|
1547
|
+
|
|
1548
|
+
const errorDetail = ` for ${unitType} ${unitId}`;
|
|
1549
|
+
await pauseAutoForProviderError(
|
|
1550
|
+
ctx.ui,
|
|
1551
|
+
errorDetail,
|
|
1552
|
+
() => deps.pauseAuto(ctx, pi),
|
|
1553
|
+
{
|
|
1554
|
+
isRateLimit: false,
|
|
1555
|
+
isTransient: allowAutoResume,
|
|
1556
|
+
retryAfterMs,
|
|
1557
|
+
resume: allowAutoResume
|
|
1558
|
+
? () => {
|
|
1559
|
+
void resumeAutoAfterProviderDelay(pi, ctx).catch((err) => {
|
|
1560
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1561
|
+
ctx.ui.notify(
|
|
1562
|
+
`Session timeout recovery failed: ${message}`,
|
|
1563
|
+
"error",
|
|
1564
|
+
);
|
|
1565
|
+
});
|
|
1566
|
+
}
|
|
1567
|
+
: undefined,
|
|
1568
|
+
},
|
|
1569
|
+
);
|
|
1570
|
+
await deps.autoCommitUnit?.(s.basePath, unitType, unitId, ctx);
|
|
1571
|
+
await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
|
|
1572
|
+
return { action: "break", reason: "session-timeout" };
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
// Unit hard timeout (30min+): pause without auto-resume — stuck agent
|
|
1362
1576
|
ctx.ui.notify(
|
|
1363
|
-
`
|
|
1577
|
+
`Unit timed out for ${unitType} ${unitId} (supervision may have failed). Pausing auto-mode.`,
|
|
1364
1578
|
"warning",
|
|
1365
1579
|
);
|
|
1366
|
-
debugLog("autoLoop", { phase: "
|
|
1580
|
+
debugLog("autoLoop", { phase: "unit-hard-timeout-pause", unitType, unitId });
|
|
1367
1581
|
await deps.pauseAuto(ctx, pi);
|
|
1368
|
-
|
|
1582
|
+
await deps.autoCommitUnit?.(s.basePath, unitType, unitId, ctx);
|
|
1583
|
+
await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
|
|
1584
|
+
return { action: "break", reason: "unit-hard-timeout" };
|
|
1369
1585
|
}
|
|
1370
1586
|
// All other cancelled states (structural errors, non-transient failures): hard stop
|
|
1587
|
+
if (s.currentUnit) {
|
|
1588
|
+
await deps.closeoutUnit(
|
|
1589
|
+
ctx,
|
|
1590
|
+
s.basePath,
|
|
1591
|
+
unitType,
|
|
1592
|
+
unitId,
|
|
1593
|
+
s.currentUnit.startedAt,
|
|
1594
|
+
deps.buildSnapshotOpts(unitType, unitId),
|
|
1595
|
+
);
|
|
1596
|
+
}
|
|
1597
|
+
await deps.autoCommitUnit?.(s.basePath, unitType, unitId, ctx);
|
|
1598
|
+
await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
|
|
1371
1599
|
ctx.ui.notify(
|
|
1372
1600
|
`Session creation failed for ${unitType} ${unitId}: ${unitResult.errorContext?.message ?? "unknown"}. Stopping auto-mode.`,
|
|
1373
1601
|
"warning",
|
|
@@ -1383,6 +1611,8 @@ export async function runUnitPhase(
|
|
|
1383
1611
|
// Guard: stopAuto() may have nulled s.currentUnit via s.reset() while
|
|
1384
1612
|
// this coroutine was suspended at `await runUnit(...)` (#2939).
|
|
1385
1613
|
if (s.currentUnit) {
|
|
1614
|
+
// Reset session timeout counter — any successful unit clears the slate
|
|
1615
|
+
consecutiveSessionTimeouts = 0;
|
|
1386
1616
|
await deps.closeoutUnit(
|
|
1387
1617
|
ctx,
|
|
1388
1618
|
s.basePath,
|
|
@@ -1545,6 +1775,9 @@ export async function runFinalize(
|
|
|
1545
1775
|
// cannot mutate state for the next unit (#3757).
|
|
1546
1776
|
s.currentUnit = null;
|
|
1547
1777
|
clearCurrentPhase();
|
|
1778
|
+
// Drop any logger entries from the timed-out unit so they don't bleed
|
|
1779
|
+
// into the next iteration's drain.
|
|
1780
|
+
drainLogs();
|
|
1548
1781
|
loopState.consecutiveFinalizeTimeouts++;
|
|
1549
1782
|
debugLog("autoLoop", {
|
|
1550
1783
|
phase: "pre-verification-timeout",
|
|
@@ -1572,11 +1805,15 @@ export async function runFinalize(
|
|
|
1572
1805
|
|
|
1573
1806
|
const preResult = preResultGuard.value;
|
|
1574
1807
|
if (preResult === "dispatched") {
|
|
1808
|
+
const dispatchedReason = s.lastGitActionFailure
|
|
1809
|
+
? "git-closeout-failure"
|
|
1810
|
+
: "pre-verification-dispatched";
|
|
1575
1811
|
debugLog("autoLoop", {
|
|
1576
1812
|
phase: "exit",
|
|
1577
|
-
reason:
|
|
1813
|
+
reason: dispatchedReason,
|
|
1814
|
+
gitError: s.lastGitActionFailure ?? undefined,
|
|
1578
1815
|
});
|
|
1579
|
-
return { action: "break", reason:
|
|
1816
|
+
return { action: "break", reason: dispatchedReason };
|
|
1580
1817
|
}
|
|
1581
1818
|
if (preResult === "retry") {
|
|
1582
1819
|
if (sidecarItem) {
|
|
@@ -1643,6 +1880,9 @@ export async function runFinalize(
|
|
|
1643
1880
|
// cannot mutate state for the next unit (#3757).
|
|
1644
1881
|
s.currentUnit = null;
|
|
1645
1882
|
clearCurrentPhase();
|
|
1883
|
+
// Drop any logger entries from the timed-out unit so they don't bleed
|
|
1884
|
+
// into the next iteration's drain.
|
|
1885
|
+
drainLogs();
|
|
1646
1886
|
loopState.consecutiveFinalizeTimeouts++;
|
|
1647
1887
|
debugLog("autoLoop", {
|
|
1648
1888
|
phase: "post-verification-timeout",
|
|
@@ -1687,5 +1927,16 @@ export async function runFinalize(
|
|
|
1687
1927
|
// Both pre and post verification completed without timeout — reset counter
|
|
1688
1928
|
loopState.consecutiveFinalizeTimeouts = 0;
|
|
1689
1929
|
|
|
1930
|
+
// Surface accumulated workflow-logger issues for this unit to the user.
|
|
1931
|
+
// Warnings/errors logged during the unit are buffered in the logger and
|
|
1932
|
+
// drained here so the user sees a single consolidated post-unit alert.
|
|
1933
|
+
if (hasAnyIssues()) {
|
|
1934
|
+
const { logs } = drainAndSummarize();
|
|
1935
|
+
if (logs.length > 0) {
|
|
1936
|
+
const severity = logs.some((e) => e.severity === "error") ? "error" : "warning";
|
|
1937
|
+
ctx.ui.notify(formatForNotification(logs), severity);
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1690
1941
|
return { action: "next", data: undefined as void };
|
|
1691
1942
|
}
|
|
@@ -106,6 +106,8 @@ export class AutoSession {
|
|
|
106
106
|
|
|
107
107
|
// ── Current unit ─────────────────────────────────────────────────────────
|
|
108
108
|
currentUnit: CurrentUnit | null = null;
|
|
109
|
+
currentTraceId: string | null = null;
|
|
110
|
+
currentTurnId: string | null = null;
|
|
109
111
|
currentUnitRouting: UnitRouting | null = null;
|
|
110
112
|
currentMilestoneId: string | null = null;
|
|
111
113
|
|
|
@@ -137,6 +139,10 @@ export class AutoSession {
|
|
|
137
139
|
/** Set when a GSD tool execution ends with isError due to malformed/truncated
|
|
138
140
|
* JSON arguments. Checked by postUnitPreVerification to break retry loops. */
|
|
139
141
|
lastToolInvocationError: string | null = null;
|
|
142
|
+
/** Set when turn-level git action fails during closeout. */
|
|
143
|
+
lastGitActionFailure: string | null = null;
|
|
144
|
+
/** Last turn-level git action status captured during finalize. */
|
|
145
|
+
lastGitActionStatus: "ok" | "failed" | null = null;
|
|
140
146
|
|
|
141
147
|
// ── Isolation degradation ────────────────────────────────────────────
|
|
142
148
|
/** Set to true when worktree creation fails; prevents merge of nonexistent branch. */
|
|
@@ -219,6 +225,8 @@ export class AutoSession {
|
|
|
219
225
|
|
|
220
226
|
// Unit
|
|
221
227
|
this.currentUnit = null;
|
|
228
|
+
this.currentTraceId = null;
|
|
229
|
+
this.currentTurnId = null;
|
|
222
230
|
this.currentUnitRouting = null;
|
|
223
231
|
this.currentMilestoneId = null;
|
|
224
232
|
|
|
@@ -250,6 +258,8 @@ export class AutoSession {
|
|
|
250
258
|
this.rewriteAttemptCount = 0;
|
|
251
259
|
this.consecutiveCompleteBootstraps = 0;
|
|
252
260
|
this.lastToolInvocationError = null;
|
|
261
|
+
this.lastGitActionFailure = null;
|
|
262
|
+
this.lastGitActionStatus = null;
|
|
253
263
|
this.isolationDegraded = false;
|
|
254
264
|
this.milestoneMergedInPhases = false;
|
|
255
265
|
this.checkpointSha = null;
|
|
@@ -53,6 +53,8 @@ import {
|
|
|
53
53
|
checkNeedsRunUat,
|
|
54
54
|
} from "./auto-prompts.js";
|
|
55
55
|
import { resolveModelWithFallbacksForUnit } from "./preferences-models.js";
|
|
56
|
+
import { resolveUokFlags } from "./uok/flags.js";
|
|
57
|
+
import { selectReactiveDispatchBatch } from "./uok/execution-graph.js";
|
|
56
58
|
|
|
57
59
|
// ─── Types ────────────────────────────────────────────────────────────────
|
|
58
60
|
|
|
@@ -584,12 +586,20 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
584
586
|
// Only activate reactive dispatch when >1 task is ready
|
|
585
587
|
if (readyIds.length <= 1) return null;
|
|
586
588
|
|
|
587
|
-
const
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
589
|
+
const uokFlags = resolveUokFlags(prefs);
|
|
590
|
+
const selected = uokFlags.executionGraph
|
|
591
|
+
? selectReactiveDispatchBatch({
|
|
592
|
+
graph,
|
|
593
|
+
readyIds,
|
|
594
|
+
maxParallel,
|
|
595
|
+
inFlightOutputs: new Set(),
|
|
596
|
+
}).selected
|
|
597
|
+
: chooseNonConflictingSubset(
|
|
598
|
+
readyIds,
|
|
599
|
+
graph,
|
|
600
|
+
maxParallel,
|
|
601
|
+
new Set(),
|
|
602
|
+
);
|
|
593
603
|
if (selected.length <= 1) return null;
|
|
594
604
|
|
|
595
605
|
// Log graph metrics for observability
|
|
@@ -10,12 +10,14 @@ import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
|
|
|
10
10
|
import type { GSDPreferences } from "./preferences.js";
|
|
11
11
|
import { resolveModelWithFallbacksForUnit, resolveDynamicRoutingConfig } from "./preferences.js";
|
|
12
12
|
import type { ComplexityTier } from "./complexity-classifier.js";
|
|
13
|
-
import { classifyUnitComplexity, tierLabel } from "./complexity-classifier.js";
|
|
13
|
+
import { classifyUnitComplexity, extractTaskMetadata, tierLabel } from "./complexity-classifier.js";
|
|
14
14
|
import { resolveModelForComplexity, escalateTier, getEligibleModels, loadCapabilityOverrides, adjustToolSet, filterToolsForProvider } from "./model-router.js";
|
|
15
15
|
import { getLedger, getProjectTotals } from "./metrics.js";
|
|
16
16
|
import { unitPhaseLabel } from "./auto-dashboard.js";
|
|
17
17
|
import { getSessionModelOverride } from "./session-model-override.js";
|
|
18
18
|
import { logWarning } from "./workflow-logger.js";
|
|
19
|
+
import { resolveUokFlags } from "./uok/flags.js";
|
|
20
|
+
import { applyModelPolicyFilter } from "./uok/model-policy.js";
|
|
19
21
|
|
|
20
22
|
export interface ModelSelectionResult {
|
|
21
23
|
/** Routing metadata for metrics recording */
|
|
@@ -75,6 +77,7 @@ export async function selectAndApplyModel(
|
|
|
75
77
|
/** Explicit /gsd model pin captured at bootstrap for long-running auto loops. */
|
|
76
78
|
sessionModelOverride?: { provider: string; id: string } | null,
|
|
77
79
|
): Promise<ModelSelectionResult> {
|
|
80
|
+
const uokFlags = resolveUokFlags(prefs);
|
|
78
81
|
const effectiveSessionModelOverride = sessionModelOverride === undefined
|
|
79
82
|
? getSessionModelOverride(ctx.sessionManager.getSessionId())
|
|
80
83
|
: (sessionModelOverride ?? undefined);
|
|
@@ -97,6 +100,9 @@ export async function selectAndApplyModel(
|
|
|
97
100
|
|
|
98
101
|
if (modelConfig) {
|
|
99
102
|
const availableModels = ctx.modelRegistry.getAvailable();
|
|
103
|
+
const modelPolicyTraceId = `model:${ctx.sessionManager.getSessionId()}:${Date.now()}`;
|
|
104
|
+
const modelPolicyTurnId = `${unitType}:${unitId}`;
|
|
105
|
+
let policyAllowedModelKeys: Set<string> | null = null;
|
|
100
106
|
|
|
101
107
|
// ─── Dynamic Model Routing ─────────────────────────────────────────
|
|
102
108
|
// Dynamic routing (complexity-based downgrading) only applies in auto-mode.
|
|
@@ -106,8 +112,40 @@ export async function selectAndApplyModel(
|
|
|
106
112
|
if (!isAutoMode) {
|
|
107
113
|
routingConfig.enabled = false;
|
|
108
114
|
}
|
|
115
|
+
// burn-max defaults to quality-first dispatch (no downgrade routing).
|
|
116
|
+
if (prefs?.token_profile === "burn-max") {
|
|
117
|
+
routingConfig.enabled = false;
|
|
118
|
+
}
|
|
109
119
|
let effectiveModelConfig = modelConfig;
|
|
110
120
|
let routingTierLabel = "";
|
|
121
|
+
let routingEligibleModels = availableModels;
|
|
122
|
+
|
|
123
|
+
const taskMetadataForPolicy = unitType === "execute-task"
|
|
124
|
+
? extractTaskMetadata(unitId, basePath)
|
|
125
|
+
: undefined;
|
|
126
|
+
|
|
127
|
+
if (uokFlags.modelPolicy) {
|
|
128
|
+
const policy = applyModelPolicyFilter(
|
|
129
|
+
availableModels,
|
|
130
|
+
{
|
|
131
|
+
basePath,
|
|
132
|
+
traceId: modelPolicyTraceId,
|
|
133
|
+
turnId: modelPolicyTurnId,
|
|
134
|
+
unitType,
|
|
135
|
+
taskMetadata: taskMetadataForPolicy,
|
|
136
|
+
currentProvider: ctx.model?.provider,
|
|
137
|
+
allowCrossProvider: routingConfig.cross_provider !== false,
|
|
138
|
+
requiredTools: pi.getActiveTools(),
|
|
139
|
+
},
|
|
140
|
+
);
|
|
141
|
+
routingEligibleModels = policy.eligible;
|
|
142
|
+
policyAllowedModelKeys = new Set(
|
|
143
|
+
policy.eligible.map((m) => `${m.provider.toLowerCase()}/${m.id.toLowerCase()}`),
|
|
144
|
+
);
|
|
145
|
+
if (routingEligibleModels.length === 0) {
|
|
146
|
+
throw new Error(`Model policy denied all candidate models for ${unitType}/${unitId}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
111
149
|
|
|
112
150
|
// Disable routing for flat-rate providers like GitHub Copilot (#3453).
|
|
113
151
|
// All models cost the same per request, so downgrading to a cheaper
|
|
@@ -115,7 +153,7 @@ export async function selectAndApplyModel(
|
|
|
115
153
|
// Fail-closed: if primary model can't be resolved, fall back to
|
|
116
154
|
// provider-level signals rather than allowing unwanted downgrades.
|
|
117
155
|
if (routingConfig.enabled) {
|
|
118
|
-
const primaryModel = resolveModelId(modelConfig.primary,
|
|
156
|
+
const primaryModel = resolveModelId(modelConfig.primary, routingEligibleModels, ctx.model?.provider);
|
|
119
157
|
if (primaryModel) {
|
|
120
158
|
const primaryFlatRateCtx = buildFlatRateContext(primaryModel.provider, ctx, prefs);
|
|
121
159
|
if (isFlatRateProvider(primaryModel.provider, primaryFlatRateCtx)) {
|
|
@@ -149,8 +187,14 @@ export async function selectAndApplyModel(
|
|
|
149
187
|
const shouldClassify = !isHook || routingConfig.hooks !== false;
|
|
150
188
|
|
|
151
189
|
if (shouldClassify) {
|
|
152
|
-
let classification = classifyUnitComplexity(
|
|
153
|
-
|
|
190
|
+
let classification = classifyUnitComplexity(
|
|
191
|
+
unitType,
|
|
192
|
+
unitId,
|
|
193
|
+
basePath,
|
|
194
|
+
budgetPct,
|
|
195
|
+
taskMetadataForPolicy,
|
|
196
|
+
);
|
|
197
|
+
const availableModelIds = routingEligibleModels.map(m => m.id);
|
|
154
198
|
|
|
155
199
|
// Escalate tier on retry when escalate_on_failure is enabled (default: true)
|
|
156
200
|
if (
|
|
@@ -257,15 +301,28 @@ export async function selectAndApplyModel(
|
|
|
257
301
|
}
|
|
258
302
|
|
|
259
303
|
const modelsToTry = [effectiveModelConfig.primary, ...effectiveModelConfig.fallbacks];
|
|
304
|
+
let attemptedPolicyEligible = false;
|
|
260
305
|
|
|
261
306
|
for (const modelId of modelsToTry) {
|
|
262
|
-
const
|
|
307
|
+
const resolutionPool = uokFlags.modelPolicy ? routingEligibleModels : availableModels;
|
|
308
|
+
const model = resolveModelId(modelId, resolutionPool, ctx.model?.provider);
|
|
263
309
|
|
|
264
310
|
if (!model) {
|
|
265
311
|
if (verbose) ctx.ui.notify(`Model ${modelId} not found, trying fallback.`, "info");
|
|
266
312
|
continue;
|
|
267
313
|
}
|
|
268
314
|
|
|
315
|
+
if (policyAllowedModelKeys) {
|
|
316
|
+
const key = `${model.provider.toLowerCase()}/${model.id.toLowerCase()}`;
|
|
317
|
+
if (!policyAllowedModelKeys.has(key)) {
|
|
318
|
+
if (verbose) {
|
|
319
|
+
ctx.ui.notify(`Model policy denied ${model.provider}/${model.id}; trying fallback.`, "warning");
|
|
320
|
+
}
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
attemptedPolicyEligible = true;
|
|
324
|
+
}
|
|
325
|
+
|
|
269
326
|
// Warn if the ID is ambiguous across providers
|
|
270
327
|
if (!modelId.includes("/")) {
|
|
271
328
|
const providers = availableModels.filter(m => m.id === modelId).map(m => m.provider);
|
|
@@ -331,6 +388,10 @@ export async function selectAndApplyModel(
|
|
|
331
388
|
}
|
|
332
389
|
}
|
|
333
390
|
}
|
|
391
|
+
|
|
392
|
+
if (uokFlags.modelPolicy && policyAllowedModelKeys && !attemptedPolicyEligible) {
|
|
393
|
+
throw new Error(`Model policy denied dispatch for ${unitType}/${unitId} before prompt send`);
|
|
394
|
+
}
|
|
334
395
|
} else if (autoModeStartModel) {
|
|
335
396
|
// No model preference for this unit type — re-apply the model captured
|
|
336
397
|
// at auto-mode start to prevent bleed from shared global settings.json (#650).
|
|
@@ -474,10 +535,10 @@ export function buildFlatRateContext(
|
|
|
474
535
|
prefs?: { flat_rate_providers?: readonly string[] },
|
|
475
536
|
): FlatRateContext {
|
|
476
537
|
let authMode: FlatRateContext["authMode"];
|
|
477
|
-
const
|
|
478
|
-
if (typeof
|
|
538
|
+
const registry = ctx?.modelRegistry;
|
|
539
|
+
if (registry && typeof registry.getProviderAuthMode === "function") {
|
|
479
540
|
try {
|
|
480
|
-
const mode =
|
|
541
|
+
const mode = registry.getProviderAuthMode(provider);
|
|
481
542
|
if (mode === "apiKey" || mode === "oauth" || mode === "externalCli" || mode === "none") {
|
|
482
543
|
authMode = mode;
|
|
483
544
|
}
|