@linxiraos/pi-ai 1.0.4 → 1.0.6
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 +36 -5
- package/dist/types/api-registry.d.ts +30 -0
- package/dist/types/auth/sqlite-credential-store.d.ts +115 -0
- package/dist/types/auth-broker/client.d.ts +100 -0
- package/dist/types/auth-broker/discover.d.ts +39 -0
- package/dist/types/auth-broker/index.d.ts +7 -0
- package/dist/types/auth-broker/refresher.d.ts +25 -0
- package/dist/types/auth-broker/remote-store.d.ts +136 -0
- package/dist/types/auth-broker/server.d.ts +48 -0
- package/dist/types/auth-broker/snapshot-cache.d.ts +17 -0
- package/dist/types/auth-broker/types.d.ts +152 -0
- package/dist/types/auth-broker/wire-schema-resource.d.ts +53 -0
- package/dist/types/auth-broker/wire-schemas.d.ts +5 -0
- package/dist/types/auth-gateway/http.d.ts +56 -0
- package/dist/types/auth-gateway/index.d.ts +3 -0
- package/dist/types/auth-gateway/server.d.ts +36 -0
- package/dist/types/auth-gateway/types.d.ts +127 -0
- package/dist/types/auth-retry.d.ts +150 -0
- package/dist/types/auth-storage.d.ts +1259 -0
- package/dist/types/dialect/anthropic.d.ts +15 -0
- package/dist/types/dialect/catalog.d.ts +3 -0
- package/dist/types/dialect/coercion.d.ts +23 -0
- package/dist/types/dialect/deepseek.d.ts +14 -0
- package/dist/types/dialect/demotion.d.ts +30 -0
- package/dist/types/dialect/examples.d.ts +18 -0
- package/dist/types/dialect/factory.d.ts +3 -0
- package/dist/types/dialect/fenced-thinking.d.ts +53 -0
- package/dist/types/dialect/gemini.d.ts +17 -0
- package/dist/types/dialect/gemma.d.ts +15 -0
- package/dist/types/dialect/glm.d.ts +9 -0
- package/dist/types/dialect/harmony.d.ts +8 -0
- package/dist/types/dialect/hermes.d.ts +9 -0
- package/dist/types/dialect/history.d.ts +3 -0
- package/dist/types/dialect/index.d.ts +11 -0
- package/dist/types/dialect/inventory.d.ts +9 -0
- package/dist/types/dialect/kimi.d.ts +14 -0
- package/dist/types/dialect/minimax.d.ts +3 -0
- package/dist/types/dialect/owned-stream.d.ts +4 -0
- package/dist/types/dialect/qwen3.d.ts +9 -0
- package/dist/types/dialect/rendering.d.ts +54 -0
- package/dist/types/dialect/thinking.d.ts +6 -0
- package/dist/types/dialect/types.d.ts +68 -0
- package/dist/types/dialect/xml.d.ts +9 -0
- package/dist/types/error/abort.d.ts +14 -0
- package/dist/types/error/auth-classify.d.ts +20 -0
- package/dist/types/error/auth.d.ts +27 -0
- package/dist/types/error/aws.d.ts +31 -0
- package/dist/types/error/classes.d.ts +106 -0
- package/dist/types/error/finalize.d.ts +39 -0
- package/dist/types/error/flags.d.ts +99 -0
- package/dist/types/error/format.d.ts +20 -0
- package/dist/types/error/gateway.d.ts +20 -0
- package/dist/types/error/index.d.ts +14 -0
- package/dist/types/error/oauth.d.ts +43 -0
- package/dist/types/error/provider.d.ts +44 -0
- package/dist/types/error/rate-limit.d.ts +83 -0
- package/dist/types/error/retryable.d.ts +27 -0
- package/dist/types/error/validation.d.ts +32 -0
- package/dist/types/index.d.ts +52 -0
- package/dist/types/oneshot-retry.d.ts +89 -0
- package/dist/types/provider-details.d.ts +24 -0
- package/dist/types/providers/amazon-bedrock.d.ts +39 -0
- package/dist/types/providers/anthropic-client.d.ts +106 -0
- package/dist/types/providers/anthropic-messages-server-schema.d.ts +937 -0
- package/dist/types/providers/anthropic-messages-server.d.ts +17 -0
- package/dist/types/providers/anthropic-wire.d.ts +358 -0
- package/dist/types/providers/anthropic.d.ts +258 -0
- package/dist/types/providers/aws-credentials.d.ts +49 -0
- package/dist/types/providers/aws-eventstream.d.ts +39 -0
- package/dist/types/providers/aws-sigv4.d.ts +55 -0
- package/dist/types/providers/azure-openai-responses.d.ts +17 -0
- package/dist/types/providers/bedrock-mantle.d.ts +13 -0
- package/dist/types/providers/claude-code-fingerprint.d.ts +19 -0
- package/dist/types/providers/cowork-fetch.d.ts +3 -0
- package/dist/types/providers/cursor/exec-modern.d.ts +98 -0
- package/dist/types/providers/cursor-pi-args.d.ts +119 -0
- package/dist/types/providers/cursor.d.ts +221 -0
- package/dist/types/providers/devin.d.ts +12 -0
- package/dist/types/providers/error-message.d.ts +25 -0
- package/dist/types/providers/github-copilot-headers.d.ts +40 -0
- package/dist/types/providers/gitlab-duo-workflow.d.ts +254 -0
- package/dist/types/providers/gitlab-duo.d.ts +27 -0
- package/dist/types/providers/google-auth.d.ts +24 -0
- package/dist/types/providers/google-gemini-cli.d.ts +119 -0
- package/dist/types/providers/google-shared.d.ts +203 -0
- package/dist/types/providers/google-types.d.ts +155 -0
- package/dist/types/providers/google-vertex.d.ts +7 -0
- package/dist/types/providers/google.d.ts +4 -0
- package/dist/types/providers/grammar.d.ts +1 -0
- package/dist/types/providers/kimi.d.ts +27 -0
- package/dist/types/providers/mock.d.ts +179 -0
- package/dist/types/providers/ollama.d.ts +8 -0
- package/dist/types/providers/openai-anthropic-shim.d.ts +35 -0
- package/dist/types/providers/openai-chat-server-schema.d.ts +1311 -0
- package/dist/types/providers/openai-chat-server.d.ts +16 -0
- package/dist/types/providers/openai-chat-wire.d.ts +669 -0
- package/dist/types/providers/openai-codex/request-transformer.d.ts +111 -0
- package/dist/types/providers/openai-codex/response-handler.d.ts +26 -0
- package/dist/types/providers/openai-codex-responses.d.ts +238 -0
- package/dist/types/providers/openai-completions.d.ts +48 -0
- package/dist/types/providers/openai-reasoning-fallback.d.ts +25 -0
- package/dist/types/providers/openai-responses-server-schema.d.ts +1314 -0
- package/dist/types/providers/openai-responses-server.d.ts +17 -0
- package/dist/types/providers/openai-responses-wire.d.ts +6099 -0
- package/dist/types/providers/openai-responses.d.ts +132 -0
- package/dist/types/providers/openai-shared.d.ts +642 -0
- package/dist/types/providers/pi-native-client.d.ts +13 -0
- package/dist/types/providers/pi-native-server.d.ts +69 -0
- package/dist/types/providers/register-builtins.d.ts +37 -0
- package/dist/types/providers/synthetic.d.ts +26 -0
- package/dist/types/providers/transform-messages.d.ts +32 -0
- package/dist/types/providers/vision-guard.d.ts +24 -0
- package/dist/types/registry/aiand.d.ts +7 -0
- package/dist/types/registry/aimlapi.d.ts +4 -0
- package/dist/types/registry/alibaba-coding-plan.d.ts +8 -0
- package/dist/types/registry/alibaba-token-plan.d.ts +18 -0
- package/dist/types/registry/amazon-bedrock.d.ts +10 -0
- package/dist/types/registry/anthropic.d.ts +10 -0
- package/dist/types/registry/api-key-login.d.ts +44 -0
- package/dist/types/registry/api-key-validation.d.ts +43 -0
- package/dist/types/registry/aws.d.ts +15 -0
- package/dist/types/registry/azure.d.ts +4 -0
- package/dist/types/registry/baseten.d.ts +7 -0
- package/dist/types/registry/bedrock-mantle.d.ts +22 -0
- package/dist/types/registry/cerebras.d.ts +7 -0
- package/dist/types/registry/cloudflare-ai-gateway.d.ts +13 -0
- package/dist/types/registry/coreweave.d.ts +7 -0
- package/dist/types/registry/cursor.d.ts +7 -0
- package/dist/types/registry/deepseek.d.ts +8 -0
- package/dist/types/registry/derived.d.ts +5 -0
- package/dist/types/registry/devin.d.ts +8 -0
- package/dist/types/registry/exa.d.ts +8 -0
- package/dist/types/registry/firepass.d.ts +16 -0
- package/dist/types/registry/fireworks.d.ts +7 -0
- package/dist/types/registry/github-copilot.d.ts +7 -0
- package/dist/types/registry/gitlab-duo-workflow.d.ts +10 -0
- package/dist/types/registry/gitlab-duo.d.ts +9 -0
- package/dist/types/registry/gmi-cloud.d.ts +7 -0
- package/dist/types/registry/google-antigravity.d.ts +9 -0
- package/dist/types/registry/google-gemini-cli.d.ts +9 -0
- package/dist/types/registry/google-vertex.d.ts +5 -0
- package/dist/types/registry/google.d.ts +4 -0
- package/dist/types/registry/groq.d.ts +4 -0
- package/dist/types/registry/huggingface.d.ts +7 -0
- package/dist/types/registry/index.d.ts +4 -0
- package/dist/types/registry/kagi.d.ts +14 -0
- package/dist/types/registry/kilo.d.ts +7 -0
- package/dist/types/registry/kimi-code.d.ts +7 -0
- package/dist/types/registry/litellm.d.ts +13 -0
- package/dist/types/registry/llama-cpp.d.ts +8 -0
- package/dist/types/registry/lm-studio.d.ts +8 -0
- package/dist/types/registry/meta.d.ts +7 -0
- package/dist/types/registry/minimax-code-cn.d.ts +6 -0
- package/dist/types/registry/minimax-code.d.ts +6 -0
- package/dist/types/registry/minimax.d.ts +4 -0
- package/dist/types/registry/mistral.d.ts +4 -0
- package/dist/types/registry/moonshot.d.ts +7 -0
- package/dist/types/registry/nanogpt.d.ts +7 -0
- package/dist/types/registry/novita.d.ts +6 -0
- package/dist/types/registry/nvidia.d.ts +7 -0
- package/dist/types/registry/oauth/anthropic-constants.d.ts +12 -0
- package/dist/types/registry/oauth/anthropic.d.ts +24 -0
- package/dist/types/registry/oauth/callback-server.d.ts +74 -0
- package/dist/types/registry/oauth/cursor.d.ts +16 -0
- package/dist/types/registry/oauth/device-code.d.ts +25 -0
- package/dist/types/registry/oauth/devin.d.ts +5 -0
- package/dist/types/registry/oauth/github-copilot.d.ts +30 -0
- package/dist/types/registry/oauth/gitlab-duo-workflow.d.ts +6 -0
- package/dist/types/registry/oauth/gitlab-duo.d.ts +3 -0
- package/dist/types/registry/oauth/google-antigravity.d.ts +15 -0
- package/dist/types/registry/oauth/google-gemini-cli.d.ts +22 -0
- package/dist/types/registry/oauth/google-oauth-shared.d.ts +56 -0
- package/dist/types/registry/oauth/index.d.ts +45 -0
- package/dist/types/registry/oauth/kimi.d.ts +21 -0
- package/dist/types/registry/oauth/minimax-code.d.ts +27 -0
- package/dist/types/registry/oauth/openai-codex.d.ts +33 -0
- package/dist/types/registry/oauth/opencode.d.ts +18 -0
- package/dist/types/registry/oauth/perplexity.d.ts +9 -0
- package/dist/types/registry/oauth/pkce.d.ts +8 -0
- package/dist/types/registry/oauth/types.d.ts +87 -0
- package/dist/types/registry/oauth/wafer.d.ts +1 -0
- package/dist/types/registry/oauth/xai-oauth.d.ts +46 -0
- package/dist/types/registry/oauth/xiaomi.d.ts +25 -0
- package/dist/types/registry/oauth/zai.d.ts +25 -0
- package/dist/types/registry/ollama-cloud.d.ts +7 -0
- package/dist/types/registry/ollama.d.ts +12 -0
- package/dist/types/registry/openai-codex-device.d.ts +8 -0
- package/dist/types/registry/openai-codex.d.ts +9 -0
- package/dist/types/registry/openai.d.ts +4 -0
- package/dist/types/registry/opencode-go.d.ts +6 -0
- package/dist/types/registry/opencode-zen.d.ts +6 -0
- package/dist/types/registry/openrouter.d.ts +13 -0
- package/dist/types/registry/parallel.d.ts +14 -0
- package/dist/types/registry/perplexity.d.ts +7 -0
- package/dist/types/registry/qianfan.d.ts +7 -0
- package/dist/types/registry/qwen-portal.d.ts +7 -0
- package/dist/types/registry/registry.d.ts +372 -0
- package/dist/types/registry/sakana.d.ts +7 -0
- package/dist/types/registry/siliconflow-cn.d.ts +7 -0
- package/dist/types/registry/siliconflow.d.ts +7 -0
- package/dist/types/registry/synthetic.d.ts +6 -0
- package/dist/types/registry/tavily.d.ts +14 -0
- package/dist/types/registry/together.d.ts +6 -0
- package/dist/types/registry/types.d.ts +75 -0
- package/dist/types/registry/umans.d.ts +7 -0
- package/dist/types/registry/venice.d.ts +13 -0
- package/dist/types/registry/vercel-ai-gateway.d.ts +7 -0
- package/dist/types/registry/vllm.d.ts +7 -0
- package/dist/types/registry/wafer-serverless.d.ts +6 -0
- package/dist/types/registry/xai-oauth.d.ts +7 -0
- package/dist/types/registry/xai.d.ts +7 -0
- package/dist/types/registry/xiaomi-token-plan-ams.d.ts +6 -0
- package/dist/types/registry/xiaomi-token-plan-cn.d.ts +6 -0
- package/dist/types/registry/xiaomi-token-plan-sgp.d.ts +6 -0
- package/dist/types/registry/xiaomi.d.ts +6 -0
- package/dist/types/registry/zai.d.ts +15 -0
- package/dist/types/registry/zenmux.d.ts +7 -0
- package/dist/types/registry/zhipu-coding-plan.d.ts +7 -0
- package/dist/types/stream.d.ts +53 -0
- package/dist/types/types.d.ts +1088 -0
- package/dist/types/usage/alibaba-token-plan.d.ts +3 -0
- package/dist/types/usage/claude.d.ts +4 -0
- package/dist/types/usage/cursor.d.ts +15 -0
- package/dist/types/usage/gemini.d.ts +2 -0
- package/dist/types/usage/github-copilot.d.ts +7 -0
- package/dist/types/usage/google-antigravity.d.ts +15 -0
- package/dist/types/usage/kimi.d.ts +4 -0
- package/dist/types/usage/minimax-code.d.ts +3 -0
- package/dist/types/usage/ollama.d.ts +5 -0
- package/dist/types/usage/openai-codex-base-url.d.ts +18 -0
- package/dist/types/usage/openai-codex-reset.d.ts +68 -0
- package/dist/types/usage/openai-codex.d.ts +10 -0
- package/dist/types/usage/opencode-go.d.ts +13 -0
- package/dist/types/usage/shared.d.ts +13 -0
- package/dist/types/usage/synthetic.d.ts +2 -0
- package/dist/types/usage/umans.d.ts +2 -0
- package/dist/types/usage/xai-oauth.d.ts +12 -0
- package/dist/types/usage/zai.d.ts +3 -0
- package/dist/types/usage.d.ts +508 -0
- package/dist/types/utils/abort.d.ts +25 -0
- package/dist/types/utils/anthropic-auth.d.ts +35 -0
- package/dist/types/utils/aws-profile.d.ts +17 -0
- package/dist/types/utils/block-symbols.d.ts +74 -0
- package/dist/types/utils/deterministic-id.d.ts +16 -0
- package/dist/types/utils/empty-completion-retry.d.ts +22 -0
- package/dist/types/utils/event-stream.d.ts +39 -0
- package/dist/types/utils/foundry.d.ts +1 -0
- package/dist/types/utils/google-validation.d.ts +2 -0
- package/dist/types/utils/harmony-leak.d.ts +135 -0
- package/dist/types/utils/http-inspector.d.ts +49 -0
- package/dist/types/utils/idle-iterator.d.ts +149 -0
- package/dist/types/utils/leaked-thinking-stream.d.ts +33 -0
- package/dist/types/utils/openai-http.d.ts +48 -0
- package/dist/types/utils/openrouter-headers.d.ts +1 -0
- package/dist/types/utils/parse-bind.d.ts +23 -0
- package/dist/types/utils/provider-response.d.ts +3 -0
- package/dist/types/utils/proxy.d.ts +39 -0
- package/dist/types/utils/request-debug.d.ts +29 -0
- package/dist/types/utils/retry-after.d.ts +4 -0
- package/dist/types/utils/retry.d.ts +14 -0
- package/dist/types/utils/schema/adapt.d.ts +24 -0
- package/dist/types/utils/schema/compatibility.d.ts +30 -0
- package/dist/types/utils/schema/dereference.d.ts +11 -0
- package/dist/types/utils/schema/draft.d.ts +10 -0
- package/dist/types/utils/schema/equality.d.ts +4 -0
- package/dist/types/utils/schema/fields.d.ts +54 -0
- package/dist/types/utils/schema/index.d.ts +14 -0
- package/dist/types/utils/schema/json-schema-validator.d.ts +20 -0
- package/dist/types/utils/schema/meta-validator.d.ts +2 -0
- package/dist/types/utils/schema/normalize.d.ts +153 -0
- package/dist/types/utils/schema/spill.d.ts +8 -0
- package/dist/types/utils/schema/stamps.d.ts +17 -0
- package/dist/types/utils/schema/strict-tool-validation.d.ts +25 -0
- package/dist/types/utils/schema/types.d.ts +4 -0
- package/dist/types/utils/schema/typescript.d.ts +24 -0
- package/dist/types/utils/schema/wire.d.ts +58 -0
- package/dist/types/utils/sdk-stream-timeout.d.ts +33 -0
- package/dist/types/utils/sse-debug.d.ts +5 -0
- package/dist/types/utils/stream-markup-healing.d.ts +87 -0
- package/dist/types/utils/thinking-loop.d.ts +94 -0
- package/dist/types/utils/tool-call-loop-guard.d.ts +26 -0
- package/dist/types/utils/tool-choice.d.ts +52 -0
- package/dist/types/utils/validation.d.ts +28 -0
- package/dist/types/utils.d.ts +57 -0
- package/package.json +138 -137
- package/src/auth-broker/client.ts +24 -7
- package/src/auth-broker/remote-store.ts +48 -3
- package/src/auth-broker/server.ts +1 -1
- package/src/auth-storage.ts +182 -52
- package/src/error/flags.ts +6 -2
- package/src/error/rate-limit.ts +31 -2
- package/src/index.ts +1 -0
- package/src/oneshot-retry.ts +230 -0
- package/src/providers/anthropic-messages-server.ts +5 -5
- package/src/providers/anthropic-wire.ts +31 -5
- package/src/providers/anthropic.ts +15 -4
- package/src/providers/cursor.ts +44 -4
- package/src/providers/openai-completions.ts +107 -63
- package/src/providers/openai-responses.ts +13 -10
- package/src/providers/openai-shared.ts +5 -3
- package/src/registry/alibaba-coding-plan.ts +2 -2
- package/src/registry/alibaba-token-plan.ts +6 -2
- package/src/registry/oauth/github-copilot.ts +1 -22
- package/src/registry/oauth/kimi.ts +20 -0
- package/src/stream.ts +59 -57
- package/src/types.ts +5 -4
- package/src/usage/alibaba-token-plan.ts +89 -34
- package/src/usage/kimi.ts +15 -0
- package/src/usage/umans.ts +93 -20
- package/src/utils/leaked-thinking-stream.ts +2 -2
- package/src/utils/schema/strict-tool-validation.ts +39 -5
- package/src/utils/schema/wire.ts +31 -0
- package/src/utils/thinking-loop.ts +96 -63
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
-
## [1.0.
|
|
5
|
+
## [1.0.6] - 2026-08-17
|
|
6
|
+
|
|
7
|
+
## [17.3.5] - 2026-08-16
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Added retryable oneshot completion support (`retryTransientCompletion`) so non-agent LLM calls correctly retry on transient provider failures (Anthropic overload/rate-limit errors, HTTP 429/500/502/503/529), honoring provider-supplied retry-after timing before giving up.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Fixed xAI availability detection so paid-key-only setups correctly default to `xai/grok-4.5` instead of the free SuperGrok catalog; explicit `xai-oauth/…` selectors still work as before.
|
|
16
|
+
- Fixed xAI Responses requests sending unsupported parameters (reasoning summary, presence/frequency penalties) that some models rejected.
|
|
17
|
+
- Fixed Umans usage reporting incorrectly marking quota as exhausted based on raw request counts instead of actual weighted usage, and improved the usage display to show both a soft-cap warning and a hard exhaustion limit with an accurate countdown to reset.
|
|
18
|
+
- Fixed `omp usage invalidate` to fully clear stale usage data and force a fresh refresh, so upgraded subscriptions no longer show outdated quota information.
|
|
19
|
+
- Improved session recovery to correctly treat certain Cursor HTTP/2 connection errors as transient instead of ending the session.
|
|
20
|
+
- Fixed OpenAI-compatible streams (e.g. DeepSeek) that are cut off mid-generation being silently treated as a completed response instead of being retried.
|
|
21
|
+
- Fixed DeepSeek resource-exhaustion interruptions not being automatically retried.
|
|
22
|
+
- Fixed tool-call IDs being lost during same-model replay, which could break correlation with custom gateways.
|
|
23
|
+
- Fixed Kimi Code multi-account routing to prefer accounts with more available quota, respect usage-limit cooldowns, and keep consistent usage history across token refreshes.
|
|
24
|
+
- Fixed Anthropic custom signing-proxy conversations losing tool-search results and thinking content during replay.
|
|
25
|
+
- Fixed rare runaway response loops across model providers so they now fail gracefully instead of repeating indefinitely.
|
|
26
|
+
- Fixed xAI rejecting entire turns due to certain MCP tool schema shapes, restoring compatibility while isolating any remaining incompatible tools rather than failing the whole request.
|
|
27
|
+
- Fixed Alibaba DashScope/Bailian transient per-minute rate limits being misclassified as full quota exhaustion, causing unnecessary long backoffs instead of quick retries.
|
|
28
|
+
- Fixed Anthropic-compatible streams dropping thinking content, which broke replay of prior reasoning.
|
|
29
|
+
- Updated the Alibaba Coding Plan China login flow to point to the current Bailian API-key management console.
|
|
30
|
+
|
|
31
|
+
## [17.3.4] - 2026-08-14
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- Fixed `omp usage invalidate` to discard stale OAuth and API-key usage snapshots, then force a cache-bypassing, per-provider serialized refresh with a broker request budget sized for the full unfiltered account batch, so upgraded subscriptions do not silently retain pre-change quota data.
|
|
36
|
+
- Fixed quota reporting and Cookie capture guidance for China (Beijing) Alibaba Token Plan credentials ([#8509](https://github.com/can1357/oh-my-pi/issues/8509)).
|
|
6
37
|
|
|
7
38
|
## [17.3.3] - 2026-08-14
|
|
8
39
|
|
|
@@ -4708,7 +4739,7 @@
|
|
|
4708
4739
|
|
|
4709
4740
|
### Changed
|
|
4710
4741
|
|
|
4711
|
-
- Forked to @
|
|
4742
|
+
- Forked to @linxiraos scope with unified versioning across all packages
|
|
4712
4743
|
|
|
4713
4744
|
### Fixed
|
|
4714
4745
|
|
|
@@ -4716,17 +4747,17 @@
|
|
|
4716
4747
|
|
|
4717
4748
|
## [1.337.0] - 2026-01-02
|
|
4718
4749
|
|
|
4719
|
-
Initial release under @
|
|
4750
|
+
Initial release under @linxiraos scope. See previous releases at [badlogic/pi-mono](https://github.com/badlogic/pi-mono).
|
|
4720
4751
|
|
|
4721
4752
|
## [1.0.1] - 2026-08-14
|
|
4722
4753
|
|
|
4723
|
-
- Reset the version to 1.0.0 and republished under the `@linxiraos/*` scope, breaking from the `@
|
|
4754
|
+
- Reset the version to 1.0.0 and republished under the `@linxiraos/*` scope, breaking from the `@linxiraos` version lineage.
|
|
4724
4755
|
|
|
4725
4756
|
## [1.0.0] - 2026-08-13
|
|
4726
4757
|
|
|
4727
4758
|
### Changed
|
|
4728
4759
|
|
|
4729
|
-
- Reset the version to 1.0.0 and republished under the `@linxiraos/*` scope, breaking from the `@
|
|
4760
|
+
- Reset the version to 1.0.0 and republished under the `@linxiraos/*` scope, breaking from the `@linxiraos` version lineage.
|
|
4730
4761
|
|
|
4731
4762
|
## [0.50.1] - 2026-01-26
|
|
4732
4763
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom API provider registry.
|
|
3
|
+
*
|
|
4
|
+
* Allows extensions to register streaming functions for custom API types
|
|
5
|
+
* (e.g., "vertex-claude-api") that are not built into stream.ts.
|
|
6
|
+
*/
|
|
7
|
+
import type { Api, AssistantMessageEventStream, Context, Model, SimpleStreamOptions, StreamOptions } from "./types.js";
|
|
8
|
+
export type CustomStreamFn = (model: Model<Api>, context: Context, options?: StreamOptions) => AssistantMessageEventStream;
|
|
9
|
+
export type CustomStreamSimpleFn = (model: Model<Api>, context: Context, options?: SimpleStreamOptions) => AssistantMessageEventStream;
|
|
10
|
+
export interface RegisteredCustomApi {
|
|
11
|
+
stream: CustomStreamFn;
|
|
12
|
+
streamSimple: CustomStreamSimpleFn;
|
|
13
|
+
sourceId?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Register a custom API streaming function.
|
|
17
|
+
*/
|
|
18
|
+
export declare function registerCustomApi(api: string, streamSimple: CustomStreamSimpleFn, sourceId?: string, stream?: CustomStreamFn): void;
|
|
19
|
+
/**
|
|
20
|
+
* Get a custom API provider by API identifier.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getCustomApi(api: string): RegisteredCustomApi | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Remove all custom APIs registered by a specific source (e.g., extension path).
|
|
25
|
+
*/
|
|
26
|
+
export declare function unregisterCustomApis(sourceId: string): void;
|
|
27
|
+
/**
|
|
28
|
+
* Clear all custom API registrations.
|
|
29
|
+
*/
|
|
30
|
+
export declare function clearCustomApis(): void;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite-backed credential persistence for AuthStorage.
|
|
3
|
+
*
|
|
4
|
+
* The public AuthCredentialStore interface remains in ../auth-storage so local
|
|
5
|
+
* and remote stores share the same contract.
|
|
6
|
+
*/
|
|
7
|
+
import { Database } from "bun:sqlite";
|
|
8
|
+
import type { AuthCredential, AuthCredentialStore, CredentialRefreshLeaseFence, DisabledCredentialSummary, StoredAuthCredential, StoredCredentialBlock } from "../auth-storage.js";
|
|
9
|
+
import type { OAuthCredentials } from "../registry/oauth/types.js";
|
|
10
|
+
import type { ClientUsageReport, ClientUsageSummary, UsageHistoryEntry, UsageHistoryQuery } from "../usage.js";
|
|
11
|
+
export declare const USAGE_REPORT_TTL_MS: number;
|
|
12
|
+
type SerializedCredentialRecord = {
|
|
13
|
+
credentialType: AuthCredential["type"];
|
|
14
|
+
data: string;
|
|
15
|
+
identityKey: string | null;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* SQLite's busy result code family — base `SQLITE_BUSY` plus the extended
|
|
19
|
+
* variants `SQLITE_BUSY_RECOVERY` (concurrent WAL recovery), `SQLITE_BUSY_SNAPSHOT`,
|
|
20
|
+
* and `SQLITE_BUSY_TIMEOUT`. All warrant the same backoff-and-retry treatment.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isSqliteBusyError(err: unknown): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* SQLite's unrecoverable-corruption result codes — the `SQLITE_CORRUPT` family
|
|
25
|
+
* (base plus extended variants like `SQLITE_CORRUPT_VTAB` / `SQLITE_CORRUPT_INDEX`)
|
|
26
|
+
* and `SQLITE_NOTADB` (the file header is not a database). Unlike
|
|
27
|
+
* {@link isSqliteBusyError}, these never clear by retrying: the store must be
|
|
28
|
+
* repaired or replaced, so callers latch and stop touching it.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isSqliteCorruptionError(err: unknown): boolean;
|
|
31
|
+
export declare function serializeCredential(provider: string, credential: AuthCredential): SerializedCredentialRecord | null;
|
|
32
|
+
export declare function resolveCredentialIdentityKey(provider: string, credential: AuthCredential): string | null;
|
|
33
|
+
/**
|
|
34
|
+
* Default SQLite-backed implementation of {@link AuthCredentialStore}.
|
|
35
|
+
*
|
|
36
|
+
* Used by the pi-ai CLI and as the default store for `AuthStorage.create()`.
|
|
37
|
+
* Also exposes convenience methods (`saveOAuth`, `getOAuth`, `saveApiKey`,
|
|
38
|
+
* `getApiKey`, `listProviders`, `deleteProvider`) that callers can use directly
|
|
39
|
+
* without going through `AuthStorage`.
|
|
40
|
+
*/
|
|
41
|
+
export declare class SqliteAuthCredentialStore implements AuthCredentialStore {
|
|
42
|
+
#private;
|
|
43
|
+
constructor(db: Database);
|
|
44
|
+
static open(dbPath?: string): Promise<SqliteAuthCredentialStore>;
|
|
45
|
+
listAuthCredentials(provider?: string): StoredAuthCredential[];
|
|
46
|
+
listDisabledCredentials(provider?: string): Promise<DisabledCredentialSummary[]>;
|
|
47
|
+
replaceAuthCredentialsForProvider(provider: string, credentials: AuthCredential[]): StoredAuthCredential[];
|
|
48
|
+
upsertAuthCredentialForProvider(provider: string, credential: AuthCredential): StoredAuthCredential[];
|
|
49
|
+
updateAuthCredential(id: number, credential: AuthCredential): void;
|
|
50
|
+
tryUpdateAuthCredentialIfMatches(id: number, expectedData: string, credential: AuthCredential, lease?: CredentialRefreshLeaseFence): boolean;
|
|
51
|
+
deleteAuthCredential(id: number, disabledCause: string): void;
|
|
52
|
+
/**
|
|
53
|
+
* CAS-style disable: only soft-deletes the row when its `data` column still
|
|
54
|
+
* matches `expectedData` and the row has not already been disabled. Used by
|
|
55
|
+
* the OAuth refresh-failure path to avoid clobbering a peer that rotated the
|
|
56
|
+
* row between our pre-check and the disable.
|
|
57
|
+
*/
|
|
58
|
+
tryDisableAuthCredentialIfMatches(id: number, expectedData: string, disabledCause: string, lease?: CredentialRefreshLeaseFence): boolean;
|
|
59
|
+
deleteAuthCredentialsForProvider(provider: string, disabledCause: string): void;
|
|
60
|
+
getCache(key: string, options?: {
|
|
61
|
+
includeExpired?: boolean;
|
|
62
|
+
}): string | null;
|
|
63
|
+
setCache(key: string, value: string, expiresAtSec: number): void;
|
|
64
|
+
/** Drop all cache rows whose keys start with the supplied prefix. */
|
|
65
|
+
deleteCachePrefix(prefix: string): void;
|
|
66
|
+
cleanExpiredCache(): void;
|
|
67
|
+
getCredentialBlock(credentialId: number, providerKey: string, blockScope: string): number | undefined;
|
|
68
|
+
getCredentialBlockReconcileAfter(credentialId: number, providerKey: string, blockScope: string): number | undefined;
|
|
69
|
+
upsertCredentialBlock(block: StoredCredentialBlock): void;
|
|
70
|
+
deleteCredentialBlock(credentialId: number, providerKey: string, blockScope: string): void;
|
|
71
|
+
deleteCredentialBlocks(credentialId: number): void;
|
|
72
|
+
cleanExpiredCredentialBlocks(nowMs: number): void;
|
|
73
|
+
listCredentialBlocks(credentialIds: readonly number[]): StoredCredentialBlock[];
|
|
74
|
+
tryAcquireCredentialRefreshLease(credentialId: number, owner: string, expiresAtMs: number): boolean;
|
|
75
|
+
getCredentialRefreshLeaseExpiresAt(credentialId: number): number | undefined;
|
|
76
|
+
renewCredentialRefreshLease(credentialId: number, owner: string, expiresAtMs: number): boolean;
|
|
77
|
+
releaseCredentialRefreshLease(credentialId: number, owner: string): void;
|
|
78
|
+
recordUsageSnapshots(entries: UsageHistoryEntry[]): void;
|
|
79
|
+
listUsageHistory(query?: UsageHistoryQuery): UsageHistoryEntry[];
|
|
80
|
+
recordClientUsage(report: ClientUsageReport): void;
|
|
81
|
+
getClientUsageSummary(sinceMs: number): ClientUsageSummary;
|
|
82
|
+
/**
|
|
83
|
+
* Save OAuth credentials for a provider.
|
|
84
|
+
* Preserves unrelated identities and replaces only the matching credential.
|
|
85
|
+
*/
|
|
86
|
+
saveOAuth(provider: string, credentials: OAuthCredentials): void;
|
|
87
|
+
/**
|
|
88
|
+
* Get OAuth credentials for a provider.
|
|
89
|
+
*/
|
|
90
|
+
getOAuth(provider: string): OAuthCredentials | null;
|
|
91
|
+
/**
|
|
92
|
+
* Save API key for a provider (replaces existing).
|
|
93
|
+
*/
|
|
94
|
+
saveApiKey(provider: string, apiKey: string): void;
|
|
95
|
+
/**
|
|
96
|
+
* Get API key for a provider.
|
|
97
|
+
*/
|
|
98
|
+
getApiKey(provider: string): string | null;
|
|
99
|
+
/**
|
|
100
|
+
* List all providers with credentials.
|
|
101
|
+
*/
|
|
102
|
+
listProviders(): string[];
|
|
103
|
+
/**
|
|
104
|
+
* Delete all credentials for a provider.
|
|
105
|
+
*/
|
|
106
|
+
deleteProvider(provider: string): void;
|
|
107
|
+
/**
|
|
108
|
+
* SQLite increments `data_version` when another connection commits. Own
|
|
109
|
+
* writes leave it unchanged and already notify AuthStorage directly.
|
|
110
|
+
*/
|
|
111
|
+
pollExternalChanges(): boolean;
|
|
112
|
+
acknowledgeLocalChanges(): void;
|
|
113
|
+
close(): void;
|
|
114
|
+
}
|
|
115
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for the omp auth-broker server.
|
|
3
|
+
*
|
|
4
|
+
* Used by {@link RemoteAuthCredentialStore} (snapshot pulls) and by
|
|
5
|
+
* `omp auth-broker status` (liveness checks). All endpoints except
|
|
6
|
+
* `/v1/healthz` require a bearer token.
|
|
7
|
+
*/
|
|
8
|
+
import type { AuthCredential, DisabledCredentialSummary } from "../auth-storage.js";
|
|
9
|
+
import type { ClientUsageReportRequest, ClientUsageReportResponse, ClientUsageSummaryResponse, CredentialBlockRequest, CredentialBlockResponse, CredentialBlocksDeleteResponse, CredentialDisableResponse, CredentialRefreshResponse, CredentialUploadResponse, HealthzResponse, SnapshotResponse, SnapshotStreamEvent, UsageHistoryResponse, UsageResponse, UsageStaleResponse } from "./types.js";
|
|
10
|
+
export interface AuthBrokerClientOptions {
|
|
11
|
+
/** Base URL (e.g. `https://broker.tailnet:8765`). Trailing slashes are trimmed. */
|
|
12
|
+
url: string;
|
|
13
|
+
/** Bearer token used for everything except `healthz`. */
|
|
14
|
+
token: string;
|
|
15
|
+
/** Per-request timeout in milliseconds. Default 10s. */
|
|
16
|
+
timeoutMs?: number;
|
|
17
|
+
/** Retry connection errors this many times. Default 1. */
|
|
18
|
+
maxRetries?: number;
|
|
19
|
+
/** Override fetch (used in tests). Default global `fetch`. */
|
|
20
|
+
fetchImpl?: typeof fetch;
|
|
21
|
+
}
|
|
22
|
+
export declare class AuthBrokerError extends Error {
|
|
23
|
+
readonly status: number | undefined;
|
|
24
|
+
readonly body: string | undefined;
|
|
25
|
+
constructor(message: string, opts?: {
|
|
26
|
+
status?: number;
|
|
27
|
+
body?: string;
|
|
28
|
+
cause?: unknown;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Thrown when a broker responds 404 to `GET /v1/snapshot/stream` — old
|
|
33
|
+
* brokers that predate the SSE endpoint. Callers (`RemoteAuthCredentialStore`)
|
|
34
|
+
* detect this sentinel to fall back to long-polling permanently.
|
|
35
|
+
*/
|
|
36
|
+
export declare class AuthBrokerStreamUnsupportedError extends AuthBrokerError {
|
|
37
|
+
constructor(message?: string);
|
|
38
|
+
}
|
|
39
|
+
export interface FetchSnapshotOptions {
|
|
40
|
+
ifGenerationGt?: number;
|
|
41
|
+
waitMs?: number;
|
|
42
|
+
signal?: AbortSignal;
|
|
43
|
+
}
|
|
44
|
+
export type FetchSnapshotResult = {
|
|
45
|
+
status: 200;
|
|
46
|
+
snapshot: SnapshotResponse;
|
|
47
|
+
generation: number;
|
|
48
|
+
} | {
|
|
49
|
+
status: 304;
|
|
50
|
+
generation: number;
|
|
51
|
+
};
|
|
52
|
+
export declare class AuthBrokerClient {
|
|
53
|
+
#private;
|
|
54
|
+
constructor(opts: AuthBrokerClientOptions);
|
|
55
|
+
healthz(signal?: AbortSignal): Promise<HealthzResponse>;
|
|
56
|
+
fetchSnapshot(opts?: FetchSnapshotOptions): Promise<FetchSnapshotResult>;
|
|
57
|
+
/**
|
|
58
|
+
* Subscribe to the broker's SSE snapshot stream. The first frame is always
|
|
59
|
+
* a full `snapshot`; subsequent frames are `entry` upserts / refreshes or
|
|
60
|
+
* `removed` deletes. Caller controls lifecycle via `opts.signal`.
|
|
61
|
+
*
|
|
62
|
+
* Throws {@link AuthBrokerStreamUnsupportedError} when the broker responds
|
|
63
|
+
* 404 — older brokers predate this endpoint and the caller should fall back
|
|
64
|
+
* to long-polling for the remainder of its lifetime.
|
|
65
|
+
*/
|
|
66
|
+
openSnapshotStream(opts?: {
|
|
67
|
+
signal?: AbortSignal;
|
|
68
|
+
}): AsyncGenerator<SnapshotStreamEvent>;
|
|
69
|
+
/**
|
|
70
|
+
* Fetch aggregate broker usage with a timeout sized for serialized
|
|
71
|
+
* same-provider account probes.
|
|
72
|
+
*/
|
|
73
|
+
fetchUsage(options?: {
|
|
74
|
+
signal?: AbortSignal;
|
|
75
|
+
maxAccountsPerProvider?: number;
|
|
76
|
+
}): Promise<UsageResponse>;
|
|
77
|
+
/** Recorded usage-limit snapshots from the broker host, oldest first. */
|
|
78
|
+
fetchUsageHistory(query?: {
|
|
79
|
+
sinceMs?: number;
|
|
80
|
+
provider?: string;
|
|
81
|
+
}, signal?: AbortSignal): Promise<UsageHistoryResponse>;
|
|
82
|
+
/** Report this client's batched observed request usage for per-install burn tracking. */
|
|
83
|
+
reportClientUsage(report: ClientUsageReportRequest, signal?: AbortSignal): Promise<ClientUsageReportResponse>;
|
|
84
|
+
/** Per-client token burn aggregates recorded by the broker host. */
|
|
85
|
+
fetchClientUsageSummary(query?: {
|
|
86
|
+
sinceMs?: number;
|
|
87
|
+
}, signal?: AbortSignal): Promise<ClientUsageSummaryResponse>;
|
|
88
|
+
notifyUsageStale(signal?: AbortSignal): Promise<UsageStaleResponse>;
|
|
89
|
+
refreshCredential(id: number, signal?: AbortSignal): Promise<CredentialRefreshResponse>;
|
|
90
|
+
disableCredential(id: number, cause: string, signal?: AbortSignal): Promise<CredentialDisableResponse>;
|
|
91
|
+
/**
|
|
92
|
+
* Disabled-credential tombstones (identity + cause, no token material).
|
|
93
|
+
* Returns an empty list against brokers predating `GET
|
|
94
|
+
* /v1/credentials/disabled` (404).
|
|
95
|
+
*/
|
|
96
|
+
listDisabledCredentials(provider?: string, signal?: AbortSignal): Promise<DisabledCredentialSummary[]>;
|
|
97
|
+
uploadCredential(provider: string, credential: AuthCredential, signal?: AbortSignal): Promise<CredentialUploadResponse>;
|
|
98
|
+
upsertCredentialBlock(id: number, block: CredentialBlockRequest, signal?: AbortSignal): Promise<CredentialBlockResponse>;
|
|
99
|
+
deleteCredentialBlocks(id: number, signal?: AbortSignal): Promise<CredentialBlocksDeleteResponse>;
|
|
100
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { AuthStorage } from "../auth-storage.js";
|
|
2
|
+
import { type AuthBrokerAccountPool } from "./remote-store.js";
|
|
3
|
+
export interface AuthBrokerClientConfig {
|
|
4
|
+
url: string;
|
|
5
|
+
token: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ResolveAuthBrokerConfigOptions {
|
|
8
|
+
agentDir?: string;
|
|
9
|
+
configValueResolver?: (config: string) => Promise<string | undefined>;
|
|
10
|
+
}
|
|
11
|
+
export interface DiscoverAuthStorageOptions {
|
|
12
|
+
agentDir?: string;
|
|
13
|
+
configValueResolver?: (config: string) => Promise<string | undefined>;
|
|
14
|
+
cachePath?: string;
|
|
15
|
+
sourceLabel?: string;
|
|
16
|
+
/** Programmatic pool for SDK hosts. Takes precedence over the environment file. */
|
|
17
|
+
accountPool?: AuthBrokerAccountPool;
|
|
18
|
+
}
|
|
19
|
+
/** Path to the local bearer token file. Created by `omp auth-broker token`. */
|
|
20
|
+
export declare function getAuthBrokerTokenFilePath(): string;
|
|
21
|
+
export declare function loadAuthBrokerAccountPool(): Promise<AuthBrokerAccountPool | undefined>;
|
|
22
|
+
/**
|
|
23
|
+
* Resolve broker connection configuration using the same precedence as the TUI:
|
|
24
|
+
*
|
|
25
|
+
* 1. `OMP_AUTH_BROKER_URL` / `OMP_AUTH_BROKER_TOKEN` env vars.
|
|
26
|
+
* 2. `auth.broker.url` / `auth.broker.token` in `<agentDir>/config.yml` or `<agentDir>/config.yaml`.
|
|
27
|
+
* 3. `<config-root>/auth-broker.token` file (paired with a URL from env/config).
|
|
28
|
+
*
|
|
29
|
+
* Returns `null` when no broker URL is configured — callers should fall back to
|
|
30
|
+
* the local SQLite store. Throws when a URL is configured but no token is
|
|
31
|
+
* available, matching the TUI behavior.
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveAuthBrokerConfig(options?: ResolveAuthBrokerConfigOptions): Promise<AuthBrokerClientConfig | null>;
|
|
34
|
+
/**
|
|
35
|
+
* Create an AuthStorage instance, using the broker when configured and falling
|
|
36
|
+
* back to the local SQLite store otherwise. This is the single source of truth
|
|
37
|
+
* for the TUI and the catalog generator.
|
|
38
|
+
*/
|
|
39
|
+
export declare function discoverAuthStorage(options?: DiscoverAuthStorageOptions): Promise<AuthStorage>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type AuthStorage } from "../auth-storage.js";
|
|
2
|
+
export interface AuthBrokerRefresherOptions {
|
|
3
|
+
storage: AuthStorage;
|
|
4
|
+
/** Refresh credentials expiring within this window. Default 5 min. */
|
|
5
|
+
refreshSkewMs?: number;
|
|
6
|
+
/** Loop cadence. Default 60s. */
|
|
7
|
+
refreshIntervalMs?: number;
|
|
8
|
+
/** Override clock (tests). */
|
|
9
|
+
now?: () => number;
|
|
10
|
+
}
|
|
11
|
+
export interface AuthBrokerRefresherSchedule {
|
|
12
|
+
enabled: boolean;
|
|
13
|
+
intervalMs: number;
|
|
14
|
+
skewMs: number;
|
|
15
|
+
nextSweepAt: number;
|
|
16
|
+
}
|
|
17
|
+
export declare class AuthBrokerRefresher {
|
|
18
|
+
#private;
|
|
19
|
+
constructor(opts: AuthBrokerRefresherOptions);
|
|
20
|
+
start(): void;
|
|
21
|
+
stop(): void;
|
|
22
|
+
getSchedule(): AuthBrokerRefresherSchedule;
|
|
23
|
+
/** Run one sweep. Exposed for tests. */
|
|
24
|
+
tick(): Promise<void>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { type AuthCredential, type AuthCredentialStore, type DisabledCredentialSummary, type OAuthCredential, type StoredAuthCredential, type StoredCredentialBlock } from "../auth-storage.js";
|
|
2
|
+
import type { OAuthCredentials } from "../registry/oauth/types.js";
|
|
3
|
+
import type { Provider } from "../types.js";
|
|
4
|
+
import type { ObservedUsageEntry, UsageReport } from "../usage.js";
|
|
5
|
+
import { type AuthBrokerClient } from "./client.js";
|
|
6
|
+
import type { SnapshotResponse } from "./types.js";
|
|
7
|
+
/**
|
|
8
|
+
* Per-provider OAuth identities visible to this trusted broker client.
|
|
9
|
+
* Missing providers are unrestricted; an empty set excludes that provider's
|
|
10
|
+
* OAuth credentials. API keys are never filtered.
|
|
11
|
+
*/
|
|
12
|
+
export type AuthBrokerAccountPool = ReadonlyMap<string, ReadonlySet<string>>;
|
|
13
|
+
export interface RemoteAuthCredentialStoreOptions {
|
|
14
|
+
client: AuthBrokerClient;
|
|
15
|
+
/**
|
|
16
|
+
* Initial snapshot. When omitted, callers must call
|
|
17
|
+
* {@link RemoteAuthCredentialStore.refreshSnapshot} before the first read.
|
|
18
|
+
*/
|
|
19
|
+
initialSnapshot?: SnapshotResponse;
|
|
20
|
+
/**
|
|
21
|
+
* Subscribe to the broker's SSE snapshot stream when available. Falls back
|
|
22
|
+
* to long-poll permanently when the broker returns 404. Default `true`.
|
|
23
|
+
*/
|
|
24
|
+
streamSnapshots?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Called with each broker-sourced raw full snapshot after the filtered
|
|
27
|
+
* public view is applied. The constructor's initial snapshot intentionally
|
|
28
|
+
* does not trigger this hook.
|
|
29
|
+
*/
|
|
30
|
+
onSnapshot?: (snapshot: SnapshotResponse, generation: number) => void;
|
|
31
|
+
/**
|
|
32
|
+
* OAuth identities visible through this store. This is a trusted-client
|
|
33
|
+
* routing policy, not broker authorization.
|
|
34
|
+
*/
|
|
35
|
+
accountPool?: AuthBrokerAccountPool;
|
|
36
|
+
/** Flush cadence for batched observed-usage reports. Default 10s. */
|
|
37
|
+
observedUsageFlushMs?: number;
|
|
38
|
+
}
|
|
39
|
+
export declare class RemoteAuthCredentialStore implements AuthCredentialStore {
|
|
40
|
+
#private;
|
|
41
|
+
constructor(opts: RemoteAuthCredentialStoreOptions);
|
|
42
|
+
get client(): AuthBrokerClient;
|
|
43
|
+
get snapshot(): SnapshotResponse;
|
|
44
|
+
/** Re-hydrate the in-memory snapshot from the broker. */
|
|
45
|
+
refreshSnapshot(): Promise<SnapshotResponse>;
|
|
46
|
+
listAuthCredentials(provider?: string): StoredAuthCredential[];
|
|
47
|
+
/** Broker-backed disabled tombstones; empty against brokers predating the endpoint. */
|
|
48
|
+
listDisabledCredentials(provider?: string, signal?: AbortSignal): Promise<DisabledCredentialSummary[]>;
|
|
49
|
+
getCredentialBlock(credentialId: number, providerKey: string, blockScope: string): number | undefined;
|
|
50
|
+
getCredentialBlockReconcileAfter(credentialId: number, providerKey: string, blockScope: string): number | undefined;
|
|
51
|
+
listCredentialBlocks(credentialIds: readonly number[]): StoredCredentialBlock[];
|
|
52
|
+
upsertCredentialBlock(block: StoredCredentialBlock): void;
|
|
53
|
+
deleteCredentialBlock(_credentialId: number, _providerKey: string, _blockScope: string): void;
|
|
54
|
+
deleteCredentialBlocks(credentialId: number): void;
|
|
55
|
+
cleanExpiredCredentialBlocks(nowMs: number): void;
|
|
56
|
+
/**
|
|
57
|
+
* In-memory update from a successful refresh through the broker. AuthStorage
|
|
58
|
+
* calls this after `#replaceCredentialAt`; the broker already persisted the
|
|
59
|
+
* authoritative row, so we just mirror it.
|
|
60
|
+
*/
|
|
61
|
+
updateAuthCredential(id: number, credential: AuthCredential): void;
|
|
62
|
+
deleteAuthCredential(id: number, disabledCause: string): void;
|
|
63
|
+
deleteAuthCredentialRemote(id: number, disabledCause: string): Promise<boolean>;
|
|
64
|
+
tryDisableAuthCredentialIfMatches(id: number, _expectedData: string, disabledCause: string): boolean;
|
|
65
|
+
waitForFreshSnapshot(maxWaitMs: number, opts?: {
|
|
66
|
+
signal?: AbortSignal;
|
|
67
|
+
}): Promise<boolean>;
|
|
68
|
+
prepareForRequest(credentialId: number, opts?: {
|
|
69
|
+
signal?: AbortSignal;
|
|
70
|
+
}): Promise<boolean>;
|
|
71
|
+
markCredentialSuspect(credentialId: number, opts?: {
|
|
72
|
+
signal?: AbortSignal;
|
|
73
|
+
}): Promise<void>;
|
|
74
|
+
replaceAuthCredentialsForProvider(_provider: string, _credentials: AuthCredential[]): StoredAuthCredential[];
|
|
75
|
+
upsertAuthCredentialForProvider(_provider: string, _credential: AuthCredential): StoredAuthCredential[];
|
|
76
|
+
deleteAuthCredentialsForProvider(_provider: string, _disabledCause: string): void;
|
|
77
|
+
/**
|
|
78
|
+
* Upsert a single credential through the broker. The broker server is the
|
|
79
|
+
* canonical writer — see `POST /v1/credential`. The redacted snapshot
|
|
80
|
+
* entries returned by the server replace the provider's rows in our local
|
|
81
|
+
* snapshot, and the global snapshot is then refreshed in the background so
|
|
82
|
+
* any concurrent peer (refresh, generation bump) stays in sync.
|
|
83
|
+
*/
|
|
84
|
+
upsertAuthCredentialRemote(provider: string, credential: AuthCredential): Promise<StoredAuthCredential[]>;
|
|
85
|
+
/**
|
|
86
|
+
* Replace-all semantics: disable every active credential for the provider,
|
|
87
|
+
* then upload each of the new credentials. Used by API-key login so a new
|
|
88
|
+
* key clobbers any previously stored key for the same provider.
|
|
89
|
+
*/
|
|
90
|
+
replaceAuthCredentialsRemote(provider: string, credentials: AuthCredential[]): Promise<StoredAuthCredential[]>;
|
|
91
|
+
/**
|
|
92
|
+
* Logout: disable every active credential for the provider on the broker,
|
|
93
|
+
* then drop them from the local snapshot. Refresh fetches the authoritative
|
|
94
|
+
* post-state in the background.
|
|
95
|
+
*/
|
|
96
|
+
deleteAuthCredentialsRemote(provider: string, disabledCause: string): Promise<void>;
|
|
97
|
+
getCache(key: string): string | null;
|
|
98
|
+
setCache(key: string, value: string, expiresAtSec: number): void;
|
|
99
|
+
/** Drop all cache rows whose keys start with the supplied prefix. */
|
|
100
|
+
deleteCachePrefix(prefix: string): void;
|
|
101
|
+
cleanExpiredCache(): void;
|
|
102
|
+
invalidateUsageCache(signal?: AbortSignal): Promise<void>;
|
|
103
|
+
/**
|
|
104
|
+
* Store-level hook consumed by `AuthStorage` — routes refresh through the
|
|
105
|
+
* broker so the actual refresh token never leaves the broker host. Returns
|
|
106
|
+
* the broker-redacted credential with {@link REMOTE_REFRESH_SENTINEL} in
|
|
107
|
+
* the `refresh` slot.
|
|
108
|
+
*/
|
|
109
|
+
refreshOAuthCredential(_provider: Provider, credentialId: number, _credential: OAuthCredential, signal?: AbortSignal): Promise<OAuthCredentials>;
|
|
110
|
+
/**
|
|
111
|
+
* Store-level hook consumed by `AuthStorage.fetchUsageReports()` — proxies
|
|
112
|
+
* to the broker's `/v1/usage` endpoint. The broker's egress IP isn't
|
|
113
|
+
* rate-limited by Anthropic's per-IP `/usage` cap the way a heavy
|
|
114
|
+
* residential laptop is, so all credentials surface every cycle.
|
|
115
|
+
*/
|
|
116
|
+
fetchUsageReports(signal?: AbortSignal): Promise<UsageReport[] | null>;
|
|
117
|
+
/**
|
|
118
|
+
* Per-credential usage hook consumed by `AuthStorage.#getUsageReport`. Pulls
|
|
119
|
+
* the aggregate broker `/v1/usage` once and serves all callers from the
|
|
120
|
+
* same response (coalesced + cached), then overlays any client-observed
|
|
121
|
+
* header hints for the matching credential.
|
|
122
|
+
*
|
|
123
|
+
* The broker already aggregates with its own 30s TTL on the server side; our
|
|
124
|
+
* 15s client TTL is below that so we usually re-use the broker's cache too.
|
|
125
|
+
*/
|
|
126
|
+
getUsageReport(provider: Provider, credential: OAuthCredential, signal?: AbortSignal): Promise<UsageReport | null>;
|
|
127
|
+
ingestUsageReport(provider: Provider, credential: OAuthCredential, report: UsageReport): boolean;
|
|
128
|
+
/**
|
|
129
|
+
* Fold locally observed request usage into the pending report and schedule
|
|
130
|
+
* a flush. One `POST /v1/usage/observed` at most per flush interval; on
|
|
131
|
+
* failure the batch is retained and retried with the next flush. A 404
|
|
132
|
+
* (pre-endpoint broker) disables reporting for the life of this store.
|
|
133
|
+
*/
|
|
134
|
+
recordObservedUsage(entries: ObservedUsageEntry[]): void;
|
|
135
|
+
close(): void;
|
|
136
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth broker HTTP server.
|
|
3
|
+
*
|
|
4
|
+
* Wraps an {@link AuthStorage} (backed by a SQLite store on the broker host)
|
|
5
|
+
* and exposes a minimal REST API for snapshot pulls and explicit refresh /
|
|
6
|
+
* disable operations. Background refresh of expiring credentials lives in
|
|
7
|
+
* {@link AuthBrokerRefresher}.
|
|
8
|
+
*
|
|
9
|
+
* Transport security is delegated to the operator (Tailscale / Wireguard);
|
|
10
|
+
* the server only checks a bearer token against an allow-list per request.
|
|
11
|
+
*/
|
|
12
|
+
import type { AuthStorage } from "../auth-storage.js";
|
|
13
|
+
export interface AuthBrokerServerOptions {
|
|
14
|
+
/** Underlying credential storage (wraps the local SQLite store on the broker). */
|
|
15
|
+
storage: AuthStorage;
|
|
16
|
+
/** Listen address; accepts `host:port` or just `port`. */
|
|
17
|
+
bind?: string;
|
|
18
|
+
/** Accept any of these bearer tokens. Empty disables auth (loopback only). */
|
|
19
|
+
bearerTokens: string[];
|
|
20
|
+
/** Broker version string surfaced on `/v1/healthz`. */
|
|
21
|
+
version?: string;
|
|
22
|
+
/** Refresh credentials expiring within this window. Default 5 min. */
|
|
23
|
+
refreshSkewMs?: number;
|
|
24
|
+
/** Background refresh cadence. Default 60s. */
|
|
25
|
+
refreshIntervalMs?: number;
|
|
26
|
+
/** Disable the background refresher (e.g. for tests). */
|
|
27
|
+
disableRefresher?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Override SSE keepalive cadence in milliseconds for `/v1/snapshot/stream`.
|
|
30
|
+
* Internal-only — tests use a short interval so they can assert heartbeats
|
|
31
|
+
* without long sleeps. Default {@link DEFAULT_STREAM_KEEPALIVE_MS}.
|
|
32
|
+
*/
|
|
33
|
+
streamKeepaliveMs?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Override cross-process SQLite change polling in milliseconds.
|
|
36
|
+
* Internal-only — tests use a short interval. Default 250ms.
|
|
37
|
+
*/
|
|
38
|
+
externalChangePollMs?: number;
|
|
39
|
+
}
|
|
40
|
+
export interface AuthBrokerServerHandle {
|
|
41
|
+
/** Bound URL (`http://host:port`). */
|
|
42
|
+
url: string;
|
|
43
|
+
port: number;
|
|
44
|
+
hostname: string;
|
|
45
|
+
close(): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
/** Boot the broker. Caller owns lifecycle; `handle.close()` to stop. */
|
|
48
|
+
export declare function startAuthBroker(opts: AuthBrokerServerOptions): AuthBrokerServerHandle;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SnapshotResponse } from "./types.js";
|
|
2
|
+
export interface ReadAuthBrokerSnapshotCacheOptions {
|
|
3
|
+
path: string;
|
|
4
|
+
token: string;
|
|
5
|
+
url: string;
|
|
6
|
+
ttlMs: number;
|
|
7
|
+
/** Override clock for deterministic tests. */
|
|
8
|
+
now?: () => number;
|
|
9
|
+
}
|
|
10
|
+
export interface WriteAuthBrokerSnapshotCacheOptions {
|
|
11
|
+
path: string;
|
|
12
|
+
token: string;
|
|
13
|
+
url: string;
|
|
14
|
+
snapshot: SnapshotResponse;
|
|
15
|
+
}
|
|
16
|
+
export declare function readAuthBrokerSnapshotCache(opts: ReadAuthBrokerSnapshotCacheOptions): Promise<SnapshotResponse | null>;
|
|
17
|
+
export declare function writeAuthBrokerSnapshotCache(opts: WriteAuthBrokerSnapshotCacheOptions): Promise<void>;
|