gsd-pi 2.73.1-dev.d987996 β 2.74.0-dev.0306a2e
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-web-branch.d.ts +4 -3
- package/dist/cli-web-branch.js +10 -7
- package/dist/cli.js +184 -206
- package/dist/headless-query.js +4 -1
- package/dist/help-text.js +23 -0
- package/dist/logo.d.ts +1 -1
- package/dist/logo.js +1 -1
- package/dist/onboarding.js +59 -53
- package/dist/resource-loader.js +2 -2
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +68 -4
- 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 +173 -13
- package/dist/resources/extensions/gsd/auto/session.js +10 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +22 -4
- package/dist/resources/extensions/gsd/auto-model-selection.js +105 -16
- package/dist/resources/extensions/gsd/auto-post-unit.js +254 -15
- package/dist/resources/extensions/gsd/auto-prompts.js +12 -0
- package/dist/resources/extensions/gsd/auto-start.js +23 -6
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +13 -0
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +18 -0
- package/dist/resources/extensions/gsd/auto-verification.js +186 -3
- package/dist/resources/extensions/gsd/auto.js +65 -12
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +30 -8
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +41 -2
- package/dist/resources/extensions/gsd/commands/catalog.js +26 -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-handlers.js +8 -2
- 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 +1 -1
- 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 +15 -2
- 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 +23 -0
- 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/notification-widget.js +2 -2
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +33 -1
- package/dist/resources/extensions/gsd/preferences-models.js +63 -3
- package/dist/resources/extensions/gsd/preferences-types.js +2 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +130 -2
- package/dist/resources/extensions/gsd/preferences.js +26 -0
- package/dist/resources/extensions/gsd/prompts/add-tests.md +35 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +12 -2
- package/dist/resources/extensions/gsd/state.js +66 -15
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +18 -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/update-check.d.ts +1 -0
- package/dist/update-check.js +13 -5
- package/dist/update-cmd.js +4 -3
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
- 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 +13 -13
- 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 -3
- 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/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/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 +2 -9
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +2 -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/dist/utils/overflow.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/overflow.js +12 -0
- package/packages/pi-ai/dist/utils/overflow.js.map +1 -1
- package/packages/pi-ai/dist/utils/tests/overflow.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/tests/overflow.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/tests/overflow.test.js +50 -0
- package/packages/pi-ai/dist/utils/tests/overflow.test.js.map +1 -0
- 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 +5 -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/src/utils/overflow.ts +14 -1
- package/packages/pi-ai/src/utils/tests/overflow.test.ts +58 -0
- package/packages/pi-ai/tsconfig.json +1 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -0
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +721 -8
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/utils.js +5 -5
- package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js +45 -0
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js.map +1 -0
- 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/assistant-message.d.ts +12 -2
- 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 +65 -28
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +9 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +52 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -0
- 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 +305 -20
- 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 +13 -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 +59 -6
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +884 -8
- package/packages/pi-coding-agent/src/core/compaction/utils.ts +5 -5
- package/packages/pi-coding-agent/src/core/compaction-utils.test.ts +50 -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/assistant-message.ts +78 -32
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +73 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +9 -3
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +381 -39
- 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 +79 -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/dist/__tests__/tui.test.js +60 -1
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts +8 -0
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +32 -3
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/tui.test.ts +76 -1
- package/packages/pi-tui/src/tui.ts +31 -3
- 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/pkg/package.json +1 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +107 -5
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +111 -2
- 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 +213 -13
- package/src/resources/extensions/gsd/auto/session.ts +10 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +26 -10
- package/src/resources/extensions/gsd/auto-model-selection.ts +151 -16
- package/src/resources/extensions/gsd/auto-post-unit.ts +278 -16
- package/src/resources/extensions/gsd/auto-prompts.ts +13 -0
- package/src/resources/extensions/gsd/auto-start.ts +30 -6
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +17 -0
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +25 -1
- package/src/resources/extensions/gsd/auto-verification.ts +225 -3
- package/src/resources/extensions/gsd/auto.ts +72 -16
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +38 -8
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +52 -2
- package/src/resources/extensions/gsd/commands/catalog.ts +26 -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-handlers.ts +8 -2
- 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 +1 -1
- 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 +15 -2
- 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 +32 -0
- 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/notification-widget.ts +2 -2
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +40 -1
- package/src/resources/extensions/gsd/preferences-models.ts +61 -3
- package/src/resources/extensions/gsd/preferences-types.ts +44 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +130 -2
- package/src/resources/extensions/gsd/preferences.ts +28 -0
- package/src/resources/extensions/gsd/prompts/add-tests.md +35 -0
- 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 +80 -17
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +18 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +9 -5
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +51 -2
- 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-milestone-false-merge.test.ts +142 -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/completed-at-reconcile.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +68 -8
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +3 -3
- 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/flat-rate-routing-guard.test.ts +137 -1
- 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/integration/state-machine-edge-cases.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +68 -1
- 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/model-isolation.test.ts +91 -2
- 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 +47 -0
- 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/state-machine-full-walkthrough.test.ts +5 -7
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +9 -6
- 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-stuck-guard.test.ts +179 -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/{cGmbVq2su4f9tMpgIkG8u β tqdo0yKKYz6fJXQnIgbdx}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{cGmbVq2su4f9tMpgIkG8u β tqdo0yKKYz6fJXQnIgbdx}/_ssgManifest.js +0 -0
|
@@ -16,7 +16,7 @@ import { MergeConflictError } from "../git-service.js";
|
|
|
16
16
|
import { setCurrentPhase, clearCurrentPhase } from "../../shared/gsd-phase-state.js";
|
|
17
17
|
import { join, basename, dirname, parse as parsePath } from "node:path";
|
|
18
18
|
import { existsSync, cpSync, readdirSync } from "node:fs";
|
|
19
|
-
import { logWarning, logError } from "../workflow-logger.js";
|
|
19
|
+
import { logWarning, logError, _resetLogs, drainLogs, drainAndSummarize, formatForNotification, hasAnyIssues, } from "../workflow-logger.js";
|
|
20
20
|
import { gsdRoot } from "../paths.js";
|
|
21
21
|
import { atomicWriteSync } from "../atomic-write.js";
|
|
22
22
|
import { verifyExpectedArtifact, diagnoseExpectedArtifact, buildLoopRemediationSteps } from "../auto-recovery.js";
|
|
@@ -25,6 +25,9 @@ import { withTimeout, FINALIZE_PRE_TIMEOUT_MS, FINALIZE_POST_TIMEOUT_MS } from "
|
|
|
25
25
|
import { getEligibleSlices } from "../slice-parallel-eligibility.js";
|
|
26
26
|
import { startSliceParallel } from "../slice-parallel-orchestrator.js";
|
|
27
27
|
import { isDbAvailable, getMilestoneSlices } from "../gsd-db.js";
|
|
28
|
+
import { ensurePlanV2Graph } from "../uok/plan-v2.js";
|
|
29
|
+
import { resolveUokFlags } from "../uok/flags.js";
|
|
30
|
+
import { UokGateRunner } from "../uok/gate-runner.js";
|
|
28
31
|
import { resetEvidence } from "../safety/evidence-collector.js";
|
|
29
32
|
import { createCheckpoint, cleanupCheckpoint, rollbackToCheckpoint } from "../safety/git-checkpoint.js";
|
|
30
33
|
import { resolveSafetyHarnessConfig } from "../safety/safety-harness.js";
|
|
@@ -46,6 +49,15 @@ export function _resolveReportBasePath(s) {
|
|
|
46
49
|
export function _resolveDispatchGuardBasePath(s) {
|
|
47
50
|
return s.originalBasePath || s.basePath;
|
|
48
51
|
}
|
|
52
|
+
const PLAN_V2_GATE_PHASES = new Set([
|
|
53
|
+
"executing",
|
|
54
|
+
"summarizing",
|
|
55
|
+
"validating-milestone",
|
|
56
|
+
"completing-milestone",
|
|
57
|
+
]);
|
|
58
|
+
function shouldRunPlanV2Gate(phase) {
|
|
59
|
+
return PLAN_V2_GATE_PHASES.has(phase);
|
|
60
|
+
}
|
|
49
61
|
/**
|
|
50
62
|
* Generate and write an HTML milestone report snapshot.
|
|
51
63
|
* Extracted from the milestone-transition block in autoLoop.
|
|
@@ -100,6 +112,22 @@ async function closeoutAndStop(ctx, pi, s, deps, reason) {
|
|
|
100
112
|
}
|
|
101
113
|
await deps.stopAuto(ctx, pi, reason);
|
|
102
114
|
}
|
|
115
|
+
async function emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, errorContext) {
|
|
116
|
+
ic.deps.emitJournalEvent({
|
|
117
|
+
ts: new Date().toISOString(),
|
|
118
|
+
flowId: ic.flowId,
|
|
119
|
+
seq: ic.nextSeq(),
|
|
120
|
+
eventType: "unit-end",
|
|
121
|
+
data: {
|
|
122
|
+
unitType,
|
|
123
|
+
unitId,
|
|
124
|
+
status: "cancelled",
|
|
125
|
+
artifactVerified: false,
|
|
126
|
+
...(errorContext ? { errorContext } : {}),
|
|
127
|
+
},
|
|
128
|
+
causedBy: { flowId: ic.flowId, seq: unitStartSeq },
|
|
129
|
+
});
|
|
130
|
+
}
|
|
103
131
|
// βββ runPreDispatch βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
104
132
|
/**
|
|
105
133
|
* Phase 1: Pre-dispatch β resource guard, health gate, state derivation,
|
|
@@ -108,13 +136,52 @@ async function closeoutAndStop(ctx, pi, s, deps, reason) {
|
|
|
108
136
|
*/
|
|
109
137
|
export async function runPreDispatch(ic, loopState) {
|
|
110
138
|
const { ctx, pi, s, deps, prefs } = ic;
|
|
139
|
+
const uokFlags = resolveUokFlags(prefs);
|
|
140
|
+
const runPreDispatchGate = async (input) => {
|
|
141
|
+
if (!uokFlags.gates)
|
|
142
|
+
return;
|
|
143
|
+
const gateRunner = new UokGateRunner();
|
|
144
|
+
gateRunner.register({
|
|
145
|
+
id: input.gateId,
|
|
146
|
+
type: input.gateType,
|
|
147
|
+
execute: async () => ({
|
|
148
|
+
outcome: input.outcome,
|
|
149
|
+
failureClass: input.failureClass,
|
|
150
|
+
rationale: input.rationale,
|
|
151
|
+
findings: input.findings ?? "",
|
|
152
|
+
}),
|
|
153
|
+
});
|
|
154
|
+
await gateRunner.run(input.gateId, {
|
|
155
|
+
basePath: s.basePath,
|
|
156
|
+
traceId: `pre-dispatch:${ic.flowId}`,
|
|
157
|
+
turnId: `iter-${ic.iteration}`,
|
|
158
|
+
milestoneId: input.milestoneId ?? s.currentMilestoneId ?? undefined,
|
|
159
|
+
unitType: "pre-dispatch",
|
|
160
|
+
unitId: `iter-${ic.iteration}`,
|
|
161
|
+
});
|
|
162
|
+
};
|
|
111
163
|
// Resource version guard
|
|
112
164
|
const staleMsg = deps.checkResourcesStale(s.resourceVersionOnStart);
|
|
113
165
|
if (staleMsg) {
|
|
166
|
+
await runPreDispatchGate({
|
|
167
|
+
gateId: "resource-version-guard",
|
|
168
|
+
gateType: "policy",
|
|
169
|
+
outcome: "fail",
|
|
170
|
+
failureClass: "policy",
|
|
171
|
+
rationale: "resource version guard blocked dispatch",
|
|
172
|
+
findings: staleMsg,
|
|
173
|
+
});
|
|
114
174
|
await deps.stopAuto(ctx, pi, staleMsg);
|
|
115
175
|
debugLog("autoLoop", { phase: "exit", reason: "resources-stale" });
|
|
116
176
|
return { action: "break", reason: "resources-stale" };
|
|
117
177
|
}
|
|
178
|
+
await runPreDispatchGate({
|
|
179
|
+
gateId: "resource-version-guard",
|
|
180
|
+
gateType: "policy",
|
|
181
|
+
outcome: "pass",
|
|
182
|
+
failureClass: "none",
|
|
183
|
+
rationale: "resource version guard passed",
|
|
184
|
+
});
|
|
118
185
|
deps.invalidateAllCaches();
|
|
119
186
|
s.lastPromptCharCount = undefined;
|
|
120
187
|
s.lastBaselineCharCount = undefined;
|
|
@@ -125,13 +192,37 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
125
192
|
ctx.ui.notify(`Pre-dispatch: ${healthGate.fixesApplied.join(", ")}`, "info");
|
|
126
193
|
}
|
|
127
194
|
if (!healthGate.proceed) {
|
|
195
|
+
await runPreDispatchGate({
|
|
196
|
+
gateId: "pre-dispatch-health-gate",
|
|
197
|
+
gateType: "execution",
|
|
198
|
+
outcome: "manual-attention",
|
|
199
|
+
failureClass: "manual-attention",
|
|
200
|
+
rationale: "pre-dispatch health gate blocked dispatch",
|
|
201
|
+
findings: healthGate.reason,
|
|
202
|
+
});
|
|
128
203
|
ctx.ui.notify(healthGate.reason || "Pre-dispatch health check failed β run /gsd doctor for details.", "error");
|
|
129
204
|
await deps.pauseAuto(ctx, pi);
|
|
130
205
|
debugLog("autoLoop", { phase: "exit", reason: "health-gate-failed" });
|
|
131
206
|
return { action: "break", reason: "health-gate-failed" };
|
|
132
207
|
}
|
|
208
|
+
await runPreDispatchGate({
|
|
209
|
+
gateId: "pre-dispatch-health-gate",
|
|
210
|
+
gateType: "execution",
|
|
211
|
+
outcome: "pass",
|
|
212
|
+
failureClass: "none",
|
|
213
|
+
rationale: "pre-dispatch health gate passed",
|
|
214
|
+
findings: healthGate.fixesApplied.length > 0 ? healthGate.fixesApplied.join(", ") : "",
|
|
215
|
+
});
|
|
133
216
|
}
|
|
134
217
|
catch (e) {
|
|
218
|
+
await runPreDispatchGate({
|
|
219
|
+
gateId: "pre-dispatch-health-gate",
|
|
220
|
+
gateType: "execution",
|
|
221
|
+
outcome: "manual-attention",
|
|
222
|
+
failureClass: "manual-attention",
|
|
223
|
+
rationale: "pre-dispatch health gate threw unexpectedly",
|
|
224
|
+
findings: String(e),
|
|
225
|
+
});
|
|
135
226
|
logWarning("engine", "Pre-dispatch health gate threw unexpectedly", { error: String(e) });
|
|
136
227
|
}
|
|
137
228
|
// Sync project root artifacts into worktree
|
|
@@ -142,6 +233,32 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
142
233
|
}
|
|
143
234
|
// Derive state
|
|
144
235
|
let state = await deps.deriveState(s.basePath);
|
|
236
|
+
if (prefs?.uok?.plan_v2?.enabled && shouldRunPlanV2Gate(state.phase)) {
|
|
237
|
+
const compiled = ensurePlanV2Graph(s.basePath, state);
|
|
238
|
+
if (!compiled.ok) {
|
|
239
|
+
const reason = compiled.reason ?? "Plan v2 compilation failed";
|
|
240
|
+
await runPreDispatchGate({
|
|
241
|
+
gateId: "plan-v2-gate",
|
|
242
|
+
gateType: "policy",
|
|
243
|
+
outcome: "manual-attention",
|
|
244
|
+
failureClass: "manual-attention",
|
|
245
|
+
rationale: "plan v2 compile gate failed",
|
|
246
|
+
findings: reason,
|
|
247
|
+
milestoneId: state.activeMilestone?.id ?? undefined,
|
|
248
|
+
});
|
|
249
|
+
ctx.ui.notify(`Plan gate failed-closed: ${reason}`, "error");
|
|
250
|
+
await deps.pauseAuto(ctx, pi);
|
|
251
|
+
return { action: "break", reason: "plan-v2-gate-failed" };
|
|
252
|
+
}
|
|
253
|
+
await runPreDispatchGate({
|
|
254
|
+
gateId: "plan-v2-gate",
|
|
255
|
+
gateType: "policy",
|
|
256
|
+
outcome: "pass",
|
|
257
|
+
failureClass: "none",
|
|
258
|
+
rationale: "plan v2 compile gate passed",
|
|
259
|
+
milestoneId: state.activeMilestone?.id ?? undefined,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
145
262
|
deps.syncCmuxSidebar(prefs, state);
|
|
146
263
|
let mid = state.activeMilestone?.id;
|
|
147
264
|
let midTitle = state.activeMilestone?.title;
|
|
@@ -177,7 +294,10 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
177
294
|
eligibleSlices: eligible.map(e => e.id),
|
|
178
295
|
});
|
|
179
296
|
ctx.ui.notify(`Slice-parallel: dispatching ${eligible.length} eligible slices for ${mid}.`, "info");
|
|
180
|
-
const result = await startSliceParallel(s.basePath, mid, eligible, {
|
|
297
|
+
const result = await startSliceParallel(s.basePath, mid, eligible, {
|
|
298
|
+
maxWorkers: prefs.slice_parallel.max_workers ?? 2,
|
|
299
|
+
useExecutionGraph: uokFlags.executionGraph,
|
|
300
|
+
});
|
|
181
301
|
if (result.started.length > 0) {
|
|
182
302
|
ctx.ui.notify(`Slice-parallel: started ${result.started.length} worker(s): ${result.started.join(", ")}.`, "info");
|
|
183
303
|
await deps.stopAuto(ctx, pi, `Slice-parallel dispatched for ${mid}`);
|
|
@@ -320,10 +440,13 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
320
440
|
}
|
|
321
441
|
else if (state.phase === "blocked") {
|
|
322
442
|
const blockerMsg = `Blocked: ${state.blockers.join(", ")}`;
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
deps.
|
|
443
|
+
// Pause instead of hard-stop so the session is resumable with `/gsd auto`.
|
|
444
|
+
// Hard-stop here was causing premature termination when slice dependencies
|
|
445
|
+
// were temporarily unresolvable (e.g. after reassessment added new slices).
|
|
446
|
+
await deps.pauseAuto(ctx, pi);
|
|
447
|
+
ctx.ui.notify(`${blockerMsg}. Fix and run /gsd auto to resume.`, "warning");
|
|
448
|
+
deps.sendDesktopNotification("GSD", blockerMsg, "warning", "attention", basename(s.originalBasePath || s.basePath));
|
|
449
|
+
deps.logCmuxEvent(prefs, blockerMsg, "warning");
|
|
327
450
|
}
|
|
328
451
|
else {
|
|
329
452
|
const ids = incomplete.map((m) => m.id).join(", ");
|
|
@@ -392,13 +515,16 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
392
515
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "terminal", data: { reason: "milestone-complete", milestoneId: mid } });
|
|
393
516
|
return { action: "break", reason: "milestone-complete" };
|
|
394
517
|
}
|
|
395
|
-
// Terminal: blocked
|
|
518
|
+
// Terminal: blocked β pause instead of hard-stop so the session is resumable.
|
|
396
519
|
if (state.phase === "blocked") {
|
|
397
520
|
const blockerMsg = `Blocked: ${state.blockers.join(", ")}`;
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
deps.
|
|
521
|
+
if (s.currentUnit) {
|
|
522
|
+
await deps.closeoutUnit(ctx, s.basePath, s.currentUnit.type, s.currentUnit.id, s.currentUnit.startedAt, deps.buildSnapshotOpts(s.currentUnit.type, s.currentUnit.id));
|
|
523
|
+
}
|
|
524
|
+
await deps.pauseAuto(ctx, pi);
|
|
525
|
+
ctx.ui.notify(`${blockerMsg}. Fix and run /gsd auto to resume.`, "warning");
|
|
526
|
+
deps.sendDesktopNotification("GSD", blockerMsg, "warning", "attention", basename(s.originalBasePath || s.basePath));
|
|
527
|
+
deps.logCmuxEvent(prefs, blockerMsg, "warning");
|
|
402
528
|
debugLog("autoLoop", { phase: "exit", reason: "blocked" });
|
|
403
529
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "terminal", data: { reason: "blocked", blockers: state.blockers } });
|
|
404
530
|
return { action: "break", reason: "blocked" };
|
|
@@ -770,7 +896,13 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
770
896
|
s.currentUnit.type === unitType &&
|
|
771
897
|
s.currentUnit.id === unitId);
|
|
772
898
|
const previousTier = s.currentUnitRouting?.tier;
|
|
899
|
+
// Scope workflow-logger buffer to this unit so post-finalize drains are
|
|
900
|
+
// per-unit. Without this, the module-level _buffer accumulates across every
|
|
901
|
+
// unit in the same Node process (see workflow-logger.ts module header).
|
|
902
|
+
_resetLogs();
|
|
773
903
|
s.currentUnit = { type: unitType, id: unitId, startedAt: Date.now() };
|
|
904
|
+
s.lastGitActionFailure = null;
|
|
905
|
+
s.lastGitActionStatus = null;
|
|
774
906
|
setCurrentPhase(unitType);
|
|
775
907
|
s.lastToolInvocationError = null; // #2883: clear stale error from previous unit
|
|
776
908
|
const unitStartSeq = ic.nextSeq();
|
|
@@ -969,6 +1101,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
969
1101
|
// Provider-error pause: pauseAuto already handled cleanup and scheduled
|
|
970
1102
|
// recovery. Don't hard-stop β just break out of the loop (#2762).
|
|
971
1103
|
if (unitResult.errorContext?.category === "provider") {
|
|
1104
|
+
await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
|
|
972
1105
|
debugLog("autoLoop", { phase: "exit", reason: "provider-pause", isTransient: unitResult.errorContext.isTransient });
|
|
973
1106
|
return { action: "break", reason: "provider-pause" };
|
|
974
1107
|
}
|
|
@@ -982,9 +1115,16 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
982
1115
|
ctx.ui.notify(`Session creation timed out for ${unitType} ${unitId}. Pausing auto-mode (recoverable).`, "warning");
|
|
983
1116
|
debugLog("autoLoop", { phase: "session-timeout-pause", unitType, unitId });
|
|
984
1117
|
await deps.pauseAuto(ctx, pi);
|
|
1118
|
+
await deps.autoCommitUnit?.(s.basePath, unitType, unitId, ctx);
|
|
1119
|
+
await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
|
|
985
1120
|
return { action: "break", reason: "session-timeout" };
|
|
986
1121
|
}
|
|
987
1122
|
// All other cancelled states (structural errors, non-transient failures): hard stop
|
|
1123
|
+
if (s.currentUnit) {
|
|
1124
|
+
await deps.closeoutUnit(ctx, s.basePath, unitType, unitId, s.currentUnit.startedAt, deps.buildSnapshotOpts(unitType, unitId));
|
|
1125
|
+
}
|
|
1126
|
+
await deps.autoCommitUnit?.(s.basePath, unitType, unitId, ctx);
|
|
1127
|
+
await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
|
|
988
1128
|
ctx.ui.notify(`Session creation failed for ${unitType} ${unitId}: ${unitResult.errorContext?.message ?? "unknown"}. Stopping auto-mode.`, "warning");
|
|
989
1129
|
await deps.stopAuto(ctx, pi, `Session creation failed: ${unitResult.errorContext?.message ?? "unknown"}`);
|
|
990
1130
|
debugLog("autoLoop", { phase: "exit", reason: "session-failed" });
|
|
@@ -1118,6 +1258,9 @@ export async function runFinalize(ic, iterData, loopState, sidecarItem) {
|
|
|
1118
1258
|
// cannot mutate state for the next unit (#3757).
|
|
1119
1259
|
s.currentUnit = null;
|
|
1120
1260
|
clearCurrentPhase();
|
|
1261
|
+
// Drop any logger entries from the timed-out unit so they don't bleed
|
|
1262
|
+
// into the next iteration's drain.
|
|
1263
|
+
drainLogs();
|
|
1121
1264
|
loopState.consecutiveFinalizeTimeouts++;
|
|
1122
1265
|
debugLog("autoLoop", {
|
|
1123
1266
|
phase: "pre-verification-timeout",
|
|
@@ -1136,11 +1279,15 @@ export async function runFinalize(ic, iterData, loopState, sidecarItem) {
|
|
|
1136
1279
|
}
|
|
1137
1280
|
const preResult = preResultGuard.value;
|
|
1138
1281
|
if (preResult === "dispatched") {
|
|
1282
|
+
const dispatchedReason = s.lastGitActionFailure
|
|
1283
|
+
? "git-closeout-failure"
|
|
1284
|
+
: "pre-verification-dispatched";
|
|
1139
1285
|
debugLog("autoLoop", {
|
|
1140
1286
|
phase: "exit",
|
|
1141
|
-
reason:
|
|
1287
|
+
reason: dispatchedReason,
|
|
1288
|
+
gitError: s.lastGitActionFailure ?? undefined,
|
|
1142
1289
|
});
|
|
1143
|
-
return { action: "break", reason:
|
|
1290
|
+
return { action: "break", reason: dispatchedReason };
|
|
1144
1291
|
}
|
|
1145
1292
|
if (preResult === "retry") {
|
|
1146
1293
|
if (sidecarItem) {
|
|
@@ -1193,6 +1340,9 @@ export async function runFinalize(ic, iterData, loopState, sidecarItem) {
|
|
|
1193
1340
|
// cannot mutate state for the next unit (#3757).
|
|
1194
1341
|
s.currentUnit = null;
|
|
1195
1342
|
clearCurrentPhase();
|
|
1343
|
+
// Drop any logger entries from the timed-out unit so they don't bleed
|
|
1344
|
+
// into the next iteration's drain.
|
|
1345
|
+
drainLogs();
|
|
1196
1346
|
loopState.consecutiveFinalizeTimeouts++;
|
|
1197
1347
|
debugLog("autoLoop", {
|
|
1198
1348
|
phase: "post-verification-timeout",
|
|
@@ -1224,5 +1374,15 @@ export async function runFinalize(ic, iterData, loopState, sidecarItem) {
|
|
|
1224
1374
|
}
|
|
1225
1375
|
// Both pre and post verification completed without timeout β reset counter
|
|
1226
1376
|
loopState.consecutiveFinalizeTimeouts = 0;
|
|
1377
|
+
// Surface accumulated workflow-logger issues for this unit to the user.
|
|
1378
|
+
// Warnings/errors logged during the unit are buffered in the logger and
|
|
1379
|
+
// drained here so the user sees a single consolidated post-unit alert.
|
|
1380
|
+
if (hasAnyIssues()) {
|
|
1381
|
+
const { logs } = drainAndSummarize();
|
|
1382
|
+
if (logs.length > 0) {
|
|
1383
|
+
const severity = logs.some((e) => e.severity === "error") ? "error" : "warning";
|
|
1384
|
+
ctx.ui.notify(formatForNotification(logs), severity);
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1227
1387
|
return { action: "next", data: undefined };
|
|
1228
1388
|
}
|
|
@@ -52,6 +52,8 @@ export class AutoSession {
|
|
|
52
52
|
continueHereHandle = null;
|
|
53
53
|
// ββ Current unit βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
54
54
|
currentUnit = null;
|
|
55
|
+
currentTraceId = null;
|
|
56
|
+
currentTurnId = null;
|
|
55
57
|
currentUnitRouting = null;
|
|
56
58
|
currentMilestoneId = null;
|
|
57
59
|
// ββ Model state ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
@@ -79,6 +81,10 @@ export class AutoSession {
|
|
|
79
81
|
/** Set when a GSD tool execution ends with isError due to malformed/truncated
|
|
80
82
|
* JSON arguments. Checked by postUnitPreVerification to break retry loops. */
|
|
81
83
|
lastToolInvocationError = null;
|
|
84
|
+
/** Set when turn-level git action fails during closeout. */
|
|
85
|
+
lastGitActionFailure = null;
|
|
86
|
+
/** Last turn-level git action status captured during finalize. */
|
|
87
|
+
lastGitActionStatus = null;
|
|
82
88
|
// ββ Isolation degradation ββββββββββββββββββββββββββββββββββββββββββββ
|
|
83
89
|
/** Set to true when worktree creation fails; prevents merge of nonexistent branch. */
|
|
84
90
|
isolationDegraded = false;
|
|
@@ -157,6 +163,8 @@ export class AutoSession {
|
|
|
157
163
|
this.unitRecoveryCount.clear();
|
|
158
164
|
// Unit
|
|
159
165
|
this.currentUnit = null;
|
|
166
|
+
this.currentTraceId = null;
|
|
167
|
+
this.currentTurnId = null;
|
|
160
168
|
this.currentUnitRouting = null;
|
|
161
169
|
this.currentMilestoneId = null;
|
|
162
170
|
// Model
|
|
@@ -185,6 +193,8 @@ export class AutoSession {
|
|
|
185
193
|
this.rewriteAttemptCount = 0;
|
|
186
194
|
this.consecutiveCompleteBootstraps = 0;
|
|
187
195
|
this.lastToolInvocationError = null;
|
|
196
|
+
this.lastGitActionFailure = null;
|
|
197
|
+
this.lastGitActionStatus = null;
|
|
188
198
|
this.isolationDegraded = false;
|
|
189
199
|
this.milestoneMergedInPhases = false;
|
|
190
200
|
this.checkpointSha = null;
|
|
@@ -19,6 +19,8 @@ import { join } from "node:path";
|
|
|
19
19
|
import { hasImplementationArtifacts } from "./auto-recovery.js";
|
|
20
20
|
import { buildDiscussMilestonePrompt, buildResearchMilestonePrompt, buildPlanMilestonePrompt, buildResearchSlicePrompt, buildPlanSlicePrompt, buildExecuteTaskPrompt, buildCompleteSlicePrompt, buildCompleteMilestonePrompt, buildValidateMilestonePrompt, buildReplanSlicePrompt, buildRunUatPrompt, buildReassessRoadmapPrompt, buildRewriteDocsPrompt, buildReactiveExecutePrompt, buildGateEvaluatePrompt, buildParallelResearchSlicesPrompt, checkNeedsReassessment, checkNeedsRunUat, } from "./auto-prompts.js";
|
|
21
21
|
import { resolveModelWithFallbacksForUnit } from "./preferences-models.js";
|
|
22
|
+
import { resolveUokFlags } from "./uok/flags.js";
|
|
23
|
+
import { selectReactiveDispatchBatch } from "./uok/execution-graph.js";
|
|
22
24
|
function missingSliceStop(mid, phase) {
|
|
23
25
|
return {
|
|
24
26
|
action: "stop",
|
|
@@ -216,7 +218,12 @@ export const DISPATCH_RULES = [
|
|
|
216
218
|
{
|
|
217
219
|
name: "reassess-roadmap (post-completion)",
|
|
218
220
|
match: async ({ state, mid, midTitle, basePath, prefs }) => {
|
|
219
|
-
if (prefs?.phases?.skip_reassess
|
|
221
|
+
if (prefs?.phases?.skip_reassess)
|
|
222
|
+
return null;
|
|
223
|
+
// Default reassess_after_slice to true β reassessment after slice completion
|
|
224
|
+
// is essential for roadmap integrity. Opt-out via explicit `false`.
|
|
225
|
+
const reassessEnabled = prefs?.phases?.reassess_after_slice ?? true;
|
|
226
|
+
if (!reassessEnabled)
|
|
220
227
|
return null;
|
|
221
228
|
const needsReassess = await checkNeedsReassessment(basePath, mid, state);
|
|
222
229
|
if (!needsReassess)
|
|
@@ -456,7 +463,15 @@ export const DISPATCH_RULES = [
|
|
|
456
463
|
// Only activate reactive dispatch when >1 task is ready
|
|
457
464
|
if (readyIds.length <= 1)
|
|
458
465
|
return null;
|
|
459
|
-
const
|
|
466
|
+
const uokFlags = resolveUokFlags(prefs);
|
|
467
|
+
const selected = uokFlags.executionGraph
|
|
468
|
+
? selectReactiveDispatchBatch({
|
|
469
|
+
graph,
|
|
470
|
+
readyIds,
|
|
471
|
+
maxParallel,
|
|
472
|
+
inFlightOutputs: new Set(),
|
|
473
|
+
}).selected
|
|
474
|
+
: chooseNonConflictingSubset(readyIds, graph, maxParallel, new Set());
|
|
460
475
|
if (selected.length <= 1)
|
|
461
476
|
return null;
|
|
462
477
|
// Log graph metrics for observability
|
|
@@ -710,11 +725,14 @@ export async function resolveDispatch(ctx) {
|
|
|
710
725
|
return result;
|
|
711
726
|
}
|
|
712
727
|
}
|
|
713
|
-
// No rule matched β unhandled phase
|
|
728
|
+
// No rule matched β unhandled phase.
|
|
729
|
+
// Use level "warning" so the loop pauses (resumable) instead of hard-stopping.
|
|
730
|
+
// Hard-stop here was causing premature termination for transient phase gaps
|
|
731
|
+
// (e.g. after reassessment modifies the roadmap and state needs re-derivation).
|
|
714
732
|
return {
|
|
715
733
|
action: "stop",
|
|
716
734
|
reason: `Unhandled phase "${ctx.state.phase}" β run /gsd doctor to diagnose.`,
|
|
717
|
-
level: "
|
|
735
|
+
level: "warning",
|
|
718
736
|
matchedRule: "<no-match>",
|
|
719
737
|
};
|
|
720
738
|
}
|
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
* and fallback chains.
|
|
5
5
|
*/
|
|
6
6
|
import { resolveModelWithFallbacksForUnit, resolveDynamicRoutingConfig } from "./preferences.js";
|
|
7
|
-
import { classifyUnitComplexity, tierLabel } from "./complexity-classifier.js";
|
|
7
|
+
import { classifyUnitComplexity, extractTaskMetadata, tierLabel } from "./complexity-classifier.js";
|
|
8
8
|
import { resolveModelForComplexity, escalateTier, getEligibleModels, loadCapabilityOverrides, adjustToolSet } from "./model-router.js";
|
|
9
9
|
import { getLedger, getProjectTotals } from "./metrics.js";
|
|
10
10
|
import { unitPhaseLabel } from "./auto-dashboard.js";
|
|
11
11
|
import { getSessionModelOverride } from "./session-model-override.js";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
isAutoMode = true) {
|
|
12
|
+
import { logWarning } from "./workflow-logger.js";
|
|
13
|
+
import { resolveUokFlags } from "./uok/flags.js";
|
|
14
|
+
import { applyModelPolicyFilter } from "./uok/model-policy.js";
|
|
15
|
+
export function resolvePreferredModelConfig(unitType, autoModeStartModel, isAutoMode = true) {
|
|
16
16
|
const explicitConfig = resolveModelWithFallbacksForUnit(unitType);
|
|
17
17
|
if (explicitConfig)
|
|
18
18
|
return explicitConfig;
|
|
@@ -24,7 +24,7 @@ isAutoMode = true) {
|
|
|
24
24
|
if (!routingConfig.enabled || !routingConfig.tier_models)
|
|
25
25
|
return undefined;
|
|
26
26
|
// Don't synthesize a routing config for flat-rate providers (#3453).
|
|
27
|
-
if (autoModeStartModel && isFlatRateProvider(autoModeStartModel.provider))
|
|
27
|
+
if (autoModeStartModel && isFlatRateProvider(autoModeStartModel.provider, autoModeStartModel.flatRateCtx))
|
|
28
28
|
return undefined;
|
|
29
29
|
const ceilingModel = routingConfig.tier_models.heavy
|
|
30
30
|
?? (autoModeStartModel ? `${autoModeStartModel.provider}/${autoModeStartModel.id}` : undefined);
|
|
@@ -48,9 +48,21 @@ export async function selectAndApplyModel(ctx, pi, unitType, unitId, basePath, p
|
|
|
48
48
|
isAutoMode = true,
|
|
49
49
|
/** Explicit /gsd model pin captured at bootstrap for long-running auto loops. */
|
|
50
50
|
sessionModelOverride) {
|
|
51
|
+
const uokFlags = resolveUokFlags(prefs);
|
|
51
52
|
const effectiveSessionModelOverride = sessionModelOverride === undefined
|
|
52
53
|
? getSessionModelOverride(ctx.sessionManager.getSessionId())
|
|
53
54
|
: (sessionModelOverride ?? undefined);
|
|
55
|
+
// Enrich the start model with a flat-rate context up front so routing
|
|
56
|
+
// synthesis and the dispatch-time guard see the same signals (built-in
|
|
57
|
+
// list + user `flat_rate_providers` preference + externalCli auto-
|
|
58
|
+
// detection). The dispatch-time primary-model check below builds its
|
|
59
|
+
// own per-provider context when it has a resolved primary model.
|
|
60
|
+
if (autoModeStartModel) {
|
|
61
|
+
autoModeStartModel = {
|
|
62
|
+
...autoModeStartModel,
|
|
63
|
+
flatRateCtx: buildFlatRateContext(autoModeStartModel.provider, ctx, prefs),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
54
66
|
const modelConfig = effectiveSessionModelOverride
|
|
55
67
|
? undefined
|
|
56
68
|
: resolvePreferredModelConfig(unitType, autoModeStartModel, isAutoMode);
|
|
@@ -58,6 +70,9 @@ sessionModelOverride) {
|
|
|
58
70
|
let appliedModel = null;
|
|
59
71
|
if (modelConfig) {
|
|
60
72
|
const availableModels = ctx.modelRegistry.getAvailable();
|
|
73
|
+
const modelPolicyTraceId = `model:${ctx.sessionManager.getSessionId()}:${Date.now()}`;
|
|
74
|
+
const modelPolicyTurnId = `${unitType}:${unitId}`;
|
|
75
|
+
let policyAllowedModelKeys = null;
|
|
61
76
|
// βββ Dynamic Model Routing βββββββββββββββββββββββββββββββββββββββββ
|
|
62
77
|
// Dynamic routing (complexity-based downgrading) only applies in auto-mode.
|
|
63
78
|
// Interactive/guided-flow dispatches use the user's session model directly,
|
|
@@ -66,22 +81,48 @@ sessionModelOverride) {
|
|
|
66
81
|
if (!isAutoMode) {
|
|
67
82
|
routingConfig.enabled = false;
|
|
68
83
|
}
|
|
84
|
+
// burn-max defaults to quality-first dispatch (no downgrade routing).
|
|
85
|
+
if (prefs?.token_profile === "burn-max") {
|
|
86
|
+
routingConfig.enabled = false;
|
|
87
|
+
}
|
|
69
88
|
let effectiveModelConfig = modelConfig;
|
|
70
89
|
let routingTierLabel = "";
|
|
90
|
+
let routingEligibleModels = availableModels;
|
|
91
|
+
const taskMetadataForPolicy = unitType === "execute-task"
|
|
92
|
+
? extractTaskMetadata(unitId, basePath)
|
|
93
|
+
: undefined;
|
|
94
|
+
if (uokFlags.modelPolicy) {
|
|
95
|
+
const policy = applyModelPolicyFilter(availableModels, {
|
|
96
|
+
basePath,
|
|
97
|
+
traceId: modelPolicyTraceId,
|
|
98
|
+
turnId: modelPolicyTurnId,
|
|
99
|
+
unitType,
|
|
100
|
+
taskMetadata: taskMetadataForPolicy,
|
|
101
|
+
currentProvider: ctx.model?.provider,
|
|
102
|
+
allowCrossProvider: routingConfig.cross_provider !== false,
|
|
103
|
+
requiredTools: pi.getActiveTools(),
|
|
104
|
+
});
|
|
105
|
+
routingEligibleModels = policy.eligible;
|
|
106
|
+
policyAllowedModelKeys = new Set(policy.eligible.map((m) => `${m.provider.toLowerCase()}/${m.id.toLowerCase()}`));
|
|
107
|
+
if (routingEligibleModels.length === 0) {
|
|
108
|
+
throw new Error(`Model policy denied all candidate models for ${unitType}/${unitId}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
71
111
|
// Disable routing for flat-rate providers like GitHub Copilot (#3453).
|
|
72
112
|
// All models cost the same per request, so downgrading to a cheaper
|
|
73
113
|
// model provides no cost benefit β it only degrades quality.
|
|
74
114
|
// Fail-closed: if primary model can't be resolved, fall back to
|
|
75
115
|
// provider-level signals rather than allowing unwanted downgrades.
|
|
76
116
|
if (routingConfig.enabled) {
|
|
77
|
-
const primaryModel = resolveModelId(modelConfig.primary,
|
|
117
|
+
const primaryModel = resolveModelId(modelConfig.primary, routingEligibleModels, ctx.model?.provider);
|
|
78
118
|
if (primaryModel) {
|
|
79
|
-
|
|
119
|
+
const primaryFlatRateCtx = buildFlatRateContext(primaryModel.provider, ctx, prefs);
|
|
120
|
+
if (isFlatRateProvider(primaryModel.provider, primaryFlatRateCtx)) {
|
|
80
121
|
routingConfig.enabled = false;
|
|
81
122
|
}
|
|
82
123
|
}
|
|
83
|
-
else if ((autoModeStartModel && isFlatRateProvider(autoModeStartModel.provider))
|
|
84
|
-
|| (ctx.model?.provider && isFlatRateProvider(ctx.model.provider))) {
|
|
124
|
+
else if ((autoModeStartModel && isFlatRateProvider(autoModeStartModel.provider, autoModeStartModel.flatRateCtx))
|
|
125
|
+
|| (ctx.model?.provider && isFlatRateProvider(ctx.model.provider, buildFlatRateContext(ctx.model.provider, ctx, prefs)))) {
|
|
85
126
|
// Primary model unresolvable but provider signals indicate flat-rate β
|
|
86
127
|
// disable routing to prevent quality degradation.
|
|
87
128
|
routingConfig.enabled = false;
|
|
@@ -100,8 +141,8 @@ sessionModelOverride) {
|
|
|
100
141
|
const isHook = unitType.startsWith("hook/");
|
|
101
142
|
const shouldClassify = !isHook || routingConfig.hooks !== false;
|
|
102
143
|
if (shouldClassify) {
|
|
103
|
-
let classification = classifyUnitComplexity(unitType, unitId, basePath, budgetPct);
|
|
104
|
-
const availableModelIds =
|
|
144
|
+
let classification = classifyUnitComplexity(unitType, unitId, basePath, budgetPct, taskMetadataForPolicy);
|
|
145
|
+
const availableModelIds = routingEligibleModels.map(m => m.id);
|
|
105
146
|
// Escalate tier on retry when escalate_on_failure is enabled (default: true)
|
|
106
147
|
if (retryContext?.isRetry &&
|
|
107
148
|
retryContext.previousTier &&
|
|
@@ -181,13 +222,25 @@ sessionModelOverride) {
|
|
|
181
222
|
}
|
|
182
223
|
}
|
|
183
224
|
const modelsToTry = [effectiveModelConfig.primary, ...effectiveModelConfig.fallbacks];
|
|
225
|
+
let attemptedPolicyEligible = false;
|
|
184
226
|
for (const modelId of modelsToTry) {
|
|
185
|
-
const
|
|
227
|
+
const resolutionPool = uokFlags.modelPolicy ? routingEligibleModels : availableModels;
|
|
228
|
+
const model = resolveModelId(modelId, resolutionPool, ctx.model?.provider);
|
|
186
229
|
if (!model) {
|
|
187
230
|
if (verbose)
|
|
188
231
|
ctx.ui.notify(`Model ${modelId} not found, trying fallback.`, "info");
|
|
189
232
|
continue;
|
|
190
233
|
}
|
|
234
|
+
if (policyAllowedModelKeys) {
|
|
235
|
+
const key = `${model.provider.toLowerCase()}/${model.id.toLowerCase()}`;
|
|
236
|
+
if (!policyAllowedModelKeys.has(key)) {
|
|
237
|
+
if (verbose) {
|
|
238
|
+
ctx.ui.notify(`Model policy denied ${model.provider}/${model.id}; trying fallback.`, "warning");
|
|
239
|
+
}
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
attemptedPolicyEligible = true;
|
|
243
|
+
}
|
|
191
244
|
// Warn if the ID is ambiguous across providers
|
|
192
245
|
if (!modelId.includes("/")) {
|
|
193
246
|
const providers = availableModels.filter(m => m.id === modelId).map(m => m.provider);
|
|
@@ -245,6 +298,9 @@ sessionModelOverride) {
|
|
|
245
298
|
}
|
|
246
299
|
}
|
|
247
300
|
}
|
|
301
|
+
if (uokFlags.modelPolicy && policyAllowedModelKeys && !attemptedPolicyEligible) {
|
|
302
|
+
throw new Error(`Model policy denied dispatch for ${unitType}/${unitId} before prompt send`);
|
|
303
|
+
}
|
|
248
304
|
}
|
|
249
305
|
else if (autoModeStartModel) {
|
|
250
306
|
// No model preference for this unit type β re-apply the model captured
|
|
@@ -331,7 +387,40 @@ export function resolveModelId(modelId, availableModels, currentProvider) {
|
|
|
331
387
|
* Uses case-insensitive matching with alias support to prevent fail-open on
|
|
332
388
|
* provider naming variations (e.g. "copilot" vs "github-copilot").
|
|
333
389
|
*/
|
|
334
|
-
const
|
|
335
|
-
export function isFlatRateProvider(provider) {
|
|
336
|
-
|
|
390
|
+
const BUILTIN_FLAT_RATE = new Set(["github-copilot", "copilot", "claude-code"]);
|
|
391
|
+
export function isFlatRateProvider(provider, opts) {
|
|
392
|
+
const p = provider.toLowerCase();
|
|
393
|
+
if (BUILTIN_FLAT_RATE.has(p))
|
|
394
|
+
return true;
|
|
395
|
+
if (opts?.userFlatRate?.some(id => id.toLowerCase() === p))
|
|
396
|
+
return true;
|
|
397
|
+
if (opts?.authMode === "externalCli")
|
|
398
|
+
return true;
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Build a FlatRateContext for a given provider from live runtime state.
|
|
403
|
+
* Safe to call when ctx or prefs are undefined β missing pieces are
|
|
404
|
+
* treated as "no signal".
|
|
405
|
+
*/
|
|
406
|
+
export function buildFlatRateContext(provider, ctx, prefs) {
|
|
407
|
+
let authMode;
|
|
408
|
+
const getAuthMode = ctx?.modelRegistry?.getProviderAuthMode;
|
|
409
|
+
if (typeof getAuthMode === "function") {
|
|
410
|
+
try {
|
|
411
|
+
const mode = getAuthMode(provider);
|
|
412
|
+
if (mode === "apiKey" || mode === "oauth" || mode === "externalCli" || mode === "none") {
|
|
413
|
+
authMode = mode;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
catch (err) {
|
|
417
|
+
// Registry lookup failure must never break flat-rate detection β
|
|
418
|
+
// fall through with authMode undefined and surface the cause.
|
|
419
|
+
logWarning("dispatch", `flat-rate auth-mode lookup failed for ${provider}: ${err instanceof Error ? err.message : String(err)}`);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return {
|
|
423
|
+
authMode,
|
|
424
|
+
userFlatRate: prefs?.flat_rate_providers,
|
|
425
|
+
};
|
|
337
426
|
}
|