gsd-pi 2.76.0 → 2.77.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -25
- package/dist/claude-cli-check.js +32 -3
- package/dist/mcp-server.d.ts +7 -0
- package/dist/mcp-server.js +35 -1
- package/dist/onboarding.js +45 -0
- package/dist/resource-loader.d.ts +1 -1
- package/dist/resource-loader.js +2 -8
- package/dist/resources/agents/researcher.md +1 -1
- package/dist/resources/extensions/claude-code-cli/readiness.js +31 -8
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +77 -17
- package/dist/resources/extensions/gsd/auto/loop.js +9 -0
- package/dist/resources/extensions/gsd/auto/phases.js +104 -11
- package/dist/resources/extensions/gsd/auto/run-unit.js +38 -2
- package/dist/resources/extensions/gsd/auto/session.js +22 -1
- package/dist/resources/extensions/gsd/auto-dispatch.js +16 -3
- package/dist/resources/extensions/gsd/auto-model-selection.js +53 -16
- package/dist/resources/extensions/gsd/auto-post-unit.js +25 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +14 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +32 -1
- package/dist/resources/extensions/gsd/auto-start.js +58 -57
- package/dist/resources/extensions/gsd/auto-verification.js +33 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +51 -53
- package/dist/resources/extensions/gsd/auto.js +70 -28
- package/dist/resources/extensions/gsd/blocked-models.js +68 -0
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +93 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +39 -9
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +93 -0
- package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +3 -0
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +12 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +52 -6
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +84 -23
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +34 -2
- package/dist/resources/extensions/gsd/clean-root-preflight.js +93 -0
- package/dist/resources/extensions/gsd/commands-extract-learnings.js +54 -89
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +968 -23
- package/dist/resources/extensions/gsd/compaction-snapshot.js +121 -0
- package/dist/resources/extensions/gsd/complexity-classifier.js +5 -3
- package/dist/resources/extensions/gsd/db-writer.js +88 -16
- package/dist/resources/extensions/gsd/doctor-git-checks.js +23 -29
- package/dist/resources/extensions/gsd/doctor-providers.js +51 -5
- package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +1 -0
- package/dist/resources/extensions/gsd/error-classifier.js +31 -3
- package/dist/resources/extensions/gsd/exec-history.js +120 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +258 -0
- package/dist/resources/extensions/gsd/gitignore.js +1 -0
- package/dist/resources/extensions/gsd/gsd-db.js +168 -23
- package/dist/resources/extensions/gsd/guided-flow.js +190 -1
- package/dist/resources/extensions/gsd/health-widget.js +4 -1
- package/dist/resources/extensions/gsd/hook-emitter.js +108 -0
- package/dist/resources/extensions/gsd/init-wizard.js +15 -1
- package/dist/resources/extensions/gsd/key-manager.js +28 -0
- package/dist/resources/extensions/gsd/memory-backfill.js +126 -0
- package/dist/resources/extensions/gsd/memory-store.js +19 -0
- package/dist/resources/extensions/gsd/model-router.js +36 -3
- package/dist/resources/extensions/gsd/pre-execution-checks.js +44 -9
- package/dist/resources/extensions/gsd/preferences-types.js +9 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +83 -0
- package/dist/resources/extensions/gsd/preferences.js +17 -17
- package/dist/resources/extensions/gsd/prompt-loader.js +22 -7
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
- package/dist/resources/extensions/gsd/prompts/discuss.md +29 -2
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +96 -0
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +13 -5
- package/dist/resources/extensions/gsd/safety/safety-harness.js +5 -1
- package/dist/resources/extensions/gsd/state.js +43 -4
- package/dist/resources/extensions/gsd/token-counter.js +22 -5
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +16 -10
- package/dist/resources/extensions/gsd/tools/exec-search-tool.js +59 -0
- package/dist/resources/extensions/gsd/tools/exec-tool.js +126 -0
- package/dist/resources/extensions/gsd/tools/memory-tools.js +26 -1
- package/dist/resources/extensions/gsd/tools/resume-tool.js +23 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +20 -3
- package/dist/resources/extensions/gsd/workflow-mcp.js +3 -0
- package/dist/resources/extensions/gsd/workflow-templates/spike.md +6 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +50 -10
- package/dist/resources/extensions/search-the-web/command-search-provider.js +5 -4
- package/dist/resources/extensions/search-the-web/native-search.js +45 -13
- package/dist/resources/skills/api-design/SKILL.md +190 -0
- package/dist/resources/skills/create-mcp-server/SKILL.md +121 -0
- package/dist/resources/skills/decompose-into-slices/SKILL.md +139 -0
- package/dist/resources/skills/dependency-upgrade/SKILL.md +158 -0
- package/dist/resources/skills/design-an-interface/SKILL.md +102 -0
- package/dist/resources/skills/forensics/SKILL.md +153 -0
- package/dist/resources/skills/grill-me/SKILL.md +93 -0
- package/dist/resources/skills/handoff/SKILL.md +121 -0
- package/dist/resources/skills/observability/SKILL.md +174 -0
- package/dist/resources/skills/security-review/SKILL.md +181 -0
- package/dist/resources/skills/spike-wrap-up/SKILL.md +138 -0
- package/dist/resources/skills/tdd/SKILL.md +112 -0
- package/dist/resources/skills/verify-before-complete/SKILL.md +98 -0
- package/dist/resources/skills/write-docs/SKILL.md +82 -0
- package/dist/resources/skills/write-milestone-brief/SKILL.md +135 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.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/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 +10 -10
- package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/server.js +1 -1
- package/dist/welcome-screen.js +6 -1
- package/dist/wizard.js +2 -0
- package/package.json +1 -1
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/dist/remote-questions.d.ts +45 -0
- package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -0
- package/packages/mcp-server/dist/remote-questions.js +732 -0
- package/packages/mcp-server/dist/remote-questions.js.map +1 -0
- package/packages/mcp-server/dist/server.d.ts +7 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +70 -8
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/session-manager.d.ts +14 -0
- package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
- package/packages/mcp-server/dist/session-manager.js +49 -1
- package/packages/mcp-server/dist/session-manager.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +163 -25
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +4 -3
- package/packages/mcp-server/src/mcp-server.test.ts +67 -0
- package/packages/mcp-server/src/remote-questions.test.ts +294 -0
- package/packages/mcp-server/src/remote-questions.ts +916 -0
- package/packages/mcp-server/src/server.ts +89 -14
- package/packages/mcp-server/src/session-manager.ts +43 -1
- package/packages/mcp-server/src/workflow-tools.test.ts +146 -1
- package/packages/mcp-server/src/workflow-tools.ts +215 -43
- package/packages/mcp-server/tsconfig.test.json +19 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +12 -0
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +30 -0
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/src/agent-loop.ts +14 -0
- package/packages/pi-agent-core/src/types.ts +34 -0
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/models/custom.d.ts +38 -0
- package/packages/pi-ai/dist/models/custom.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/custom.js +41 -0
- package/packages/pi-ai/dist/models/custom.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +13 -0
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +27 -4
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +13 -4
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +80 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +60 -15
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.d.ts +10 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +16 -1
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/providers/think-tag-parser.d.ts +17 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.js +75 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.js.map +1 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.js +41 -0
- package/packages/pi-ai/dist/providers/think-tag-parser.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js +12 -2
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +164 -14
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +15 -3
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +67 -0
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +16 -3
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +67 -0
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +289 -0
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +1 -0
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/models/custom.ts +42 -0
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +1 -1
- package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -0
- package/packages/pi-ai/src/providers/anthropic-shared.ts +26 -5
- package/packages/pi-ai/src/providers/anthropic.ts +15 -4
- package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +98 -0
- package/packages/pi-ai/src/providers/openai-completions.ts +57 -16
- package/packages/pi-ai/src/providers/simple-options.ts +17 -1
- package/packages/pi-ai/src/providers/think-tag-parser.test.ts +44 -0
- package/packages/pi-ai/src/providers/think-tag-parser.ts +94 -0
- package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +200 -23
- package/packages/pi-ai/src/utils/oauth/github-copilot.ts +12 -2
- package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +84 -0
- package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +15 -5
- package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +84 -0
- package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +16 -5
- package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +363 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +3 -2
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +2 -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 +32 -2
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +4 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +35 -2
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +233 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +205 -2
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts +53 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.js +337 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +234 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/index.js +1 -0
- package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.d.ts +3 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.js +92 -12
- package/packages/pi-coding-agent/dist/core/model-discovery.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.test.js +16 -1
- package/packages/pi-coding-agent/dist/core/model-discovery.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js +40 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js +203 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-discovery.test.js +61 -1
- package/packages/pi-coding-agent/dist/core/model-registry-discovery.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +5 -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 +90 -10
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.js +49 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.js +67 -0
- package/packages/pi-coding-agent/dist/core/redact-secrets.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +10 -6
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js +45 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +55 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +5 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +13 -7
- package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts +7 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +29 -21
- package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- 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 +13 -1
- 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/agent-session-abort-order.test.ts +3 -2
- package/packages/pi-coding-agent/src/core/agent-session.ts +38 -2
- package/packages/pi-coding-agent/src/core/extensions/index.ts +16 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +351 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +258 -0
- package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +269 -0
- package/packages/pi-coding-agent/src/core/hooks-runner.ts +460 -0
- package/packages/pi-coding-agent/src/core/index.ts +10 -0
- package/packages/pi-coding-agent/src/core/model-discovery.test.ts +19 -0
- package/packages/pi-coding-agent/src/core/model-discovery.ts +99 -12
- package/packages/pi-coding-agent/src/core/model-registry-auth-header.test.ts +44 -0
- package/packages/pi-coding-agent/src/core/model-registry-custom-caps.test.ts +245 -0
- package/packages/pi-coding-agent/src/core/model-registry-discovery.test.ts +75 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +102 -10
- package/packages/pi-coding-agent/src/core/redact-secrets.test.ts +86 -0
- package/packages/pi-coding-agent/src/core/redact-secrets.ts +58 -0
- package/packages/pi-coding-agent/src/core/session-manager.test.ts +65 -1
- package/packages/pi-coding-agent/src/core/session-manager.ts +10 -6
- package/packages/pi-coding-agent/src/core/settings-manager.ts +57 -0
- package/packages/pi-coding-agent/src/index.ts +16 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +6 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +16 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +36 -22
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +13 -1
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/pkg/package.json +1 -1
- package/scripts/link-workspace-packages.cjs +1 -0
- package/src/resources/agents/researcher.md +1 -1
- package/src/resources/extensions/claude-code-cli/readiness.ts +32 -8
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +78 -17
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +149 -5
- package/src/resources/extensions/gsd/auto/loop-deps.ts +14 -0
- package/src/resources/extensions/gsd/auto/loop.ts +9 -0
- package/src/resources/extensions/gsd/auto/phases.ts +131 -10
- package/src/resources/extensions/gsd/auto/run-unit.ts +40 -2
- package/src/resources/extensions/gsd/auto/session.ts +35 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +16 -3
- package/src/resources/extensions/gsd/auto-model-selection.ts +71 -15
- package/src/resources/extensions/gsd/auto-post-unit.ts +29 -3
- package/src/resources/extensions/gsd/auto-prompts.ts +28 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +26 -1
- package/src/resources/extensions/gsd/auto-start.ts +60 -68
- package/src/resources/extensions/gsd/auto-verification.ts +33 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +62 -63
- package/src/resources/extensions/gsd/auto.ts +73 -28
- package/src/resources/extensions/gsd/blocked-models.ts +98 -0
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +120 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +40 -9
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +109 -0
- package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +5 -0
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +15 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +54 -6
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +89 -26
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +35 -2
- package/src/resources/extensions/gsd/clean-root-preflight.ts +111 -0
- package/src/resources/extensions/gsd/commands-extract-learnings.ts +55 -90
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +898 -32
- package/src/resources/extensions/gsd/compaction-snapshot.ts +165 -0
- package/src/resources/extensions/gsd/complexity-classifier.ts +5 -3
- package/src/resources/extensions/gsd/db-writer.ts +88 -17
- package/src/resources/extensions/gsd/doctor-git-checks.ts +23 -27
- package/src/resources/extensions/gsd/doctor-providers.ts +59 -6
- package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +2 -0
- package/src/resources/extensions/gsd/error-classifier.ts +36 -3
- package/src/resources/extensions/gsd/exec-history.ts +153 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +326 -0
- package/src/resources/extensions/gsd/gitignore.ts +1 -1
- package/src/resources/extensions/gsd/gsd-db.ts +186 -23
- package/src/resources/extensions/gsd/guided-flow.ts +222 -1
- package/src/resources/extensions/gsd/health-widget.ts +3 -1
- package/src/resources/extensions/gsd/hook-emitter.ts +188 -0
- package/src/resources/extensions/gsd/init-wizard.ts +15 -1
- package/src/resources/extensions/gsd/journal.ts +2 -1
- package/src/resources/extensions/gsd/key-manager.ts +28 -0
- package/src/resources/extensions/gsd/memory-backfill.ts +140 -0
- package/src/resources/extensions/gsd/memory-store.ts +26 -0
- package/src/resources/extensions/gsd/model-router.ts +42 -1
- package/src/resources/extensions/gsd/pre-execution-checks.ts +46 -10
- package/src/resources/extensions/gsd/preferences-types.ts +46 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +79 -0
- package/src/resources/extensions/gsd/preferences.ts +17 -17
- package/src/resources/extensions/gsd/prompt-loader.ts +30 -7
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
- package/src/resources/extensions/gsd/prompts/discuss.md +29 -2
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +119 -0
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +17 -4
- package/src/resources/extensions/gsd/safety/safety-harness.ts +9 -0
- package/src/resources/extensions/gsd/state.ts +45 -4
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +188 -2
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +95 -1
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +141 -0
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +33 -3
- package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/blocked-models.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +68 -66
- package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +61 -1
- 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/complexity-classifier.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +148 -3
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +306 -1
- package/src/resources/extensions/gsd/tests/escalation.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/exec-history.test.ts +237 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +210 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +40 -9
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +447 -1
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-git-symlink-cwd.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/integration/gitignore-tracked-gsd.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/issue-4540-regressions.test.ts +288 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/load-memory-block.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/pre-exec-gate-loop.test.ts +272 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +356 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +103 -4
- package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +388 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +9 -3
- package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +230 -0
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +205 -0
- package/src/resources/extensions/gsd/tests/save-gate-result-render.test.ts +95 -0
- package/src/resources/extensions/gsd/tests/schema-v21-sequence.test.ts +413 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +32 -40
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/token-counter.test.ts +105 -1
- package/src/resources/extensions/gsd/tests/tool-compatibility.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +9 -3
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +65 -2
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -5
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +3 -1
- package/src/resources/extensions/gsd/token-counter.ts +22 -5
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +15 -9
- package/src/resources/extensions/gsd/tools/exec-search-tool.ts +81 -0
- package/src/resources/extensions/gsd/tools/exec-tool.ts +183 -0
- package/src/resources/extensions/gsd/tools/memory-tools.ts +31 -1
- package/src/resources/extensions/gsd/tools/resume-tool.ts +40 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +26 -3
- package/src/resources/extensions/gsd/workflow-logger.ts +4 -1
- package/src/resources/extensions/gsd/workflow-mcp.ts +3 -0
- package/src/resources/extensions/gsd/workflow-templates/spike.md +6 -0
- package/src/resources/extensions/gsd/worktree-resolver.ts +54 -9
- package/src/resources/extensions/search-the-web/command-search-provider.ts +5 -4
- package/src/resources/extensions/search-the-web/native-search.ts +48 -12
- package/src/resources/skills/api-design/SKILL.md +190 -0
- package/src/resources/skills/create-mcp-server/SKILL.md +121 -0
- package/src/resources/skills/decompose-into-slices/SKILL.md +139 -0
- package/src/resources/skills/dependency-upgrade/SKILL.md +158 -0
- package/src/resources/skills/design-an-interface/SKILL.md +102 -0
- package/src/resources/skills/forensics/SKILL.md +153 -0
- package/src/resources/skills/grill-me/SKILL.md +93 -0
- package/src/resources/skills/handoff/SKILL.md +121 -0
- package/src/resources/skills/observability/SKILL.md +174 -0
- package/src/resources/skills/security-review/SKILL.md +181 -0
- package/src/resources/skills/spike-wrap-up/SKILL.md +138 -0
- package/src/resources/skills/tdd/SKILL.md +112 -0
- package/src/resources/skills/verify-before-complete/SKILL.md +98 -0
- package/src/resources/skills/write-docs/SKILL.md +82 -0
- package/src/resources/skills/write-milestone-brief/SKILL.md +135 -0
- /package/dist/web/standalone/.next/static/{ssX7BLv3Dw9Fb4CtrCGeR → pV-mPo7rYGb5JBC09C8GG}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{ssX7BLv3Dw9Fb4CtrCGeR → pV-mPo7rYGb5JBC09C8GG}/_ssgManifest.js +0 -0
|
@@ -292,4 +292,46 @@ export const CUSTOM_MODELS = {
|
|
|
292
292
|
compat: { thinkingFormat: "zai", supportsDeveloperRole: false },
|
|
293
293
|
} satisfies Model<"openai-completions">,
|
|
294
294
|
},
|
|
295
|
+
|
|
296
|
+
// ─── MiniMax additive hotfixes ───────────────────────────────────────
|
|
297
|
+
// models.dev currently omits MiniMax-M2.1-highspeed in some snapshots.
|
|
298
|
+
// Keep this additive (no overrides) so generated models still win when present.
|
|
299
|
+
"minimax": {
|
|
300
|
+
"MiniMax-M2.1-highspeed": {
|
|
301
|
+
id: "MiniMax-M2.1-highspeed",
|
|
302
|
+
name: "MiniMax-M2.1-highspeed",
|
|
303
|
+
api: "anthropic-messages",
|
|
304
|
+
provider: "minimax",
|
|
305
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
306
|
+
reasoning: true,
|
|
307
|
+
input: ["text"],
|
|
308
|
+
cost: {
|
|
309
|
+
input: 0.6,
|
|
310
|
+
output: 2.4,
|
|
311
|
+
cacheRead: 0,
|
|
312
|
+
cacheWrite: 0,
|
|
313
|
+
},
|
|
314
|
+
contextWindow: 204800,
|
|
315
|
+
maxTokens: 131072,
|
|
316
|
+
} satisfies Model<"anthropic-messages">,
|
|
317
|
+
},
|
|
318
|
+
"minimax-cn": {
|
|
319
|
+
"MiniMax-M2.1-highspeed": {
|
|
320
|
+
id: "MiniMax-M2.1-highspeed",
|
|
321
|
+
name: "MiniMax-M2.1-highspeed",
|
|
322
|
+
api: "anthropic-messages",
|
|
323
|
+
provider: "minimax-cn",
|
|
324
|
+
baseUrl: "https://api.minimaxi.com/anthropic",
|
|
325
|
+
reasoning: true,
|
|
326
|
+
input: ["text"],
|
|
327
|
+
cost: {
|
|
328
|
+
input: 0.6,
|
|
329
|
+
output: 2.4,
|
|
330
|
+
cacheRead: 0,
|
|
331
|
+
cacheWrite: 0,
|
|
332
|
+
},
|
|
333
|
+
contextWindow: 204800,
|
|
334
|
+
maxTokens: 131072,
|
|
335
|
+
} satisfies Model<"anthropic-messages">,
|
|
336
|
+
},
|
|
295
337
|
} as const;
|
|
@@ -18,7 +18,7 @@ test("usesAnthropicBearerAuth covers Bearer-only Anthropic-compatible providers
|
|
|
18
18
|
test("createClient routes Bearer-auth providers through authToken (#3783)", () => {
|
|
19
19
|
const source = readFileSync(join(__dirname, "..", "..", "src", "providers", "anthropic.ts"), "utf-8");
|
|
20
20
|
assert.ok(
|
|
21
|
-
source.includes("const usesBearerAuth = usesAnthropicBearerAuth(model.provider)
|
|
21
|
+
source.includes("const usesBearerAuth = usesAnthropicBearerAuth(model.provider)"),
|
|
22
22
|
"createClient should derive auth mode from usesAnthropicBearerAuth",
|
|
23
23
|
);
|
|
24
24
|
assert.ok(
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
|
|
6
|
+
const source = readFileSync(join(import.meta.dirname, "anthropic.ts"), "utf-8");
|
|
7
|
+
|
|
8
|
+
describe("anthropic bearer auth for custom providers (#3874)", () => {
|
|
9
|
+
it("treats Bearer Authorization headers as authToken-capable providers", () => {
|
|
10
|
+
assert.match(
|
|
11
|
+
source,
|
|
12
|
+
/usesAnthropicBearerAuth\(model\.provider\) \|\| hasBearerAuthorizationHeader\(model\)/,
|
|
13
|
+
"custom providers with Authorization headers should opt into bearer auth",
|
|
14
|
+
);
|
|
15
|
+
assert.match(
|
|
16
|
+
source,
|
|
17
|
+
/apiKey: usesBearerAuth \? null : apiKey/,
|
|
18
|
+
"bearer-auth providers should not send x-api-key",
|
|
19
|
+
);
|
|
20
|
+
assert.match(
|
|
21
|
+
source,
|
|
22
|
+
/authToken: usesBearerAuth \? apiKey : undefined/,
|
|
23
|
+
"bearer-auth providers should send authToken instead",
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -339,10 +339,16 @@ export function convertMessages(
|
|
|
339
339
|
});
|
|
340
340
|
}
|
|
341
341
|
} else if (block.type === "toolCall") {
|
|
342
|
+
// Guard: never forward a tool_use block with an empty name.
|
|
343
|
+
// fine-grained-tool-streaming-2025-05-14 can cause the name to arrive
|
|
344
|
+
// as a delta on incompatible providers (e.g. MiniMax), leaving block.name
|
|
345
|
+
// as "". Re-sending that to MiniMax triggers error 2013 (#4538).
|
|
346
|
+
const toolName = isOAuthToken ? toClaudeCodeName(block.name) : block.name;
|
|
347
|
+
if (!toolName) continue;
|
|
342
348
|
blocks.push({
|
|
343
349
|
type: "tool_use",
|
|
344
350
|
id: block.id,
|
|
345
|
-
name:
|
|
351
|
+
name: toolName,
|
|
346
352
|
input: block.arguments ?? {},
|
|
347
353
|
});
|
|
348
354
|
} else if (block.type === "serverToolUse") {
|
|
@@ -505,7 +511,9 @@ export function buildParams(
|
|
|
505
511
|
if (supportsAdaptiveThinking(model.id)) {
|
|
506
512
|
params.thinking = { type: "adaptive" };
|
|
507
513
|
if (options.effort) {
|
|
508
|
-
|
|
514
|
+
// The SDK's OutputConfig.effort type doesn't include "xhigh" yet.
|
|
515
|
+
// Cast so our superset AnthropicEffort type compiles cleanly.
|
|
516
|
+
params.output_config = { effort: options.effort as "low" | "medium" | "high" | "max" };
|
|
509
517
|
}
|
|
510
518
|
} else {
|
|
511
519
|
params.thinking = {
|
|
@@ -641,12 +649,25 @@ export function processAnthropicStream(
|
|
|
641
649
|
output.content.push(block);
|
|
642
650
|
stream.push({ type: "thinking_start", contentIndex: output.content.length - 1, partial: output });
|
|
643
651
|
} else if (event.content_block.type === "tool_use") {
|
|
652
|
+
// Guard: some Anthropic-compatible providers (e.g. MiniMax with
|
|
653
|
+
// fine-grained-tool-streaming beta) stream the tool name as a delta,
|
|
654
|
+
// leaving content_block.name as "" here. Fall back to the tool list
|
|
655
|
+
// if available to avoid storing an empty name in history (#4538).
|
|
656
|
+
const rawName = event.content_block.name;
|
|
657
|
+
let resolvedName: string;
|
|
658
|
+
if (rawName) {
|
|
659
|
+
resolvedName = isOAuthToken ? fromClaudeCodeName(rawName, context.tools) : rawName;
|
|
660
|
+
} else {
|
|
661
|
+
const fallbackName = context.tools?.[0]?.name ?? rawName;
|
|
662
|
+
if (fallbackName && fallbackName !== rawName) {
|
|
663
|
+
console.warn(`[anthropic-shared] Empty tool name in content_block_start (id=${event.content_block.id}); falling back to first tool: ${fallbackName}`);
|
|
664
|
+
}
|
|
665
|
+
resolvedName = fallbackName;
|
|
666
|
+
}
|
|
644
667
|
const block: Block = {
|
|
645
668
|
type: "toolCall",
|
|
646
669
|
id: event.content_block.id,
|
|
647
|
-
name:
|
|
648
|
-
? fromClaudeCodeName(event.content_block.name, context.tools)
|
|
649
|
-
: event.content_block.name,
|
|
670
|
+
name: resolvedName,
|
|
650
671
|
arguments: (event.content_block.input as Record<string, any>) ?? {},
|
|
651
672
|
partialJson: "",
|
|
652
673
|
index: event.index,
|
|
@@ -66,6 +66,11 @@ export function usesAnthropicBearerAuth(provider: Model<"anthropic-messages">["p
|
|
|
66
66
|
return provider === "alibaba-coding-plan" || provider === "minimax" || provider === "minimax-cn";
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
function hasBearerAuthorizationHeader(model: Model<"anthropic-messages">): boolean {
|
|
70
|
+
const authHeader = model.headers?.Authorization ?? model.headers?.authorization;
|
|
71
|
+
return typeof authHeader === "string" && authHeader.trim().toLowerCase().startsWith("bearer ");
|
|
72
|
+
}
|
|
73
|
+
|
|
69
74
|
async function createClient(
|
|
70
75
|
model: Model<"anthropic-messages">,
|
|
71
76
|
apiKey: string,
|
|
@@ -105,8 +110,14 @@ async function createClient(
|
|
|
105
110
|
return { client, isOAuthToken: false };
|
|
106
111
|
}
|
|
107
112
|
|
|
108
|
-
// Skip beta headers for providers that don't support
|
|
109
|
-
|
|
113
|
+
// Skip beta headers for providers that don't support fine-grained-tool-streaming.
|
|
114
|
+
// MiniMax and minimax-cn implement the beta by emitting empty tool names in
|
|
115
|
+
// content_block_start (name arrives as a delta instead), which corrupts conversation
|
|
116
|
+
// history and triggers MiniMax error 2013 on the next request (#4538).
|
|
117
|
+
const skipBetaHeaders =
|
|
118
|
+
model.provider === "alibaba-coding-plan" ||
|
|
119
|
+
model.provider === "minimax" ||
|
|
120
|
+
model.provider === "minimax-cn";
|
|
110
121
|
const betaFeatures = skipBetaHeaders ? [] : ["fine-grained-tool-streaming-2025-05-14"];
|
|
111
122
|
if (needsInterleavedBeta && !skipBetaHeaders) {
|
|
112
123
|
betaFeatures.push("interleaved-thinking-2025-05-14");
|
|
@@ -114,11 +125,11 @@ async function createClient(
|
|
|
114
125
|
|
|
115
126
|
// API key auth (Anthropic OAuth removed per TOS compliance — use API keys or Claude CLI)
|
|
116
127
|
// Some Anthropic-compatible providers require Bearer auth instead of x-api-key.
|
|
117
|
-
const usesBearerAuth = usesAnthropicBearerAuth(model.provider);
|
|
128
|
+
const usesBearerAuth = usesAnthropicBearerAuth(model.provider) || hasBearerAuthorizationHeader(model);
|
|
118
129
|
const client = new AnthropicClass({
|
|
119
130
|
apiKey: usesBearerAuth ? null : apiKey,
|
|
120
131
|
authToken: usesBearerAuth ? apiKey : undefined,
|
|
121
|
-
baseURL: model
|
|
132
|
+
baseURL: resolveAnthropicBaseUrl(model),
|
|
122
133
|
dangerouslyAllowBrowser: true,
|
|
123
134
|
defaultHeaders: mergeHeaders(
|
|
124
135
|
{
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression tests for MiniMax error 2013 "function name or parameters is empty" (#4538).
|
|
3
|
+
*
|
|
4
|
+
* Root cause: the `fine-grained-tool-streaming-2025-05-14` beta header is sent to
|
|
5
|
+
* MiniMax. MiniMax's Anthropic-compatible API implements this beta by streaming the
|
|
6
|
+
* tool name as a delta (empty string in `content_block_start`). The empty name gets
|
|
7
|
+
* stored in conversation history and sent back on the next request, causing MiniMax
|
|
8
|
+
* to return error 2013.
|
|
9
|
+
*
|
|
10
|
+
* Fix: exclude MiniMax (and minimax-cn) from the fine-grained-tool-streaming beta,
|
|
11
|
+
* same as alibaba-coding-plan. Also guard against storing empty tool names.
|
|
12
|
+
*/
|
|
13
|
+
import test, { describe } from "node:test";
|
|
14
|
+
import assert from "node:assert/strict";
|
|
15
|
+
import { readFileSync } from "node:fs";
|
|
16
|
+
import { dirname, join } from "node:path";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
18
|
+
import { convertMessages } from "./anthropic-shared.js";
|
|
19
|
+
import type { AssistantMessage } from "../types.js";
|
|
20
|
+
|
|
21
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
22
|
+
const source = readFileSync(join(__dirname, "anthropic.ts"), "utf-8");
|
|
23
|
+
|
|
24
|
+
describe("MiniMax fine-grained-tool-streaming exclusion (#4538)", () => {
|
|
25
|
+
test("minimax is excluded from fine-grained-tool-streaming-2025-05-14 beta", () => {
|
|
26
|
+
// The skipBetaHeaders flag must include minimax so it never receives the
|
|
27
|
+
// fine-grained-tool-streaming beta that causes empty tool names.
|
|
28
|
+
assert.match(
|
|
29
|
+
source,
|
|
30
|
+
/skipBetaHeaders.*minimax/s,
|
|
31
|
+
"minimax must be included in skipBetaHeaders to suppress fine-grained-tool-streaming",
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("minimax-cn is excluded from fine-grained-tool-streaming-2025-05-14 beta", () => {
|
|
36
|
+
assert.match(
|
|
37
|
+
source,
|
|
38
|
+
/skipBetaHeaders.*minimax-cn/s,
|
|
39
|
+
"minimax-cn must be included in skipBetaHeaders to suppress fine-grained-tool-streaming",
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe("empty tool name guard in convertMessages (#4538)", () => {
|
|
45
|
+
// When fine-grained-tool-streaming causes a tool name to arrive as empty in
|
|
46
|
+
// content_block_start, we must not store '' in conversation history.
|
|
47
|
+
// convertMessages must skip tool_use blocks with empty/missing names.
|
|
48
|
+
const minimaxModel = {
|
|
49
|
+
id: "MiniMax-M2",
|
|
50
|
+
api: "anthropic-messages" as const,
|
|
51
|
+
provider: "minimax" as const,
|
|
52
|
+
baseUrl: "https://api.minimax.io/anthropic",
|
|
53
|
+
reasoning: true,
|
|
54
|
+
input: ["text"] as ["text"],
|
|
55
|
+
name: "MiniMax-M2",
|
|
56
|
+
cost: { input: 0.3, output: 1.2, cacheRead: 0, cacheWrite: 0 },
|
|
57
|
+
contextWindow: 196608,
|
|
58
|
+
maxTokens: 128000,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
test("tool_use blocks with empty name are dropped from converted messages", () => {
|
|
62
|
+
const assistantMsg: AssistantMessage = {
|
|
63
|
+
role: "assistant",
|
|
64
|
+
content: [
|
|
65
|
+
{
|
|
66
|
+
type: "toolCall",
|
|
67
|
+
id: "toolu_01",
|
|
68
|
+
name: "", // empty — the bug: fine-grained streaming left name as ""
|
|
69
|
+
arguments: { path: "/foo" },
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
api: "anthropic-messages",
|
|
73
|
+
provider: "minimax",
|
|
74
|
+
model: "MiniMax-M2",
|
|
75
|
+
usage: { input: 1, output: 1, cacheRead: 0, cacheWrite: 0, totalTokens: 2, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },
|
|
76
|
+
stopReason: "toolUse",
|
|
77
|
+
timestamp: Date.now(),
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const messages = [assistantMsg];
|
|
81
|
+
const result = convertMessages(messages, minimaxModel, false, undefined);
|
|
82
|
+
|
|
83
|
+
// The assistant block with the empty-name toolCall must not appear in the output.
|
|
84
|
+
// If it does appear, its tool_use name must not be empty.
|
|
85
|
+
for (const param of result) {
|
|
86
|
+
if (param.role === "assistant" && Array.isArray(param.content)) {
|
|
87
|
+
for (const block of param.content) {
|
|
88
|
+
if ((block as any).type === "tool_use") {
|
|
89
|
+
assert.ok(
|
|
90
|
+
(block as any).name && (block as any).name.length > 0,
|
|
91
|
+
`tool_use block must never have an empty name; got: "${(block as any).name}"`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
});
|
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
finalizeStream,
|
|
40
40
|
handleStreamError,
|
|
41
41
|
} from "./openai-shared.js";
|
|
42
|
+
import { ThinkTagParser } from "./think-tag-parser.js";
|
|
42
43
|
import { transformMessagesWithReport } from "./transform-messages.js";
|
|
43
44
|
|
|
44
45
|
/**
|
|
@@ -91,6 +92,7 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions", OpenA
|
|
|
91
92
|
stream.push({ type: "start", partial: output });
|
|
92
93
|
|
|
93
94
|
let currentBlock: TextContent | ThinkingContent | (ToolCall & { partialArgs?: string }) | null = null;
|
|
95
|
+
const thinkTagParser = new ThinkTagParser();
|
|
94
96
|
const blocks = output.content;
|
|
95
97
|
const blockIndex = () => blocks.length - 1;
|
|
96
98
|
const finishCurrentBlock = (block?: typeof currentBlock) => {
|
|
@@ -121,6 +123,55 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions", OpenA
|
|
|
121
123
|
}
|
|
122
124
|
}
|
|
123
125
|
};
|
|
126
|
+
const appendTextDelta = (delta: string) => {
|
|
127
|
+
if (!delta) return;
|
|
128
|
+
if (!currentBlock || currentBlock.type !== "text") {
|
|
129
|
+
finishCurrentBlock(currentBlock);
|
|
130
|
+
currentBlock = { type: "text", text: "" };
|
|
131
|
+
output.content.push(currentBlock);
|
|
132
|
+
stream.push({ type: "text_start", contentIndex: blockIndex(), partial: output });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (currentBlock.type === "text") {
|
|
136
|
+
currentBlock.text += delta;
|
|
137
|
+
stream.push({
|
|
138
|
+
type: "text_delta",
|
|
139
|
+
contentIndex: blockIndex(),
|
|
140
|
+
delta,
|
|
141
|
+
partial: output,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
const appendThinkingDelta = (delta: string) => {
|
|
146
|
+
if (!delta) return;
|
|
147
|
+
if (!currentBlock || currentBlock.type !== "thinking") {
|
|
148
|
+
finishCurrentBlock(currentBlock);
|
|
149
|
+
currentBlock = {
|
|
150
|
+
type: "thinking",
|
|
151
|
+
thinking: "",
|
|
152
|
+
thinkingSignature: "think-tag",
|
|
153
|
+
};
|
|
154
|
+
output.content.push(currentBlock);
|
|
155
|
+
stream.push({ type: "thinking_start", contentIndex: blockIndex(), partial: output });
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (currentBlock.type === "thinking") {
|
|
159
|
+
currentBlock.thinking += delta;
|
|
160
|
+
stream.push({
|
|
161
|
+
type: "thinking_delta",
|
|
162
|
+
contentIndex: blockIndex(),
|
|
163
|
+
delta,
|
|
164
|
+
partial: output,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
const appendContentDelta = (delta: string) => {
|
|
169
|
+
const segments = thinkTagParser.consume(delta);
|
|
170
|
+
for (const segment of segments) {
|
|
171
|
+
if (segment.type === "thinking") appendThinkingDelta(segment.text);
|
|
172
|
+
else appendTextDelta(segment.text);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
124
175
|
|
|
125
176
|
for await (const chunk of openaiStream) {
|
|
126
177
|
if (chunk.usage) {
|
|
@@ -161,22 +212,7 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions", OpenA
|
|
|
161
212
|
choice.delta.content !== undefined &&
|
|
162
213
|
choice.delta.content.length > 0
|
|
163
214
|
) {
|
|
164
|
-
|
|
165
|
-
finishCurrentBlock(currentBlock);
|
|
166
|
-
currentBlock = { type: "text", text: "" };
|
|
167
|
-
output.content.push(currentBlock);
|
|
168
|
-
stream.push({ type: "text_start", contentIndex: blockIndex(), partial: output });
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (currentBlock.type === "text") {
|
|
172
|
-
currentBlock.text += choice.delta.content;
|
|
173
|
-
stream.push({
|
|
174
|
-
type: "text_delta",
|
|
175
|
-
contentIndex: blockIndex(),
|
|
176
|
-
delta: choice.delta.content,
|
|
177
|
-
partial: output,
|
|
178
|
-
});
|
|
179
|
-
}
|
|
215
|
+
appendContentDelta(choice.delta.content);
|
|
180
216
|
}
|
|
181
217
|
|
|
182
218
|
// Some endpoints return reasoning in reasoning_content (llama.cpp),
|
|
@@ -276,6 +312,11 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions", OpenA
|
|
|
276
312
|
}
|
|
277
313
|
}
|
|
278
314
|
|
|
315
|
+
for (const segment of thinkTagParser.flush()) {
|
|
316
|
+
if (segment.type === "thinking") appendThinkingDelta(segment.text);
|
|
317
|
+
else appendTextDelta(segment.text);
|
|
318
|
+
}
|
|
319
|
+
|
|
279
320
|
finishCurrentBlock(currentBlock);
|
|
280
321
|
assertStreamSuccess(output, options?.signal);
|
|
281
322
|
finalizeStream(stream, output);
|
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
import type { Api, Model, SimpleStreamOptions, StreamOptions, ThinkingBudgets, ThinkingLevel } from "../types.js";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Compute the default maxTokens for a model when no explicit value is provided.
|
|
5
|
+
*
|
|
6
|
+
* The 32 k cap is retained only for native Anthropic models (api === "anthropic-messages")
|
|
7
|
+
* where the Anthropic API historically rejected higher values. Custom and
|
|
8
|
+
* Anthropic-compatible models (e.g. OpenAI-completions, Vertex, etc.) use their
|
|
9
|
+
* declared model.maxTokens directly so that providers with larger output windows
|
|
10
|
+
* (131 072 tokens, etc.) are not silently capped.
|
|
11
|
+
*/
|
|
12
|
+
export function defaultMaxTokens(model: Model<Api>): number {
|
|
13
|
+
if (model.api === "anthropic-messages") {
|
|
14
|
+
return Math.min(model.maxTokens, 32000);
|
|
15
|
+
}
|
|
16
|
+
return model.maxTokens;
|
|
17
|
+
}
|
|
18
|
+
|
|
3
19
|
export function buildBaseOptions(model: Model<Api>, options?: SimpleStreamOptions, apiKey?: string): StreamOptions {
|
|
4
20
|
return {
|
|
5
21
|
temperature: options?.temperature,
|
|
6
|
-
maxTokens: options?.maxTokens ||
|
|
22
|
+
maxTokens: options?.maxTokens || defaultMaxTokens(model),
|
|
7
23
|
signal: options?.signal,
|
|
8
24
|
apiKey: apiKey || options?.apiKey,
|
|
9
25
|
cacheRetention: options?.cacheRetention,
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { ThinkTagParser } from "./think-tag-parser.js";
|
|
4
|
+
|
|
5
|
+
describe("ThinkTagParser", () => {
|
|
6
|
+
it("keeps plain text untouched", () => {
|
|
7
|
+
const parser = new ThinkTagParser();
|
|
8
|
+
assert.deepEqual(parser.consume("hello world"), [{ type: "text", text: "hello world" }]);
|
|
9
|
+
assert.deepEqual(parser.flush(), []);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("splits inline think tags into thinking segments", () => {
|
|
13
|
+
const parser = new ThinkTagParser();
|
|
14
|
+
const out = parser.consume("A<think>B</think>C");
|
|
15
|
+
assert.deepEqual(out, [
|
|
16
|
+
{ type: "text", text: "A" },
|
|
17
|
+
{ type: "thinking", text: "B" },
|
|
18
|
+
{ type: "text", text: "C" },
|
|
19
|
+
]);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("handles tag boundaries across deltas", () => {
|
|
23
|
+
const parser = new ThinkTagParser();
|
|
24
|
+
const out1 = parser.consume("A<th");
|
|
25
|
+
const out2 = parser.consume("ink>B</thi");
|
|
26
|
+
const out3 = parser.consume("nk>C");
|
|
27
|
+
const out4 = parser.flush();
|
|
28
|
+
assert.deepEqual([...out1, ...out2, ...out3, ...out4], [
|
|
29
|
+
{ type: "text", text: "A" },
|
|
30
|
+
{ type: "thinking", text: "B" },
|
|
31
|
+
{ type: "text", text: "C" },
|
|
32
|
+
]);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("flushes unclosed think blocks as thinking", () => {
|
|
36
|
+
const parser = new ThinkTagParser();
|
|
37
|
+
const out1 = parser.consume("A<think>partial");
|
|
38
|
+
const out2 = parser.flush();
|
|
39
|
+
assert.deepEqual([...out1, ...out2], [
|
|
40
|
+
{ type: "text", text: "A" },
|
|
41
|
+
{ type: "thinking", text: "partial" },
|
|
42
|
+
]);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
export type ThinkSegmentType = "text" | "thinking";
|
|
2
|
+
|
|
3
|
+
export interface ThinkSegment {
|
|
4
|
+
type: ThinkSegmentType;
|
|
5
|
+
text: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface ThinkTagParserState {
|
|
9
|
+
mode: ThinkSegmentType;
|
|
10
|
+
pending: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const OPEN_TAG = "<think>";
|
|
14
|
+
const CLOSE_TAG = "</think>";
|
|
15
|
+
|
|
16
|
+
function trailingPartialLength(text: string, token: string): number {
|
|
17
|
+
const max = Math.min(text.length, token.length - 1);
|
|
18
|
+
for (let len = max; len > 0; len--) {
|
|
19
|
+
if (token.startsWith(text.slice(-len))) return len;
|
|
20
|
+
}
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Stateful parser for streaming `<think>...</think>` wrappers emitted by some
|
|
26
|
+
* OpenAI-compatible providers. Converts tagged sections into logical
|
|
27
|
+
* text/thinking segments while handling chunk boundaries safely.
|
|
28
|
+
*/
|
|
29
|
+
export class ThinkTagParser {
|
|
30
|
+
private state: ThinkTagParserState = { mode: "text", pending: "" };
|
|
31
|
+
|
|
32
|
+
consume(delta: string): ThinkSegment[] {
|
|
33
|
+
this.state.pending += delta;
|
|
34
|
+
return this.drain(false);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
flush(): ThinkSegment[] {
|
|
38
|
+
return this.drain(true);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private drain(flushAll: boolean): ThinkSegment[] {
|
|
42
|
+
const out: ThinkSegment[] = [];
|
|
43
|
+
const push = (type: ThinkSegmentType, text: string) => {
|
|
44
|
+
if (!text) return;
|
|
45
|
+
out.push({ type, text });
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
while (this.state.pending.length > 0) {
|
|
49
|
+
if (this.state.mode === "text") {
|
|
50
|
+
const openIdx = this.state.pending.indexOf(OPEN_TAG);
|
|
51
|
+
if (openIdx >= 0) {
|
|
52
|
+
push("text", this.state.pending.slice(0, openIdx));
|
|
53
|
+
this.state.pending = this.state.pending.slice(openIdx + OPEN_TAG.length);
|
|
54
|
+
this.state.mode = "thinking";
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (flushAll) {
|
|
59
|
+
push("text", this.state.pending);
|
|
60
|
+
this.state.pending = "";
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const keep = trailingPartialLength(this.state.pending, OPEN_TAG);
|
|
65
|
+
const safeEnd = Math.max(0, this.state.pending.length - keep);
|
|
66
|
+
push("text", this.state.pending.slice(0, safeEnd));
|
|
67
|
+
this.state.pending = this.state.pending.slice(safeEnd);
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const closeIdx = this.state.pending.indexOf(CLOSE_TAG);
|
|
72
|
+
if (closeIdx >= 0) {
|
|
73
|
+
push("thinking", this.state.pending.slice(0, closeIdx));
|
|
74
|
+
this.state.pending = this.state.pending.slice(closeIdx + CLOSE_TAG.length);
|
|
75
|
+
this.state.mode = "text";
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (flushAll) {
|
|
80
|
+
push("thinking", this.state.pending);
|
|
81
|
+
this.state.pending = "";
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const keep = trailingPartialLength(this.state.pending, CLOSE_TAG);
|
|
86
|
+
const safeEnd = Math.max(0, this.state.pending.length - keep);
|
|
87
|
+
push("thinking", this.state.pending.slice(0, safeEnd));
|
|
88
|
+
this.state.pending = this.state.pending.slice(safeEnd);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return out;
|
|
93
|
+
}
|
|
94
|
+
}
|