@earendil-works/pi-coding-agent 0.87.0 → 0.99.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/CHANGELOG.md +103 -0
- package/README.md +25 -711
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/restore-sandbox-env.d.ts.map +1 -1
- package/dist/bun/restore-sandbox-env.js.map +1 -1
- package/dist/bun/runtime-setup.d.ts.map +1 -1
- package/dist/bun/runtime-setup.js +4 -1
- package/dist/bun/runtime-setup.js.map +1 -1
- package/dist/bun/sandbox-env-setup.d.ts.map +1 -1
- package/dist/bundle/chunks/anthropic-messages-A6EXUBG6.js +6 -0
- package/dist/bundle/chunks/anthropic.js +2 -2
- package/dist/bundle/chunks/azure-openai-responses-EN5WOBET.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +2 -2
- package/dist/bundle/chunks/chunk-4CSSZFEW.js +1435 -0
- package/dist/bundle/chunks/chunk-7JGR3GZN.js +11 -0
- package/dist/bundle/chunks/chunk-AXPY26X7.js +146 -0
- package/dist/bundle/chunks/chunk-EPDRUIU6.js +2 -0
- package/dist/bundle/chunks/chunk-GOPCREV2.js +4 -0
- package/dist/bundle/chunks/chunk-H3QXYIF7.js +31 -0
- package/dist/bundle/chunks/{chunk-S7SZN6Z3.js → chunk-HSPCVFST.js} +1 -1
- package/dist/bundle/chunks/chunk-IMTXZUO7.js +82 -0
- package/dist/bundle/chunks/chunk-J4CWPC4N.js +2 -0
- package/dist/bundle/chunks/chunk-LLMKQWZS.js +21 -0
- package/dist/bundle/chunks/{chunk-WIUZI2CJ.js → chunk-LRS5S6EK.js} +3 -3
- package/dist/bundle/chunks/chunk-PEHWOV5U.js +187 -0
- package/dist/bundle/chunks/{chunk-XDUWOHPL.js → chunk-S3GGRYIO.js} +2 -2
- package/dist/bundle/chunks/chunk-UTB4DTYQ.js +2 -0
- package/dist/bundle/chunks/{chunk-FUXEF6JQ.js → chunk-W2DOMZSC.js} +1 -1
- package/dist/bundle/chunks/cli-AZXNGIZH.js +49 -0
- package/dist/bundle/chunks/cloudflare-workers-ai-system-one-XJQQYGGU.js +2 -0
- package/dist/bundle/chunks/codemode-worker.js +295 -0
- package/dist/bundle/chunks/execute-7XXPZAWW.js +308 -0
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/google-generative-ai-CQAKKJTA.js +2 -0
- package/dist/bundle/chunks/google-vertex-AE36YXJU.js +2 -0
- package/dist/bundle/chunks/{lib-HGQMNYVT.js → lib-TEDK3E5I.js} +2 -2
- package/dist/bundle/chunks/llama-cpp-classify-PJJYKPLD.js +22 -0
- package/dist/bundle/chunks/mistral-conversations-KEYTXJM7.js +5 -0
- package/dist/bundle/chunks/{openai-codex-responses-QDSOTBBO.js → openai-codex-responses-JQTCOVEG.js} +2 -2
- package/dist/bundle/chunks/openai-codex.js +2 -2
- package/dist/bundle/chunks/{openai-completions-XHML6MTL.js → openai-completions-XW2Q5HVC.js} +2 -2
- package/dist/bundle/chunks/openai-responses-6AXWFL75.js +3 -0
- package/dist/bundle/chunks/{openrouter-images-N4XVVFSD.js → openrouter-images-TPQ4V6OR.js} +1 -1
- package/dist/bundle/chunks/openrouter.js +2 -2
- package/dist/bundle/chunks/{pi-messages-GFKBWJHZ.js → pi-messages-TM5SOOIW.js} +2 -2
- package/dist/bundle/chunks/radius.js +2 -2
- package/dist/bundle/chunks/runtime-G5WJPRBM.js +2 -0
- package/dist/bundle/chunks/typesafe-system-one-E7A4HNJI.js +2 -0
- package/dist/bundle/chunks/virtual-modules-AQ3FLU6H.js +2 -0
- package/dist/bundle/cli-runtime.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +18 -7
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth-check.d.ts.map +1 -1
- package/dist/cli/auth-check.js.map +1 -1
- package/dist/cli/auth-command.d.ts.map +1 -1
- package/dist/cli/auth-command.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/credential-print.d.ts.map +1 -1
- package/dist/cli/credential-print.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/initial-message.d.ts +1 -1
- package/dist/cli/initial-message.d.ts.map +1 -1
- package/dist/cli/initial-message.js.map +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/project-trust.d.ts.map +1 -1
- package/dist/cli/project-trust.js.map +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +38 -30
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/config.d.ts +18 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +30 -4
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +1 -1
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +13 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +135 -11
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +509 -253
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-guidance.d.ts.map +1 -1
- package/dist/core/auth-guidance.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/bug-report-upload.d.ts.map +1 -1
- package/dist/core/bug-report-upload.js.map +1 -1
- package/dist/core/bug-report.d.ts +1 -1
- package/dist/core/bug-report.d.ts.map +1 -1
- package/dist/core/bug-report.js +1 -1
- package/dist/core/bug-report.js.map +1 -1
- package/dist/core/cache-stats.d.ts.map +1 -1
- package/dist/core/cache-stats.js.map +1 -1
- package/dist/core/cache-warmer.d.ts.map +1 -1
- package/dist/core/cache-warmer.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +10 -31
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/utils.d.ts +2 -1
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js +25 -18
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/crash-log.d.ts.map +1 -1
- package/dist/core/crash-log.js +2 -1
- package/dist/core/crash-log.js.map +1 -1
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/diagnostics.d.ts.map +1 -1
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js.map +1 -1
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
- package/dist/core/export-html/ansi-to-html.js.map +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/template.css +10 -0
- package/dist/core/export-html/template.js +66 -17
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/jiti-loader.d.ts.map +1 -1
- package/dist/core/extensions/jiti-static-loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +55 -5
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +18 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +99 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +296 -22
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.d.ts +2 -2
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +3 -3
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/keybindings.d.ts +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +1 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/mcp-servers.d.ts +98 -0
- package/dist/core/mcp-servers.d.ts.map +1 -0
- package/dist/core/mcp-servers.js +157 -0
- package/dist/core/mcp-servers.js.map +1 -0
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts +13 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +25 -0
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +2 -2
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +5 -5
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +41 -3
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +167 -17
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/nested-tool-calls.d.ts +102 -0
- package/dist/core/nested-tool-calls.d.ts.map +1 -0
- package/dist/core/nested-tool-calls.js +178 -0
- package/dist/core/nested-tool-calls.js.map +1 -0
- package/dist/core/output-guard.d.ts.map +1 -1
- package/dist/core/output-guard.js.map +1 -1
- package/dist/core/package-manager.d.ts +4 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +59 -12
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/provider-composer.d.ts +40 -21
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +92 -40
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/radius.d.ts.map +1 -1
- package/dist/core/radius.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts +8 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +18 -3
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/resource-loader.d.ts +7 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +161 -35
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-credentials.d.ts.map +1 -1
- package/dist/core/runtime-credentials.js.map +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +24 -6
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-cwd.d.ts.map +1 -1
- package/dist/core/session-cwd.js.map +1 -1
- package/dist/core/session-export.d.ts.map +1 -1
- package/dist/core/session-export.js.map +1 -1
- package/dist/core/session-manager.d.ts +9 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +22 -22
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-diagnostics.d.ts.map +1 -1
- package/dist/core/settings-diagnostics.js.map +1 -1
- package/dist/core/settings-manager.d.ts +31 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +72 -2
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/source-info.d.ts +8 -0
- package/dist/core/source-info.d.ts.map +1 -1
- package/dist/core/source-info.js +16 -0
- package/dist/core/source-info.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/bash.d.ts +12 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +35 -2
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +11 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +36 -0
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.js.map +1 -1
- package/dist/core/tools/powershell.d.ts.map +1 -1
- package/dist/core/tools/powershell.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +6 -0
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +26 -0
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/renderers/bash.d.ts.map +1 -1
- package/dist/core/tools/renderers/bash.js +9 -10
- package/dist/core/tools/renderers/bash.js.map +1 -1
- package/dist/core/tools/renderers/edit.d.ts.map +1 -1
- package/dist/core/tools/renderers/edit.js.map +1 -1
- package/dist/core/tools/renderers/find.d.ts.map +1 -1
- package/dist/core/tools/renderers/find.js.map +1 -1
- package/dist/core/tools/renderers/grep.d.ts.map +1 -1
- package/dist/core/tools/renderers/grep.js.map +1 -1
- package/dist/core/tools/renderers/index.d.ts.map +1 -1
- package/dist/core/tools/renderers/index.js.map +1 -1
- package/dist/core/tools/renderers/ls.d.ts.map +1 -1
- package/dist/core/tools/renderers/ls.js.map +1 -1
- package/dist/core/tools/renderers/read.d.ts.map +1 -1
- package/dist/core/tools/renderers/read.js +3 -2
- package/dist/core/tools/renderers/read.js.map +1 -1
- package/dist/core/tools/renderers/write.d.ts.map +1 -1
- package/dist/core/tools/renderers/write.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts +5 -3
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +3 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/tools/truncate.d.ts +14 -0
- package/dist/core/tools/truncate.d.ts.map +1 -1
- package/dist/core/tools/truncate.js +29 -0
- package/dist/core/tools/truncate.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +1 -0
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/usage-totals.d.ts +2 -0
- package/dist/core/usage-totals.d.ts.map +1 -1
- package/dist/core/usage-totals.js +23 -0
- package/dist/core/usage-totals.js.map +1 -1
- package/dist/core/virtual-models.d.ts +115 -0
- package/dist/core/virtual-models.d.ts.map +1 -0
- package/dist/core/virtual-models.js +117 -0
- package/dist/core/virtual-models.js.map +1 -0
- package/dist/extensions/codemode/execute.d.ts +16 -0
- package/dist/extensions/codemode/execute.d.ts.map +1 -0
- package/dist/extensions/codemode/execute.js +390 -0
- package/dist/extensions/codemode/execute.js.map +1 -0
- package/dist/extensions/codemode/execute.lazy.d.ts +3 -0
- package/dist/extensions/codemode/execute.lazy.d.ts.map +1 -0
- package/dist/extensions/codemode/execute.lazy.js +3 -0
- package/dist/extensions/codemode/execute.lazy.js.map +1 -0
- package/dist/extensions/codemode/index.d.ts +21 -0
- package/dist/extensions/codemode/index.d.ts.map +1 -0
- package/dist/extensions/codemode/index.js +31 -0
- package/dist/extensions/codemode/index.js.map +1 -0
- package/dist/extensions/codemode/renderer.d.ts +12 -0
- package/dist/extensions/codemode/renderer.d.ts.map +1 -0
- package/dist/extensions/codemode/renderer.js +119 -0
- package/dist/extensions/codemode/renderer.js.map +1 -0
- package/dist/extensions/codemode/tool.d.ts +122 -0
- package/dist/extensions/codemode/tool.d.ts.map +1 -0
- package/dist/extensions/codemode/tool.js +324 -0
- package/dist/extensions/codemode/tool.js.map +1 -0
- package/dist/extensions/codemode/worker.d.ts +7 -0
- package/dist/extensions/codemode/worker.d.ts.map +1 -0
- package/dist/extensions/codemode/worker.js +7 -0
- package/dist/extensions/codemode/worker.js.map +1 -0
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +11 -1
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/llama/client.d.ts.map +1 -1
- package/dist/extensions/llama/client.js.map +1 -1
- package/dist/extensions/llama/huggingface.d.ts.map +1 -1
- package/dist/extensions/llama/huggingface.js.map +1 -1
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +65 -13
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/extensions/llama/ui.d.ts.map +1 -1
- package/dist/extensions/llama/ui.js.map +1 -1
- package/dist/extensions/mcp/cli.d.ts +21 -0
- package/dist/extensions/mcp/cli.d.ts.map +1 -0
- package/dist/extensions/mcp/cli.js +485 -0
- package/dist/extensions/mcp/cli.js.map +1 -0
- package/dist/extensions/mcp/cli.lazy.d.ts +3 -0
- package/dist/extensions/mcp/cli.lazy.d.ts.map +1 -0
- package/dist/extensions/mcp/cli.lazy.js +3 -0
- package/dist/extensions/mcp/cli.lazy.js.map +1 -0
- package/dist/extensions/mcp/config.d.ts +70 -0
- package/dist/extensions/mcp/config.d.ts.map +1 -0
- package/dist/extensions/mcp/config.js +146 -0
- package/dist/extensions/mcp/config.js.map +1 -0
- package/dist/extensions/mcp/index.d.ts +52 -0
- package/dist/extensions/mcp/index.d.ts.map +1 -0
- package/dist/extensions/mcp/index.js +902 -0
- package/dist/extensions/mcp/index.js.map +1 -0
- package/dist/extensions/mcp/log.d.ts +16 -0
- package/dist/extensions/mcp/log.d.ts.map +1 -0
- package/dist/extensions/mcp/log.js +66 -0
- package/dist/extensions/mcp/log.js.map +1 -0
- package/dist/extensions/mcp/oauth.d.ts +94 -0
- package/dist/extensions/mcp/oauth.d.ts.map +1 -0
- package/dist/extensions/mcp/oauth.js +333 -0
- package/dist/extensions/mcp/oauth.js.map +1 -0
- package/dist/extensions/mcp/resources.d.ts +43 -0
- package/dist/extensions/mcp/resources.d.ts.map +1 -0
- package/dist/extensions/mcp/resources.js +262 -0
- package/dist/extensions/mcp/resources.js.map +1 -0
- package/dist/extensions/mcp/runtime.d.ts +96 -0
- package/dist/extensions/mcp/runtime.d.ts.map +1 -0
- package/dist/extensions/mcp/runtime.js +388 -0
- package/dist/extensions/mcp/runtime.js.map +1 -0
- package/dist/extensions/mcp/runtime.lazy.d.ts +3 -0
- package/dist/extensions/mcp/runtime.lazy.d.ts.map +1 -0
- package/dist/extensions/mcp/runtime.lazy.js +3 -0
- package/dist/extensions/mcp/runtime.lazy.js.map +1 -0
- package/dist/extensions/mcp/tools.d.ts +83 -0
- package/dist/extensions/mcp/tools.d.ts.map +1 -0
- package/dist/extensions/mcp/tools.js +233 -0
- package/dist/extensions/mcp/tools.js.map +1 -0
- package/dist/extensions/mcp/ui.d.ts +60 -0
- package/dist/extensions/mcp/ui.d.ts.map +1 -0
- package/dist/extensions/mcp/ui.js +172 -0
- package/dist/extensions/mcp/ui.js.map +1 -0
- package/dist/extensions/tool-search/index.d.ts +12 -0
- package/dist/extensions/tool-search/index.d.ts.map +1 -0
- package/dist/extensions/tool-search/index.js +15 -0
- package/dist/extensions/tool-search/index.js.map +1 -0
- package/dist/extensions/tool-search/tool.d.ts +72 -0
- package/dist/extensions/tool-search/tool.d.ts.map +1 -0
- package/dist/extensions/tool-search/tool.js +210 -0
- package/dist/extensions/tool-search/tool.js.map +1 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +10 -0
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/interactive/bug-report.d.ts.map +1 -1
- package/dist/modes/interactive/bug-report.js.map +1 -1
- package/dist/modes/interactive/chat-viewport.d.ts.map +1 -1
- package/dist/modes/interactive/chat-viewport.js.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +13 -3
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-entry.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/dist/modes/interactive/components/diff.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts +4 -4
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +8 -2
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +7 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +43 -3
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
- package/dist/modes/interactive/components/mermaid.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/pi-logo.d.ts +12 -0
- package/dist/modes/interactive/components/pi-logo.d.ts.map +1 -0
- package/dist/modes/interactive/components/pi-logo.js +25 -0
- package/dist/modes/interactive/components/pi-logo.js.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +28 -6
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/themed-text.d.ts +17 -0
- package/dist/modes/interactive/components/themed-text.d.ts.map +1 -0
- package/dist/modes/interactive/components/themed-text.js +29 -0
- package/dist/modes/interactive/components/themed-text.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +2 -2
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/trust-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +11 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +199 -161
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -1
- package/dist/modes/interactive/model-catalog-refresh.js.map +1 -1
- package/dist/modes/interactive/model-search.d.ts.map +1 -1
- package/dist/modes/interactive/model-search.js.map +1 -1
- package/dist/modes/interactive/session-share.d.ts.map +1 -1
- package/dist/modes/interactive/session-share.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +59 -72
- package/dist/modes/interactive/theme/light.json +57 -69
- package/dist/modes/interactive/theme/system-theme.d.ts +54 -0
- package/dist/modes/interactive/theme/system-theme.d.ts.map +1 -0
- package/dist/modes/interactive/theme/system-theme.js +535 -0
- package/dist/modes/interactive/theme/system-theme.js.map +1 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +46 -6
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +127 -47
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-json.d.ts +1 -0
- package/dist/modes/interactive/theme/theme-json.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-json.js +3 -1
- package/dist/modes/interactive/theme/theme-json.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +7 -2
- package/dist/modes/interactive/theme/theme.d.ts +66 -39
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +238 -317
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/interactive/tui-renderer.d.ts +2 -1
- package/dist/modes/interactive/tui-renderer.d.ts.map +1 -1
- package/dist/modes/interactive/tui-renderer.js +1 -0
- package/dist/modes/interactive/tui-renderer.js.map +1 -1
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/jsonl.d.ts.map +1 -1
- package/dist/modes/rpc/jsonl.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +6 -6
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +12 -8
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +7 -9
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +10 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +6 -2
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/rpc-entry.d.ts.map +1 -1
- package/dist/rpc-entry.js.map +1 -1
- package/dist/utils/abort.d.ts.map +1 -1
- package/dist/utils/abort.js.map +1 -1
- package/dist/utils/ansi.d.ts.map +1 -1
- package/dist/utils/ansi.js.map +1 -1
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/clipboard-command.d.ts.map +1 -1
- package/dist/utils/clipboard-command.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +14 -17
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard.d.ts +2 -0
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +5 -0
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/deprecation.d.ts.map +1 -1
- package/dist/utils/deprecation.js.map +1 -1
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js.map +1 -1
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/html.d.ts.map +1 -1
- package/dist/utils/html.js.map +1 -1
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-process.d.ts.map +1 -1
- package/dist/utils/image-process.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts.map +1 -1
- package/dist/utils/image-resize-core.js.map +1 -1
- package/dist/utils/image-resize-worker.d.ts.map +1 -1
- package/dist/utils/image-resize-worker.js.map +1 -1
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/json.d.ts.map +1 -1
- package/dist/utils/json.js.map +1 -1
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/mime.d.ts.map +1 -1
- package/dist/utils/mime.js.map +1 -1
- package/dist/utils/open-browser.d.ts.map +1 -1
- package/dist/utils/open-browser.js.map +1 -1
- package/dist/utils/paths.d.ts +3 -3
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +5 -4
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/photon.d.ts.map +1 -1
- package/dist/utils/photon.js.map +1 -1
- package/dist/utils/pi-user-agent.d.ts.map +1 -1
- package/dist/utils/pi-user-agent.js.map +1 -1
- package/dist/utils/shell.d.ts +1 -3
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +3 -30
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/sleep.d.ts.map +1 -1
- package/dist/utils/sleep.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +2 -0
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/text.d.ts.map +1 -1
- package/dist/utils/text.js.map +1 -1
- package/dist/utils/tool-result-images.d.ts.map +1 -1
- package/dist/utils/tool-result-images.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/windows-self-update.d.ts.map +1 -1
- package/dist/utils/windows-self-update.js.map +1 -1
- package/dist/utils/wsl.d.ts.map +1 -1
- package/dist/utils/wsl.js.map +1 -1
- package/dist/utils/zip.d.ts.map +1 -1
- package/dist/utils/zip.js.map +1 -1
- package/docs/cli-integration.md +106 -0
- package/docs/cli.md +329 -0
- package/docs/compaction.md +22 -22
- package/docs/configuration.md +47 -0
- package/docs/containerization.md +109 -82
- package/docs/custom-provider.md +109 -722
- package/docs/docs.json +147 -99
- package/docs/environment-variables.md +3 -5
- package/docs/extensions.md +165 -2996
- package/docs/how-pi-works.md +49 -0
- package/docs/images/interactive-mode.png +0 -0
- package/docs/index.md +24 -69
- package/docs/json.md +193 -65
- package/docs/keybindings.md +58 -103
- package/docs/llama-cpp.md +16 -3
- package/docs/mcp.md +188 -0
- package/docs/message-types.md +261 -0
- package/docs/models.md +81 -556
- package/docs/packages.md +67 -166
- package/docs/prompt-templates.md +31 -68
- package/docs/providers.md +103 -240
- package/docs/quickstart.md +61 -106
- package/docs/rpc-commands.md +860 -0
- package/docs/rpc-extension-ui.md +200 -0
- package/docs/rpc.md +130 -1555
- package/docs/sdk.md +79 -1169
- package/docs/security.md +72 -32
- package/docs/session-format.md +15 -215
- package/docs/sessions.md +35 -141
- package/docs/settings.md +116 -377
- package/docs/shell-aliases.md +85 -5
- package/docs/skills.md +51 -190
- package/docs/slash-commands.md +60 -0
- package/docs/terminal-setup.md +105 -78
- package/docs/termux.md +74 -83
- package/docs/themes.md +88 -274
- package/docs/tmux.md +31 -39
- package/docs/tui.md +74 -910
- package/docs/usage.md +54 -272
- package/docs/virtual-models.md +114 -0
- package/docs/windows.md +45 -17
- package/examples/README.md +13 -2
- package/examples/extensions/README.md +2 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +5 -5
- package/examples/extensions/debug-provider.ts +90 -0
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/jev-router.ts +113 -0
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/rpc-client.ts +35 -0
- package/examples/rpc-extension-ui.ts +26 -6
- package/examples/sdk/14-codemode-mcp.ts +61 -0
- package/examples/sdk/README.md +3 -2
- package/npm-shrinkwrap.json +89 -39
- package/package.json +14 -12
- package/dist/bundle/chunks/anthropic-messages-MYU5ZMRF.js +0 -6
- package/dist/bundle/chunks/azure-openai-responses-HUSQ3GP2.js +0 -2
- package/dist/bundle/chunks/chunk-4DKZACXI.js +0 -1568
- package/dist/bundle/chunks/chunk-6R7UI4IY.js +0 -2
- package/dist/bundle/chunks/chunk-GV2E3GBU.js +0 -2
- package/dist/bundle/chunks/chunk-NUHFSC37.js +0 -25
- package/dist/bundle/chunks/chunk-RCZIEVGO.js +0 -11
- package/dist/bundle/chunks/google-generative-ai-IMS5EK2Y.js +0 -2
- package/dist/bundle/chunks/google-vertex-O4YJEQUW.js +0 -2
- package/dist/bundle/chunks/mistral-conversations-NOSQHBEY.js +0 -5
- package/dist/bundle/chunks/openai-responses-HWEUZ6WZ.js +0 -2
- package/dist/bundle/chunks/virtual-modules-BNWPZYDH.js +0 -2
- package/docs/development.md +0 -90
package/docs/custom-provider.md
CHANGED
|
@@ -1,786 +1,173 @@
|
|
|
1
1
|
# Custom Providers
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A provider extension connects Pi to a model service that needs custom authentication, model discovery, request handling, or streaming. If the service already speaks a supported API, configure it in `models.json` instead.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- **Custom endpoints** - Use self-hosted or private model deployments
|
|
7
|
-
- **OAuth/SSO** - Add authentication flows for enterprise providers
|
|
8
|
-
- **Custom APIs** - Implement streaming for non-standard LLM APIs
|
|
5
|
+
Provider extensions run inside Pi and can inspect credentials, prompts, tool definitions, model responses, and usage. Treat them as trusted code and avoid logging secrets or provider payloads.
|
|
9
6
|
|
|
10
|
-
##
|
|
7
|
+
## Choose the smallest integration
|
|
11
8
|
|
|
12
|
-
|
|
9
|
+
| Requirement | Use |
|
|
10
|
+
|---|---|
|
|
11
|
+
| Add models behind a supported API | [`models.json`](models.md#configure-a-compatible-endpoint) |
|
|
12
|
+
| Change an existing provider endpoint or headers | `models.json` or a small provider extension |
|
|
13
|
+
| Discover models dynamically | A provider with `refreshModels` |
|
|
14
|
+
| Add a `/login` flow | A provider with native or legacy OAuth configuration |
|
|
15
|
+
| Implement an unsupported wire protocol | A provider with `stream` or `streamSimple` |
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
- [`examples/extensions/custom-provider-gitlab-duo/`](../examples/extensions/custom-provider-gitlab-duo/)
|
|
17
|
+
A provider extension is an [extension](extensions.md), so it follows the same loading, trust, reload, and error behavior.
|
|
16
18
|
|
|
17
|
-
##
|
|
19
|
+
## Register a provider
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
- [Quick Reference](#quick-reference)
|
|
21
|
-
- [Override Existing Provider](#override-existing-provider)
|
|
22
|
-
- [Register New Provider](#register-new-provider)
|
|
23
|
-
- [Unregister Provider](#unregister-provider)
|
|
24
|
-
- [OAuth Support](#oauth-support)
|
|
25
|
-
- [Custom Streaming API](#custom-streaming-api)
|
|
26
|
-
- [Context Overflow Errors](#context-overflow-errors)
|
|
27
|
-
- [Testing Your Implementation](#testing-your-implementation)
|
|
28
|
-
- [Config Reference](#config-reference)
|
|
29
|
-
- [Model Definition Reference](#model-definition-reference)
|
|
21
|
+
Call `pi.registerProvider()` from the extension factory. Pi waits for asynchronous factories before startup continues, so providers registered there are available to startup model selection and `pi --list-models`.
|
|
30
22
|
|
|
31
|
-
|
|
23
|
+
There are two registration forms:
|
|
32
24
|
|
|
33
|
-
|
|
25
|
+
- Register a complete `Provider` from `@earendil-works/pi-ai` for native authentication, filtering, discovery, refresh, and streaming behavior.
|
|
26
|
+
- Register a provider name with `ProviderConfig` for the legacy configuration form used by existing extensions.
|
|
34
27
|
|
|
35
|
-
|
|
36
|
-
import { createProvider, openAICompletionsApi } from "@earendil-works/pi-ai";
|
|
37
|
-
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
38
|
-
|
|
39
|
-
export default function (pi: ExtensionAPI) {
|
|
40
|
-
pi.registerProvider(createProvider({
|
|
41
|
-
id: "native-local",
|
|
42
|
-
name: "Native Local",
|
|
43
|
-
baseUrl: "http://localhost:8080/v1",
|
|
44
|
-
auth: {
|
|
45
|
-
apiKey: {
|
|
46
|
-
name: "Local server API key",
|
|
47
|
-
async login(interaction) {
|
|
48
|
-
return {
|
|
49
|
-
type: "api_key",
|
|
50
|
-
key: await interaction.prompt({ type: "secret", message: "API key" })
|
|
51
|
-
};
|
|
52
|
-
},
|
|
53
|
-
async resolve({ credential }) {
|
|
54
|
-
return credential?.key
|
|
55
|
-
? { auth: { apiKey: credential.key }, source: "stored API key" }
|
|
56
|
-
: undefined;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
models: [],
|
|
61
|
-
api: openAICompletionsApi()
|
|
62
|
-
}));
|
|
63
|
-
|
|
64
|
-
// Legacy provider-config form:
|
|
65
|
-
// Override baseUrl for existing provider
|
|
66
|
-
pi.registerProvider("anthropic", {
|
|
67
|
-
baseUrl: "https://proxy.example.com"
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// Register new provider with models
|
|
71
|
-
pi.registerProvider("my-provider", {
|
|
72
|
-
name: "My Provider",
|
|
73
|
-
baseUrl: "https://api.example.com",
|
|
74
|
-
apiKey: "$MY_API_KEY",
|
|
75
|
-
api: "openai-completions",
|
|
76
|
-
models: [
|
|
77
|
-
{
|
|
78
|
-
id: "my-model",
|
|
79
|
-
name: "My Model",
|
|
80
|
-
reasoning: false,
|
|
81
|
-
input: ["text", "image"],
|
|
82
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
83
|
-
contextWindow: 128000,
|
|
84
|
-
maxTokens: 4096
|
|
85
|
-
}
|
|
86
|
-
]
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
The extension factory can also be `async`. For dynamic model discovery, fetch and register models in the factory instead of `session_start`. pi waits for the factory before startup continues, so the provider is available during interactive startup and to `pi --list-models`.
|
|
28
|
+
Prefer a complete provider for new integrations that own more than static endpoint and model metadata. Pi composes `models.json` overrides above a registered native provider.
|
|
92
29
|
|
|
93
|
-
|
|
30
|
+
Registering only `baseUrl` or `headers` for an existing provider preserves its built-in models. Supplying `models` in the legacy form replaces that provider's models across chat, image, and classifier operations. An omitted `type` means `"chat"`; image and classifier models require explicit discriminants and implementations keyed by their `api` values through the `images` and `classifiers` fields.
|
|
94
31
|
|
|
95
|
-
|
|
32
|
+
For example, a mixed-operation provider can register non-chat models and their implementations together:
|
|
96
33
|
|
|
97
34
|
```typescript
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
baseUrl: "https://proxy.example.com"
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// Add custom headers to OpenAI requests
|
|
104
|
-
pi.registerProvider("openai", {
|
|
105
|
-
headers: {
|
|
106
|
-
"X-Custom-Header": "value"
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
// Both baseUrl and headers
|
|
111
|
-
pi.registerProvider("google", {
|
|
112
|
-
baseUrl: "https://ai-gateway.corp.com/google",
|
|
113
|
-
headers: {
|
|
114
|
-
"X-Corp-Auth": "$CORP_AUTH_TOKEN" // env var or literal
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
When only `baseUrl` and/or `headers` are provided (no `models`), all existing models for that provider are preserved with the new endpoint.
|
|
120
|
-
|
|
121
|
-
## Register New Provider
|
|
122
|
-
|
|
123
|
-
To add a completely new provider, specify `models` along with the required configuration.
|
|
124
|
-
|
|
125
|
-
If the model list comes from a remote endpoint, use an async extension factory:
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
129
|
-
|
|
130
|
-
export default async function (pi: ExtensionAPI) {
|
|
131
|
-
const response = await fetch("http://localhost:1234/v1/models");
|
|
132
|
-
const payload = (await response.json()) as {
|
|
133
|
-
data: Array<{
|
|
134
|
-
id: string;
|
|
135
|
-
name?: string;
|
|
136
|
-
context_window?: number;
|
|
137
|
-
max_tokens?: number;
|
|
138
|
-
}>;
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
pi.registerProvider("local-openai", {
|
|
142
|
-
baseUrl: "http://localhost:1234/v1",
|
|
143
|
-
apiKey: "$LOCAL_OPENAI_API_KEY",
|
|
144
|
-
api: "openai-completions",
|
|
145
|
-
models: payload.data.map((model) => ({
|
|
146
|
-
id: model.id,
|
|
147
|
-
name: model.name ?? model.id,
|
|
148
|
-
reasoning: false,
|
|
149
|
-
input: ["text"],
|
|
150
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
151
|
-
contextWindow: model.context_window ?? 128000,
|
|
152
|
-
maxTokens: model.max_tokens ?? 4096,
|
|
153
|
-
})),
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
This registers the fetched models before startup finishes.
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
pi.registerProvider("my-llm", {
|
|
162
|
-
baseUrl: "https://api.my-llm.com/v1",
|
|
163
|
-
apiKey: "$MY_LLM_API_KEY", // env var reference
|
|
164
|
-
api: "openai-completions", // which streaming API to use
|
|
35
|
+
pi.registerProvider("media-tools", {
|
|
36
|
+
apiKey: "$MEDIA_TOOLS_API_KEY",
|
|
165
37
|
models: [
|
|
166
38
|
{
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
cacheWrite: 3.75
|
|
176
|
-
},
|
|
177
|
-
contextWindow: 200000,
|
|
178
|
-
maxTokens: 16384
|
|
179
|
-
}
|
|
180
|
-
]
|
|
181
|
-
});
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
When `models` is provided, it **replaces** all existing models for that provider.
|
|
185
|
-
|
|
186
|
-
`apiKey` and custom header values use the same config value syntax as `models.json`: `!command` at the start executes a command for the whole value, `$ENV_VAR` and `${ENV_VAR}` interpolate environment variables, `$$` emits a literal `$`, and `$!` emits a literal `!`.
|
|
187
|
-
|
|
188
|
-
## Unregister Provider
|
|
189
|
-
|
|
190
|
-
Use `pi.unregisterProvider(name)` to remove a provider that was previously registered via `pi.registerProvider(name, ...)`:
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
// Register
|
|
194
|
-
pi.registerProvider("my-llm", {
|
|
195
|
-
baseUrl: "https://api.my-llm.com/v1",
|
|
196
|
-
apiKey: "$MY_LLM_API_KEY",
|
|
197
|
-
api: "openai-completions",
|
|
198
|
-
models: [
|
|
199
|
-
{
|
|
200
|
-
id: "my-llm-large",
|
|
201
|
-
name: "My LLM Large",
|
|
202
|
-
reasoning: true,
|
|
203
|
-
input: ["text", "image"],
|
|
204
|
-
cost: { input: 3.0, output: 15.0, cacheRead: 0.3, cacheWrite: 3.75 },
|
|
205
|
-
contextWindow: 200000,
|
|
206
|
-
maxTokens: 16384
|
|
207
|
-
}
|
|
208
|
-
]
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
// Later, remove it
|
|
212
|
-
pi.unregisterProvider("my-llm");
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
Unregistering removes that provider's dynamic models, API key fallback, OAuth provider registration, and custom stream handler registrations. Any built-in models or provider behavior that were overridden are restored.
|
|
216
|
-
|
|
217
|
-
Calls made after the initial extension load phase are applied immediately, so no `/reload` is required.
|
|
218
|
-
|
|
219
|
-
### API Types
|
|
220
|
-
|
|
221
|
-
The `api` field determines which streaming implementation is used:
|
|
222
|
-
|
|
223
|
-
| API | Use for |
|
|
224
|
-
|-----|---------|
|
|
225
|
-
| `anthropic-messages` | Anthropic Claude API and compatibles |
|
|
226
|
-
| `openai-completions` | OpenAI Chat Completions API and compatibles |
|
|
227
|
-
| `openai-responses` | OpenAI Responses API |
|
|
228
|
-
| `azure-openai-responses` | Azure OpenAI Responses API |
|
|
229
|
-
| `openai-codex-responses` | OpenAI Codex Responses API |
|
|
230
|
-
| `mistral-conversations` | Native Mistral Chat Completions streaming |
|
|
231
|
-
| `google-generative-ai` | Google Generative AI API |
|
|
232
|
-
| `google-vertex` | Google Vertex AI API |
|
|
233
|
-
| `bedrock-converse-stream` | Amazon Bedrock Converse API |
|
|
234
|
-
|
|
235
|
-
Most OpenAI-compatible providers work with `openai-completions`. Use model-level `thinkingLevelMap` for model-specific thinking levels, and `compat` for provider quirks. The `xhigh` and `max` levels are opt-in, require non-null map entries, and may be separated by unsupported holes:
|
|
236
|
-
|
|
237
|
-
```typescript
|
|
238
|
-
models: [{
|
|
239
|
-
id: "custom-model",
|
|
240
|
-
// ...
|
|
241
|
-
reasoning: true,
|
|
242
|
-
thinkingLevelMap: { // map pi levels to provider values; null hides unsupported levels
|
|
243
|
-
minimal: null,
|
|
244
|
-
low: null,
|
|
245
|
-
medium: null,
|
|
246
|
-
high: "default",
|
|
247
|
-
xhigh: null,
|
|
248
|
-
max: "max"
|
|
249
|
-
},
|
|
250
|
-
compat: {
|
|
251
|
-
supportsDeveloperRole: false, // use "system" instead of "developer"
|
|
252
|
-
supportsReasoningEffort: true,
|
|
253
|
-
maxTokensField: "max_tokens", // instead of "max_completion_tokens"
|
|
254
|
-
requiresToolResultName: true, // tool results need name field
|
|
255
|
-
thinkingFormat: "qwen", // top-level enable_thinking: true
|
|
256
|
-
cacheControlFormat: "anthropic" // Anthropic-style cache_control markers
|
|
257
|
-
}
|
|
258
|
-
}]
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
Use `openrouter` for OpenRouter-style `reasoning: { effort }` controls. Use `together` for Together-style `reasoning: { enabled }` controls; with `supportsReasoningEffort`, it also sends `reasoning_effort`. Use `qwen-chat-template` for local Qwen-compatible servers that read `chat_template_kwargs.enable_thinking` and need `preserve_thinking`.
|
|
262
|
-
Use `cacheControlFormat: "anthropic"` for OpenAI-compatible providers that expose Anthropic-style prompt caching via `cache_control` on the system prompt, last tool definition, and last user, assistant, or tool-result text content.
|
|
263
|
-
|
|
264
|
-
For Anthropic-compatible providers using `api: "anthropic-messages"`, set `compat.forceAdaptiveThinking: true` on models or providers whose upstream model requires adaptive thinking (`thinking.type: "adaptive"` plus `output_config.effort`). Built-in adaptive Claude models set this automatically. Set `compat.allowEmptySignature: true` only for providers that emit empty thinking signatures and expect `signature: ""` on replay.
|
|
265
|
-
|
|
266
|
-
> Migration note: Mistral moved from `openai-completions` to `mistral-conversations`.
|
|
267
|
-
> Use `mistral-conversations` for native Mistral models.
|
|
268
|
-
> If you intentionally route Mistral-compatible/custom endpoints through `openai-completions`, set `compat` flags explicitly as needed.
|
|
269
|
-
|
|
270
|
-
### Auth Header
|
|
271
|
-
|
|
272
|
-
If your provider expects `Authorization: Bearer <key>` but doesn't use a standard API, set `authHeader: true`:
|
|
273
|
-
|
|
274
|
-
```typescript
|
|
275
|
-
pi.registerProvider("custom-api", {
|
|
276
|
-
baseUrl: "https://api.example.com",
|
|
277
|
-
apiKey: "$MY_API_KEY",
|
|
278
|
-
authHeader: true, // adds Authorization: Bearer header
|
|
279
|
-
api: "openai-completions",
|
|
280
|
-
models: [...]
|
|
281
|
-
});
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
The key is resolved for each request. An explicit request `Authorization` header takes precedence over the generated value.
|
|
285
|
-
|
|
286
|
-
## OAuth Support
|
|
287
|
-
|
|
288
|
-
Add OAuth/SSO authentication that integrates with `/login`:
|
|
289
|
-
|
|
290
|
-
```typescript
|
|
291
|
-
import type { OAuthCredentials, OAuthLoginCallbacks } from "@earendil-works/pi-ai";
|
|
292
|
-
|
|
293
|
-
pi.registerProvider("corporate-ai", {
|
|
294
|
-
baseUrl: "https://ai.corp.com/v1",
|
|
295
|
-
api: "openai-responses",
|
|
296
|
-
models: [...],
|
|
297
|
-
oauth: {
|
|
298
|
-
name: "Corporate AI (SSO)",
|
|
299
|
-
|
|
300
|
-
async login(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {
|
|
301
|
-
const method = await callbacks.onSelect({
|
|
302
|
-
message: "Select login method:",
|
|
303
|
-
options: [
|
|
304
|
-
{ id: "browser", label: "Browser OAuth" },
|
|
305
|
-
{ id: "device", label: "Device code" }
|
|
306
|
-
]
|
|
307
|
-
});
|
|
308
|
-
if (!method) throw new Error("Login cancelled");
|
|
309
|
-
|
|
310
|
-
let code: string;
|
|
311
|
-
if (method === "device") {
|
|
312
|
-
callbacks.onDeviceCode({
|
|
313
|
-
userCode: "ABCD-1234",
|
|
314
|
-
verificationUri: "https://sso.corp.com/device",
|
|
315
|
-
intervalSeconds: 5,
|
|
316
|
-
expiresInSeconds: 900
|
|
317
|
-
});
|
|
318
|
-
code = await pollDeviceCodeUntilComplete();
|
|
319
|
-
} else {
|
|
320
|
-
callbacks.onAuth({ url: "https://sso.corp.com/authorize?..." });
|
|
321
|
-
code = await callbacks.onPrompt({ message: "Enter SSO code:" });
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// Exchange for tokens (your implementation)
|
|
325
|
-
const tokens = await exchangeCodeForTokens(code);
|
|
326
|
-
|
|
327
|
-
return {
|
|
328
|
-
refresh: tokens.refreshToken,
|
|
329
|
-
access: tokens.accessToken,
|
|
330
|
-
expires: Date.now() + tokens.expiresIn * 1000
|
|
331
|
-
};
|
|
39
|
+
type: "image",
|
|
40
|
+
id: "image-v1",
|
|
41
|
+
name: "Image V1",
|
|
42
|
+
api: "media-images",
|
|
43
|
+
baseUrl: "https://media.example.com/v1",
|
|
44
|
+
input: ["text"],
|
|
45
|
+
output: ["image"],
|
|
46
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
332
47
|
},
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
}
|
|
48
|
+
{
|
|
49
|
+
type: "classifier",
|
|
50
|
+
id: "classifier-v1",
|
|
51
|
+
name: "Classifier V1",
|
|
52
|
+
api: "media-classifier",
|
|
53
|
+
baseUrl: "https://media.example.com/v1",
|
|
54
|
+
input: ["text"],
|
|
55
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
56
|
+
contextWindow: 64000,
|
|
341
57
|
},
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
58
|
+
],
|
|
59
|
+
images: {
|
|
60
|
+
"media-images": { generateImages: async (model, context, options) => result },
|
|
61
|
+
},
|
|
62
|
+
classifiers: {
|
|
63
|
+
"media-classifier": { classify: async (model, context, options) => result },
|
|
64
|
+
},
|
|
347
65
|
});
|
|
348
66
|
```
|
|
349
67
|
|
|
350
|
-
|
|
68
|
+
Model-level `baseUrl` values take precedence over the provider endpoint. If no `models` list is supplied, built-in models of every operation remain registered. Equal model IDs in different operations remain distinct, including their model-specific headers.
|
|
351
69
|
|
|
352
|
-
|
|
70
|
+
Calls made after initial extension loading take effect immediately. Use `pi.unregisterProvider()` to remove the dynamic provider and restore built-in behavior that it replaced.
|
|
353
71
|
|
|
354
|
-
|
|
72
|
+
See the checked [GitLab Duo provider](../examples/extensions/custom-provider-gitlab-duo/) for a complete registration that delegates streaming to built-in API implementations.
|
|
355
73
|
|
|
356
|
-
|
|
357
|
-
interface OAuthLoginCallbacks {
|
|
358
|
-
// Open URL in browser (for OAuth redirects)
|
|
359
|
-
onAuth(params: { url: string }): void;
|
|
360
|
-
|
|
361
|
-
// Show device code (for device authorization flow)
|
|
362
|
-
onDeviceCode(params: {
|
|
363
|
-
userCode: string;
|
|
364
|
-
verificationUri: string;
|
|
365
|
-
intervalSeconds?: number;
|
|
366
|
-
expiresInSeconds?: number;
|
|
367
|
-
}): void;
|
|
368
|
-
|
|
369
|
-
// Show transient progress
|
|
370
|
-
onProgress?(message: string): void;
|
|
371
|
-
|
|
372
|
-
// Prompt user for input (for manual token entry)
|
|
373
|
-
onPrompt(params: { message: string }): Promise<string>;
|
|
374
|
-
|
|
375
|
-
// Show an interactive selector, e.g. to choose browser OAuth vs device code
|
|
376
|
-
onSelect(params: {
|
|
377
|
-
message: string;
|
|
378
|
-
options: { id: string; label: string }[];
|
|
379
|
-
}): Promise<string | undefined>;
|
|
380
|
-
}
|
|
381
|
-
```
|
|
74
|
+
## Provide authentication
|
|
382
75
|
|
|
383
|
-
|
|
76
|
+
Static providers can resolve an API key from a literal, environment interpolation, or a command. These values use the same syntax as `models.json`:
|
|
384
77
|
|
|
385
|
-
|
|
78
|
+
- `$NAME` and `${NAME}` read environment variables.
|
|
79
|
+
- A leading `!command` uses command output.
|
|
80
|
+
- `$$` emits a literal `$`.
|
|
81
|
+
- `$!` emits a literal leading `!`.
|
|
386
82
|
|
|
387
|
-
|
|
388
|
-
interface OAuthCredentials {
|
|
389
|
-
refresh: string; // Refresh token (for refreshToken())
|
|
390
|
-
access: string; // Access token (returned by getApiKey())
|
|
391
|
-
expires: number; // Expiration timestamp in milliseconds
|
|
392
|
-
}
|
|
393
|
-
```
|
|
83
|
+
Use native provider authentication when the integration needs stored credentials, custom resolution, provider-scoped environment, or multiple login methods.
|
|
394
84
|
|
|
395
|
-
|
|
85
|
+
An OAuth provider supplies a display name, login flow, token refresh, and access-token resolution. After registration it appears in `/login`, and Pi stores returned credentials in `~/.pi/agent/auth.json`.
|
|
396
86
|
|
|
397
|
-
|
|
87
|
+
OAuth callbacks are UI-neutral. They can open an authorization URL, show a device code, report progress, request input, or ask the user to choose a login method. Honor cancellation and the supplied abort signal during network requests.
|
|
398
88
|
|
|
399
|
-
|
|
400
|
-
- [anthropic-messages.ts](https://github.com/earendil-works/pi/blob/main/packages/ai/src/api/anthropic-messages.ts) - Anthropic Messages API
|
|
401
|
-
- [mistral-conversations.ts](https://github.com/earendil-works/pi/blob/main/packages/ai/src/api/mistral-conversations.ts) - Mistral Conversations API
|
|
402
|
-
- [openai-completions.ts](https://github.com/earendil-works/pi/blob/main/packages/ai/src/api/openai-completions.ts) - OpenAI Chat Completions
|
|
403
|
-
- [openai-responses.ts](https://github.com/earendil-works/pi/blob/main/packages/ai/src/api/openai-responses.ts) - OpenAI Responses API
|
|
404
|
-
- [google-generative-ai.ts](https://github.com/earendil-works/pi/blob/main/packages/ai/src/api/google-generative-ai.ts) - Google Generative AI
|
|
405
|
-
- [bedrock-converse-stream.ts](https://github.com/earendil-works/pi/blob/main/packages/ai/src/api/bedrock-converse-stream.ts) - AWS Bedrock
|
|
89
|
+
Never write access tokens, refresh tokens, authorization headers, or complete provider responses to ordinary logs.
|
|
406
90
|
|
|
407
|
-
|
|
91
|
+
## Supply and refresh models
|
|
408
92
|
|
|
409
|
-
|
|
93
|
+
Every model needs an ID, display name, input capabilities, and cost metadata. Chat and classifier models also need a context window; chat models need an output limit and reasoning support; image models declare their output modalities. Choose the API implementation at the provider level unless one model requires an override.
|
|
410
94
|
|
|
411
|
-
|
|
412
|
-
import {
|
|
413
|
-
type AssistantMessage,
|
|
414
|
-
type AssistantMessageEventStream,
|
|
415
|
-
type Model,
|
|
416
|
-
type SimpleStreamOptions,
|
|
417
|
-
type TranscriptContext,
|
|
418
|
-
calculateCost,
|
|
419
|
-
collapseSystemMessages,
|
|
420
|
-
createAssistantMessageEventStream,
|
|
421
|
-
getCurrentSystemPrompt,
|
|
422
|
-
getCurrentTools,
|
|
423
|
-
} from "@earendil-works/pi-ai";
|
|
424
|
-
|
|
425
|
-
function streamMyProvider(
|
|
426
|
-
model: Model<any>,
|
|
427
|
-
context: TranscriptContext,
|
|
428
|
-
options?: SimpleStreamOptions
|
|
429
|
-
): AssistantMessageEventStream {
|
|
430
|
-
const stream = createAssistantMessageEventStream();
|
|
431
|
-
const transcript = collapseSystemMessages(context);
|
|
432
|
-
const systemPrompt = getCurrentSystemPrompt(transcript.messages);
|
|
433
|
-
const tools = getCurrentTools(transcript.messages);
|
|
434
|
-
|
|
435
|
-
(async () => {
|
|
436
|
-
// Initialize output message
|
|
437
|
-
const output: AssistantMessage = {
|
|
438
|
-
role: "assistant",
|
|
439
|
-
content: [],
|
|
440
|
-
api: model.api,
|
|
441
|
-
provider: model.provider,
|
|
442
|
-
model: model.id,
|
|
443
|
-
usage: {
|
|
444
|
-
input: 0,
|
|
445
|
-
output: 0,
|
|
446
|
-
cacheRead: 0,
|
|
447
|
-
cacheWrite: 0,
|
|
448
|
-
totalTokens: 0,
|
|
449
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
450
|
-
},
|
|
451
|
-
stopReason: "pending",
|
|
452
|
-
timestamp: Date.now(),
|
|
453
|
-
};
|
|
454
|
-
|
|
455
|
-
try {
|
|
456
|
-
// Push start event
|
|
457
|
-
stream.push({ type: "start", partial: output });
|
|
458
|
-
|
|
459
|
-
// Make API request and process response...
|
|
460
|
-
// Push content events as they arrive and set stopReason from the terminal event.
|
|
461
|
-
if (output.stopReason === "pending") {
|
|
462
|
-
throw new Error("Provider stream ended without a stop reason");
|
|
463
|
-
}
|
|
464
|
-
if (output.stopReason === "error" || output.stopReason === "aborted") {
|
|
465
|
-
throw new Error(output.errorMessage || "An unknown error occurred");
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
// Push done event
|
|
469
|
-
stream.push({
|
|
470
|
-
type: "done",
|
|
471
|
-
reason: output.stopReason,
|
|
472
|
-
message: output
|
|
473
|
-
});
|
|
474
|
-
stream.end();
|
|
475
|
-
} catch (error) {
|
|
476
|
-
output.stopReason = options?.signal?.aborted ? "aborted" : "error";
|
|
477
|
-
output.errorMessage = error instanceof Error ? error.message : String(error);
|
|
478
|
-
stream.push({ type: "error", reason: output.stopReason, error: output });
|
|
479
|
-
stream.end();
|
|
480
|
-
}
|
|
481
|
-
})();
|
|
482
|
-
|
|
483
|
-
return stream;
|
|
484
|
-
}
|
|
485
|
-
```
|
|
95
|
+
Set `promptCache.short` or `promptCache.long` to the provider's best-effort cache lifetime in seconds when Pi should keep an idle prompt cache warm. Leave them unset to disable cache warming for that retention tier.
|
|
486
96
|
|
|
487
|
-
|
|
97
|
+
Compatibility flags describe verified differences in an otherwise supported API. Do not enable them based only on an endpoint claiming compatibility.
|
|
488
98
|
|
|
489
|
-
|
|
99
|
+
Confirm the request fields and response behavior against the actual server.
|
|
490
100
|
|
|
491
|
-
|
|
101
|
+
Use `refreshModels` when the available catalog comes from a live service. Pass `context.signal` to blocking I/O so callers can cancel refreshes.
|
|
492
102
|
|
|
493
|
-
|
|
494
|
-
- `{ type: "text_start", contentIndex, partial }` - Text block started
|
|
495
|
-
- `{ type: "text_delta", contentIndex, delta, partial }` - Text chunk
|
|
496
|
-
- `{ type: "text_end", contentIndex, content, partial }` - Text block ended
|
|
497
|
-
- `{ type: "thinking_start", contentIndex, partial }` - Thinking started
|
|
498
|
-
- `{ type: "thinking_delta", contentIndex, delta, partial }` - Thinking chunk
|
|
499
|
-
- `{ type: "thinking_end", contentIndex, content, partial }` - Thinking ended
|
|
500
|
-
- `{ type: "toolcall_start", contentIndex, partial }` - Tool call started
|
|
501
|
-
- `{ type: "toolcall_delta", contentIndex, delta, partial }` - Tool call JSON chunk
|
|
502
|
-
- `{ type: "toolcall_end", contentIndex, toolCall, partial }` - Tool call ended
|
|
103
|
+
The two registration forms have different refresh contracts:
|
|
503
104
|
|
|
504
|
-
|
|
105
|
+
- A complete `Provider` returns nothing. It calls `context.publish({ update })` to install provider-owned model state, after which its synchronous `getModels()` exposes the latest list.
|
|
106
|
+
- Legacy `ProviderConfig.refreshModels` returns mixed-operation model definitions. Pi replaces that registration’s live models with the returned list and applies any requested persistence.
|
|
505
107
|
|
|
506
|
-
|
|
108
|
+
Publish persisted catalog data only when it should survive across runs. A live service such as llama.cpp can update its in-memory list without persisting it; a remote catalog can retain a snapshot for offline startup.
|
|
507
109
|
|
|
508
|
-
|
|
110
|
+
## Reuse a supported streaming API
|
|
509
111
|
|
|
510
|
-
|
|
112
|
+
Use one of Pi AI’s API implementations whenever the provider protocol matches it.
|
|
511
113
|
|
|
512
|
-
|
|
513
|
-
// Text block
|
|
514
|
-
output.content.push({ type: "text", text: "" });
|
|
515
|
-
stream.push({ type: "text_start", contentIndex: output.content.length - 1, partial: output });
|
|
516
|
-
|
|
517
|
-
// As text arrives
|
|
518
|
-
const block = output.content[contentIndex];
|
|
519
|
-
if (block.type === "text") {
|
|
520
|
-
block.text += delta;
|
|
521
|
-
stream.push({ type: "text_delta", contentIndex, delta, partial: output });
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
// When block completes
|
|
525
|
-
stream.push({ type: "text_end", contentIndex, content: block.text, partial: output });
|
|
526
|
-
```
|
|
527
|
-
|
|
528
|
-
### Tool Calls
|
|
529
|
-
|
|
530
|
-
Tool calls require accumulating JSON and parsing:
|
|
531
|
-
|
|
532
|
-
```typescript
|
|
533
|
-
// Start tool call
|
|
534
|
-
output.content.push({
|
|
535
|
-
type: "toolCall",
|
|
536
|
-
id: toolCallId,
|
|
537
|
-
name: toolName,
|
|
538
|
-
arguments: {}
|
|
539
|
-
});
|
|
540
|
-
stream.push({ type: "toolcall_start", contentIndex: output.content.length - 1, partial: output });
|
|
541
|
-
|
|
542
|
-
// Accumulate JSON
|
|
543
|
-
let partialJson = "";
|
|
544
|
-
partialJson += jsonDelta;
|
|
545
|
-
try {
|
|
546
|
-
block.arguments = JSON.parse(partialJson);
|
|
547
|
-
} catch {}
|
|
548
|
-
stream.push({ type: "toolcall_delta", contentIndex, delta: jsonDelta, partial: output });
|
|
549
|
-
|
|
550
|
-
// Complete
|
|
551
|
-
stream.push({
|
|
552
|
-
type: "toolcall_end",
|
|
553
|
-
contentIndex,
|
|
554
|
-
toolCall: { type: "toolCall", id, name, arguments: block.arguments },
|
|
555
|
-
partial: output
|
|
556
|
-
});
|
|
557
|
-
```
|
|
558
|
-
|
|
559
|
-
### Usage and Cost
|
|
560
|
-
|
|
561
|
-
Update usage from API response and calculate cost:
|
|
562
|
-
|
|
563
|
-
```typescript
|
|
564
|
-
output.usage.input = response.usage.input_tokens;
|
|
565
|
-
output.usage.output = response.usage.output_tokens;
|
|
566
|
-
output.usage.cacheRead = response.usage.cache_read_tokens ?? 0;
|
|
567
|
-
output.usage.cacheWrite = response.usage.cache_write_tokens ?? 0;
|
|
568
|
-
output.usage.totalTokens = output.usage.input + output.usage.output +
|
|
569
|
-
output.usage.cacheRead + output.usage.cacheWrite;
|
|
570
|
-
calculateCost(model, output.usage);
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
### Context Overflow Errors
|
|
114
|
+
Supported implementations cover Anthropic Messages, OpenAI Chat Completions and Responses, Google Generative AI and Vertex, Azure OpenAI Responses, Mistral Conversations, and Bedrock Converse.
|
|
574
115
|
|
|
575
|
-
|
|
116
|
+
The provider can still customize authentication, base URLs, headers, model filtering, and discovery while delegating request conversion and streaming to an existing API implementation.
|
|
576
117
|
|
|
577
|
-
|
|
118
|
+
This is safer than copying a stream implementation because it preserves Pi’s message conversion, tool handling, usage accounting, cancellation, and compatibility behavior.
|
|
578
119
|
|
|
579
|
-
|
|
580
|
-
- `errorMessage` matches one of pi's known overflow patterns (see [`packages/ai/src/utils/overflow.ts`](https://github.com/earendil-works/pi/blob/main/packages/ai/src/utils/overflow.ts))
|
|
120
|
+
## Implement custom streaming
|
|
581
121
|
|
|
582
|
-
|
|
122
|
+
Implement `streamSimple` only when no existing API implementation can represent the service. Study the implementations under [`packages/ai/src/api`](https://github.com/earendil-works/pi/tree/main/packages/ai/src/api) first.
|
|
583
123
|
|
|
584
|
-
|
|
585
|
-
const MY_PROVIDER_OVERFLOW_PATTERN = /your provider's overflow phrase/i;
|
|
586
|
-
|
|
587
|
-
export default function (pi: ExtensionAPI) {
|
|
588
|
-
pi.registerProvider("my-provider", { /* ... */ });
|
|
589
|
-
|
|
590
|
-
pi.on("message_end", (event, ctx) => {
|
|
591
|
-
const message = event.message;
|
|
592
|
-
if (message.role !== "assistant") return;
|
|
593
|
-
if (message.stopReason !== "error") return;
|
|
594
|
-
if (
|
|
595
|
-
message.provider !== "my-provider" &&
|
|
596
|
-
ctx.model?.provider !== "my-provider"
|
|
597
|
-
)
|
|
598
|
-
return;
|
|
599
|
-
|
|
600
|
-
const errorMessage = message.errorMessage ?? "";
|
|
601
|
-
if (errorMessage.includes("context_length_exceeded")) return;
|
|
602
|
-
if (!MY_PROVIDER_OVERFLOW_PATTERN.test(errorMessage)) return;
|
|
603
|
-
|
|
604
|
-
return {
|
|
605
|
-
message: {
|
|
606
|
-
...message,
|
|
607
|
-
errorMessage: `context_length_exceeded: ${errorMessage}`,
|
|
608
|
-
},
|
|
609
|
-
};
|
|
610
|
-
});
|
|
611
|
-
}
|
|
612
|
-
```
|
|
124
|
+
The stream receives a normalized `TranscriptContext`. System prompts and tool declarations live in transcript system messages, so read them with `getCurrentSystemPrompt(context.messages)` and `getCurrentTools(context.messages)` rather than expecting `context.systemPrompt` or `context.tools`. A model that supports mid-conversation system messages can receive them in place; otherwise call `collapseSystemMessages(context)` to fold later system messages into the leading one.
|
|
613
125
|
|
|
614
|
-
|
|
126
|
+
A custom stream must:
|
|
615
127
|
|
|
616
|
-
1.
|
|
617
|
-
2.
|
|
618
|
-
3.
|
|
619
|
-
4.
|
|
128
|
+
1. Create an assistant message with provider, model, timestamp, pending stop reason, content, and zeroed usage.
|
|
129
|
+
2. After request setup succeeds, emit one `start` event before content events.
|
|
130
|
+
3. Update the message while emitting balanced text, thinking, and tool-call events.
|
|
131
|
+
4. Finalize usage, cost, content, and stop reason.
|
|
132
|
+
5. Emit exactly one terminal `done` or `error` event and close the stream.
|
|
133
|
+
6. Convert cancellation into an aborted result.
|
|
620
134
|
|
|
621
|
-
|
|
135
|
+
Request setup can fail before `start`; in that case the stream can terminate directly with `error`. Missing request authentication may also throw synchronously before a stream is returned.
|
|
622
136
|
|
|
623
|
-
|
|
624
|
-
- Match a provider-specific pattern, not pi's generic overflow patterns. Rewriting rate-limit or throttling errors (`rate limit`, `too many requests`) would falsely trigger compaction instead of pi's normal retry-with-backoff path.
|
|
625
|
-
- Skip when `errorMessage` already includes `context_length_exceeded` so the handler is idempotent.
|
|
137
|
+
Content indexes refer to blocks in the assistant message. Update each block before emitting the event whose `partial` field exposes that state. Tool-call arguments must contain valid parsed input by `toolcall_end`.
|
|
626
138
|
|
|
627
|
-
|
|
139
|
+
The stream must also honor request instrumentation supplied through `SimpleStreamOptions`:
|
|
628
140
|
|
|
629
|
-
|
|
141
|
+
- Call `options.onPayload` before sending the provider request and use any replacement payload it returns.
|
|
142
|
+
- Call `options.onResponse` after receiving the response but before consuming its body.
|
|
143
|
+
- Await `options.onProviderStreamEvent?.(providerEvent, model)` for each parsed provider event before normalizing it.
|
|
144
|
+
- Pass through the abort signal and provider-scoped environment.
|
|
630
145
|
|
|
631
|
-
|
|
632
|
-
pi.registerProvider("my-provider", {
|
|
633
|
-
baseUrl: "https://api.example.com",
|
|
634
|
-
apiKey: "$MY_API_KEY",
|
|
635
|
-
api: "my-custom-api",
|
|
636
|
-
models: [...],
|
|
637
|
-
streamSimple: streamMyProvider
|
|
638
|
-
});
|
|
639
|
-
```
|
|
146
|
+
These hooks power extension request inspection, response-header events, and provider-stream observation. Omitting them makes the provider behave differently from Pi’s built-in providers.
|
|
640
147
|
|
|
641
|
-
##
|
|
148
|
+
## Report failures and usage
|
|
642
149
|
|
|
643
|
-
|
|
150
|
+
Set a concrete terminal stop reason. Error and aborted messages need an `errorMessage`; successful messages need accurate input, output, cache, total-token, and cost values.
|
|
644
151
|
|
|
645
|
-
|
|
646
|
-
|------|---------|
|
|
647
|
-
| `stream.test.ts` | Basic streaming, text output |
|
|
648
|
-
| `tokens.test.ts` | Token counting and usage |
|
|
649
|
-
| `abort.test.ts` | AbortSignal handling |
|
|
650
|
-
| `empty.test.ts` | Empty/minimal responses |
|
|
651
|
-
| `context-overflow.test.ts` | Context window limits |
|
|
652
|
-
| `image-limits.test.ts` | Image input handling |
|
|
653
|
-
| `unicode-surrogate.test.ts` | Unicode edge cases |
|
|
654
|
-
| `tool-call-without-result.test.ts` | Tool call edge cases |
|
|
655
|
-
| `image-tool-result.test.ts` | Images in tool results |
|
|
656
|
-
| `total-tokens.test.ts` | Total token calculation |
|
|
657
|
-
| `cross-provider-handoff.test.ts` | Context handoff between providers |
|
|
152
|
+
Pi can compact and retry after recognized context-overflow errors. If the service uses an unknown message, normalize only that provider’s overflow response to `context_length_exceeded` in a guarded `message_end` handler.
|
|
658
153
|
|
|
659
|
-
|
|
154
|
+
Do not rewrite rate limits or transient provider failures as context overflow. Those failures use Pi’s normal retry behavior instead.
|
|
660
155
|
|
|
661
|
-
##
|
|
156
|
+
## Test the integration
|
|
662
157
|
|
|
663
|
-
|
|
664
|
-
interface ProviderConfig {
|
|
665
|
-
/** Display name for the provider in UI such as /login. */
|
|
666
|
-
name?: string;
|
|
667
|
-
|
|
668
|
-
/** API endpoint URL. Required when defining models. */
|
|
669
|
-
baseUrl?: string;
|
|
670
|
-
|
|
671
|
-
/** API key literal, env interpolation ($ENV_VAR or ${ENV_VAR}), or !command. Required when defining models (unless oauth). */
|
|
672
|
-
apiKey?: string;
|
|
673
|
-
|
|
674
|
-
/** API type for streaming. Required at provider or model level when defining models. */
|
|
675
|
-
api?: Api;
|
|
676
|
-
|
|
677
|
-
/** Custom streaming implementation for non-standard APIs. Receives a normalized transcript. */
|
|
678
|
-
streamSimple?: (
|
|
679
|
-
model: Model<Api>,
|
|
680
|
-
context: TranscriptContext,
|
|
681
|
-
options?: SimpleStreamOptions
|
|
682
|
-
) => AssistantMessageEventStream;
|
|
683
|
-
|
|
684
|
-
/** Custom headers to include in requests. Values use the same resolution syntax as apiKey. */
|
|
685
|
-
headers?: Record<string, string>;
|
|
686
|
-
|
|
687
|
-
/** If true, adds Authorization: Bearer header with the resolved API key. */
|
|
688
|
-
authHeader?: boolean;
|
|
689
|
-
|
|
690
|
-
/** Models to register. If provided, replaces all existing models for this provider. */
|
|
691
|
-
models?: ProviderModelConfig[];
|
|
692
|
-
|
|
693
|
-
/** OAuth provider for /login support. */
|
|
694
|
-
oauth?: {
|
|
695
|
-
name: string;
|
|
696
|
-
login(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials>;
|
|
697
|
-
refreshToken(credentials: OAuthCredentials, signal: AbortSignal): Promise<OAuthCredentials>;
|
|
698
|
-
getApiKey(credentials: OAuthCredentials): string;
|
|
699
|
-
};
|
|
700
|
-
}
|
|
701
|
-
```
|
|
158
|
+
Test at least:
|
|
702
159
|
|
|
703
|
-
|
|
160
|
+
- ordinary and empty text responses
|
|
161
|
+
- tool calls and tool results
|
|
162
|
+
- image input and image tool results when supported
|
|
163
|
+
- usage and cost accounting
|
|
164
|
+
- abort behavior
|
|
165
|
+
- context overflow
|
|
166
|
+
- malformed or partial streams
|
|
167
|
+
- Unicode boundaries
|
|
168
|
+
- cross-provider session handoff
|
|
169
|
+
- authentication refresh and cancellation
|
|
704
170
|
|
|
705
|
-
|
|
706
|
-
interface ProviderModelConfig {
|
|
707
|
-
/** Model ID (e.g., "claude-sonnet-4-20250514"). */
|
|
708
|
-
id: string;
|
|
709
|
-
|
|
710
|
-
/** Display name (e.g., "Claude 4 Sonnet"). */
|
|
711
|
-
name: string;
|
|
712
|
-
|
|
713
|
-
/** API type override for this specific model. */
|
|
714
|
-
api?: Api;
|
|
715
|
-
|
|
716
|
-
/** API endpoint URL override for this specific model. */
|
|
717
|
-
baseUrl?: string;
|
|
718
|
-
|
|
719
|
-
/** Whether the model supports extended thinking. */
|
|
720
|
-
reasoning: boolean;
|
|
721
|
-
|
|
722
|
-
/** Maps pi thinking levels to provider/model-specific values; null marks a level unsupported. */
|
|
723
|
-
thinkingLevelMap?: Partial<Record<"off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", string | null>>;
|
|
724
|
-
|
|
725
|
-
/** Supported input types. */
|
|
726
|
-
input: ("text" | "image")[];
|
|
727
|
-
|
|
728
|
-
/** Cost per million tokens (for usage tracking). */
|
|
729
|
-
cost: {
|
|
730
|
-
input: number;
|
|
731
|
-
output: number;
|
|
732
|
-
cacheRead: number;
|
|
733
|
-
cacheWrite: number;
|
|
734
|
-
};
|
|
735
|
-
|
|
736
|
-
/** Best-effort prompt cache lifetime in seconds per retention tier. Unset disables cache warming. */
|
|
737
|
-
promptCache?: { short?: number; long?: number };
|
|
738
|
-
|
|
739
|
-
/** Maximum context window size in tokens. */
|
|
740
|
-
contextWindow: number;
|
|
741
|
-
|
|
742
|
-
/** Maximum output tokens. */
|
|
743
|
-
maxTokens: number;
|
|
744
|
-
|
|
745
|
-
/** Custom headers for this specific model. */
|
|
746
|
-
headers?: Record<string, string>;
|
|
747
|
-
|
|
748
|
-
/** Compatibility settings for the selected API. */
|
|
749
|
-
compat?: {
|
|
750
|
-
// openai-completions
|
|
751
|
-
supportsStore?: boolean;
|
|
752
|
-
supportsDeveloperRole?: boolean;
|
|
753
|
-
supportsReasoningEffort?: boolean;
|
|
754
|
-
supportsUsageInStreaming?: boolean;
|
|
755
|
-
supportsFinishReason?: boolean;
|
|
756
|
-
supportsStrictMode?: boolean;
|
|
757
|
-
supportsOpenAIGrammarTools?: boolean; // openai-completions/openai-responses; false falls back to normal function tools
|
|
758
|
-
maxTokensField?: "max_completion_tokens" | "max_tokens";
|
|
759
|
-
requiresToolResultName?: boolean;
|
|
760
|
-
requiresAssistantAfterToolResult?: boolean;
|
|
761
|
-
requiresThinkingAsText?: boolean;
|
|
762
|
-
requiresReasoningContentOnAssistantMessages?: boolean;
|
|
763
|
-
thinkingFormat?: "openai" | "openrouter" | "deepseek" | "together" | "baseten" | "zai" | "qwen" | "chat-template" | "qwen-chat-template" | "string-thinking" | "ant-ling";
|
|
764
|
-
chatTemplateKwargs?: Record<string, string | number | boolean | null | { "$var": "thinking.enabled" | "thinking.effort" | "thinking.budget"; omitWhenOff?: boolean }>;
|
|
765
|
-
chatTemplateArgs?: Record<string, string | number | boolean | null | { "$var": "thinking.enabled" | "thinking.effort" | "thinking.budget"; omitWhenOff?: boolean }>;
|
|
766
|
-
thinkingTokenBudgetField?: "thinking_token_budget" | "thinking_budget" | "thinking_budget_tokens";
|
|
767
|
-
supportsThinkingTokenBudget?: boolean;
|
|
768
|
-
cacheControlFormat?: "anthropic";
|
|
769
|
-
sessionAffinityFormat?: "openai" | "openai-nosession" | "openrouter";
|
|
770
|
-
sendSessionAffinityHeaders?: boolean;
|
|
771
|
-
|
|
772
|
-
// anthropic-messages
|
|
773
|
-
supportsEagerToolInputStreaming?: boolean;
|
|
774
|
-
supportsLongCacheRetention?: boolean;
|
|
775
|
-
sendSessionAffinityHeaders?: boolean;
|
|
776
|
-
supportsCacheControlOnTools?: boolean;
|
|
777
|
-
forceAdaptiveThinking?: boolean;
|
|
778
|
-
allowEmptySignature?: boolean;
|
|
779
|
-
supportsStrictTools?: boolean;
|
|
780
|
-
};
|
|
781
|
-
}
|
|
782
|
-
```
|
|
171
|
+
The provider tests under [`packages/ai/test`](https://github.com/earendil-works/pi/tree/main/packages/ai/test) define the behavior expected from built-in providers. Adapt the relevant suites rather than relying only on manual prompts.
|
|
783
172
|
|
|
784
|
-
|
|
785
|
-
`thinkingTokenBudgetField` sends a clamped per-level thinking budget as a top-level request field (`thinking_token_budget` on vLLM, `thinking_budget` on Qwen/SGLang, `thinking_budget_tokens` on llama.cpp). `supportsThinkingTokenBudget: true` is an alias for the vLLM field name. Do not combine it with `reasoning_effort` on DashScope Qwen models.
|
|
786
|
-
`cacheControlFormat: "anthropic"` applies Anthropic-style `cache_control` markers to the system prompt, last tool definition, and last user, assistant, or tool-result text content.
|
|
173
|
+
Run the extension directly while developing, then move it to a discovered extension location or distribute it through a [Pi package](packages.md). Use `/reload` after changing a discovered provider extension in an active session.
|