jeopi-ai 16.2.13 → 16.2.14
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 +3 -0
- package/package.json +9 -9
- package/src/auth-storage.ts +1 -1
- package/src/utils/schema/CONSTRAINTS.md +2 -1
- package/src/utils/schema/fields.ts +31 -0
- package/src/utils/schema/normalize.ts +44 -9
- package/dist/types/api-registry.d.ts +0 -30
- package/dist/types/auth-broker/client.d.ts +0 -73
- package/dist/types/auth-broker/discover.d.ts +0 -35
- package/dist/types/auth-broker/index.d.ts +0 -7
- package/dist/types/auth-broker/refresher.d.ts +0 -25
- package/dist/types/auth-broker/remote-store.d.ts +0 -102
- package/dist/types/auth-broker/server.d.ts +0 -43
- package/dist/types/auth-broker/snapshot-cache.d.ts +0 -17
- package/dist/types/auth-broker/types.d.ts +0 -107
- package/dist/types/auth-broker/wire-schemas.d.ts +0 -411
- package/dist/types/auth-gateway/http.d.ts +0 -39
- package/dist/types/auth-gateway/index.d.ts +0 -3
- package/dist/types/auth-gateway/server.d.ts +0 -36
- package/dist/types/auth-gateway/types.d.ts +0 -123
- package/dist/types/auth-retry.d.ts +0 -124
- package/dist/types/auth-storage.d.ts +0 -1026
- package/dist/types/dialect/anthropic.d.ts +0 -15
- package/dist/types/dialect/catalog.d.ts +0 -3
- package/dist/types/dialect/coercion.d.ts +0 -23
- package/dist/types/dialect/deepseek.d.ts +0 -14
- package/dist/types/dialect/demotion.d.ts +0 -23
- package/dist/types/dialect/examples.d.ts +0 -2
- package/dist/types/dialect/factory.d.ts +0 -3
- package/dist/types/dialect/fenced-thinking.d.ts +0 -53
- package/dist/types/dialect/gemini.d.ts +0 -17
- package/dist/types/dialect/gemma.d.ts +0 -15
- package/dist/types/dialect/glm.d.ts +0 -9
- package/dist/types/dialect/harmony.d.ts +0 -8
- package/dist/types/dialect/hermes.d.ts +0 -9
- package/dist/types/dialect/history.d.ts +0 -3
- package/dist/types/dialect/index.d.ts +0 -11
- package/dist/types/dialect/inventory.d.ts +0 -12
- package/dist/types/dialect/kimi.d.ts +0 -14
- package/dist/types/dialect/minimax.d.ts +0 -3
- package/dist/types/dialect/owned-stream.d.ts +0 -4
- package/dist/types/dialect/qwen3.d.ts +0 -9
- package/dist/types/dialect/rendering.d.ts +0 -45
- package/dist/types/dialect/thinking.d.ts +0 -6
- package/dist/types/dialect/types.d.ts +0 -69
- package/dist/types/dialect/xml.d.ts +0 -9
- package/dist/types/error/abort.d.ts +0 -14
- package/dist/types/error/auth-classify.d.ts +0 -16
- package/dist/types/error/auth.d.ts +0 -27
- package/dist/types/error/aws.d.ts +0 -23
- package/dist/types/error/classes.d.ts +0 -102
- package/dist/types/error/finalize.d.ts +0 -39
- package/dist/types/error/flags.d.ts +0 -79
- package/dist/types/error/format.d.ts +0 -20
- package/dist/types/error/gateway.d.ts +0 -20
- package/dist/types/error/index.d.ts +0 -13
- package/dist/types/error/oauth.d.ts +0 -43
- package/dist/types/error/provider.d.ts +0 -42
- package/dist/types/error/rate-limit.d.ts +0 -59
- package/dist/types/error/retryable.d.ts +0 -27
- package/dist/types/error/validation.d.ts +0 -32
- package/dist/types/index.d.ts +0 -49
- package/dist/types/provider-details.d.ts +0 -24
- package/dist/types/providers/__tests__/google-auth.test.d.ts +0 -1
- package/dist/types/providers/__tests__/kimi-code-thinking.test.d.ts +0 -1
- package/dist/types/providers/__tests__/openai-codex-error.test.d.ts +0 -1
- package/dist/types/providers/amazon-bedrock.d.ts +0 -39
- package/dist/types/providers/anthropic-client.d.ts +0 -94
- package/dist/types/providers/anthropic-messages-server-schema.d.ts +0 -497
- package/dist/types/providers/anthropic-messages-server.d.ts +0 -17
- package/dist/types/providers/anthropic-wire.d.ts +0 -318
- package/dist/types/providers/anthropic.d.ts +0 -248
- package/dist/types/providers/aws-credentials.d.ts +0 -53
- package/dist/types/providers/aws-eventstream.d.ts +0 -39
- package/dist/types/providers/aws-sigv4.d.ts +0 -55
- package/dist/types/providers/azure-openai-responses.d.ts +0 -16
- package/dist/types/providers/cursor.d.ts +0 -91
- package/dist/types/providers/devin.d.ts +0 -12
- package/dist/types/providers/error-message.d.ts +0 -27
- package/dist/types/providers/github-copilot-headers.d.ts +0 -40
- package/dist/types/providers/gitlab-duo-workflow.d.ts +0 -254
- package/dist/types/providers/gitlab-duo.d.ts +0 -27
- package/dist/types/providers/google-auth.d.ts +0 -32
- package/dist/types/providers/google-gemini-cli.d.ts +0 -118
- package/dist/types/providers/google-interactions.d.ts +0 -65
- package/dist/types/providers/google-shared.d.ts +0 -203
- package/dist/types/providers/google-types.d.ts +0 -155
- package/dist/types/providers/google-vertex.d.ts +0 -7
- package/dist/types/providers/google.d.ts +0 -4
- package/dist/types/providers/grammar.d.ts +0 -1
- package/dist/types/providers/kimi.d.ts +0 -27
- package/dist/types/providers/mock.d.ts +0 -178
- package/dist/types/providers/ollama.d.ts +0 -7
- package/dist/types/providers/openai-anthropic-shim.d.ts +0 -31
- package/dist/types/providers/openai-chat-server-schema.d.ts +0 -695
- package/dist/types/providers/openai-chat-server.d.ts +0 -16
- package/dist/types/providers/openai-chat-wire.d.ts +0 -644
- package/dist/types/providers/openai-codex/request-transformer.d.ts +0 -54
- package/dist/types/providers/openai-codex/response-handler.d.ts +0 -26
- package/dist/types/providers/openai-codex-responses.d.ts +0 -108
- package/dist/types/providers/openai-completions.d.ts +0 -45
- package/dist/types/providers/openai-reasoning-fallback.d.ts +0 -25
- package/dist/types/providers/openai-responses-server-schema.d.ts +0 -349
- package/dist/types/providers/openai-responses-server.d.ts +0 -17
- package/dist/types/providers/openai-responses-wire.d.ts +0 -6065
- package/dist/types/providers/openai-responses.d.ts +0 -126
- package/dist/types/providers/openai-shared.d.ts +0 -506
- package/dist/types/providers/pi-native-client.d.ts +0 -13
- package/dist/types/providers/pi-native-server.d.ts +0 -69
- package/dist/types/providers/register-builtins.d.ts +0 -32
- package/dist/types/providers/synthetic.d.ts +0 -26
- package/dist/types/providers/transform-messages.d.ts +0 -11
- package/dist/types/providers/vision-guard.d.ts +0 -20
- package/dist/types/registry/aimlapi.d.ts +0 -4
- package/dist/types/registry/alibaba-coding-plan.d.ts +0 -8
- package/dist/types/registry/amazon-bedrock.d.ts +0 -5
- package/dist/types/registry/anthropic.d.ts +0 -10
- package/dist/types/registry/api-key-login.d.ts +0 -42
- package/dist/types/registry/api-key-validation.d.ts +0 -43
- package/dist/types/registry/azure.d.ts +0 -4
- package/dist/types/registry/cerebras.d.ts +0 -7
- package/dist/types/registry/cloudflare-ai-gateway.d.ts +0 -13
- package/dist/types/registry/coreweave.d.ts +0 -7
- package/dist/types/registry/cursor.d.ts +0 -7
- package/dist/types/registry/deepseek.d.ts +0 -8
- package/dist/types/registry/derived.d.ts +0 -5
- package/dist/types/registry/devin.d.ts +0 -8
- package/dist/types/registry/firepass.d.ts +0 -16
- package/dist/types/registry/fireworks.d.ts +0 -7
- package/dist/types/registry/github-copilot.d.ts +0 -7
- package/dist/types/registry/gitlab-duo-workflow.d.ts +0 -10
- package/dist/types/registry/gitlab-duo.d.ts +0 -9
- package/dist/types/registry/google-antigravity.d.ts +0 -9
- package/dist/types/registry/google-gemini-cli.d.ts +0 -9
- package/dist/types/registry/google-vertex.d.ts +0 -5
- package/dist/types/registry/google.d.ts +0 -4
- package/dist/types/registry/groq.d.ts +0 -4
- package/dist/types/registry/huggingface.d.ts +0 -7
- package/dist/types/registry/index.d.ts +0 -4
- package/dist/types/registry/kagi.d.ts +0 -14
- package/dist/types/registry/kilo.d.ts +0 -7
- package/dist/types/registry/kimi-code.d.ts +0 -7
- package/dist/types/registry/litellm.d.ts +0 -13
- package/dist/types/registry/llama-cpp.d.ts +0 -8
- package/dist/types/registry/lm-studio.d.ts +0 -8
- package/dist/types/registry/minimax-code-cn.d.ts +0 -6
- package/dist/types/registry/minimax-code.d.ts +0 -6
- package/dist/types/registry/minimax.d.ts +0 -4
- package/dist/types/registry/mistral.d.ts +0 -4
- package/dist/types/registry/moonshot.d.ts +0 -7
- package/dist/types/registry/nanogpt.d.ts +0 -7
- package/dist/types/registry/nvidia.d.ts +0 -7
- package/dist/types/registry/oauth/__tests__/xai-oauth.test.d.ts +0 -1
- package/dist/types/registry/oauth/anthropic.d.ts +0 -23
- package/dist/types/registry/oauth/callback-server.d.ts +0 -72
- package/dist/types/registry/oauth/cursor.d.ts +0 -15
- package/dist/types/registry/oauth/devin.d.ts +0 -5
- package/dist/types/registry/oauth/github-copilot.d.ts +0 -30
- package/dist/types/registry/oauth/gitlab-duo-workflow.d.ts +0 -6
- package/dist/types/registry/oauth/gitlab-duo.d.ts +0 -3
- package/dist/types/registry/oauth/google-antigravity.d.ts +0 -11
- package/dist/types/registry/oauth/google-gemini-cli.d.ts +0 -10
- package/dist/types/registry/oauth/google-oauth-shared.d.ts +0 -22
- package/dist/types/registry/oauth/index.d.ts +0 -64
- package/dist/types/registry/oauth/kimi.d.ts +0 -21
- package/dist/types/registry/oauth/minimax-code.d.ts +0 -27
- package/dist/types/registry/oauth/openai-codex.d.ts +0 -33
- package/dist/types/registry/oauth/opencode.d.ts +0 -18
- package/dist/types/registry/oauth/perplexity.d.ts +0 -9
- package/dist/types/registry/oauth/pkce.d.ts +0 -8
- package/dist/types/registry/oauth/types.d.ts +0 -56
- package/dist/types/registry/oauth/wafer.d.ts +0 -1
- package/dist/types/registry/oauth/xai-oauth.d.ts +0 -52
- package/dist/types/registry/oauth/xiaomi.d.ts +0 -25
- package/dist/types/registry/ollama-cloud.d.ts +0 -7
- package/dist/types/registry/ollama.d.ts +0 -12
- package/dist/types/registry/openai-codex-device.d.ts +0 -8
- package/dist/types/registry/openai-codex.d.ts +0 -9
- package/dist/types/registry/openai.d.ts +0 -4
- package/dist/types/registry/opencode-go.d.ts +0 -6
- package/dist/types/registry/opencode-zen.d.ts +0 -6
- package/dist/types/registry/openrouter.d.ts +0 -13
- package/dist/types/registry/parallel.d.ts +0 -14
- package/dist/types/registry/perplexity.d.ts +0 -7
- package/dist/types/registry/qianfan.d.ts +0 -7
- package/dist/types/registry/qwen-portal.d.ts +0 -7
- package/dist/types/registry/registry.d.ts +0 -303
- package/dist/types/registry/sakana.d.ts +0 -7
- package/dist/types/registry/synthetic.d.ts +0 -6
- package/dist/types/registry/tavily.d.ts +0 -14
- package/dist/types/registry/together.d.ts +0 -6
- package/dist/types/registry/types.d.ts +0 -51
- package/dist/types/registry/umans.d.ts +0 -7
- package/dist/types/registry/venice.d.ts +0 -13
- package/dist/types/registry/vercel-ai-gateway.d.ts +0 -7
- package/dist/types/registry/vllm.d.ts +0 -7
- package/dist/types/registry/wafer-serverless.d.ts +0 -6
- package/dist/types/registry/xai-oauth.d.ts +0 -7
- package/dist/types/registry/xai.d.ts +0 -4
- package/dist/types/registry/xiaomi-token-plan-ams.d.ts +0 -6
- package/dist/types/registry/xiaomi-token-plan-cn.d.ts +0 -6
- package/dist/types/registry/xiaomi-token-plan-sgp.d.ts +0 -6
- package/dist/types/registry/xiaomi.d.ts +0 -6
- package/dist/types/registry/zai.d.ts +0 -7
- package/dist/types/registry/zenmux.d.ts +0 -7
- package/dist/types/registry/zhipu-coding-plan.d.ts +0 -7
- package/dist/types/stream.d.ts +0 -44
- package/dist/types/types.d.ts +0 -715
- package/dist/types/usage/claude.d.ts +0 -4
- package/dist/types/usage/gemini.d.ts +0 -2
- package/dist/types/usage/github-copilot.d.ts +0 -7
- package/dist/types/usage/google-antigravity.d.ts +0 -15
- package/dist/types/usage/kimi.d.ts +0 -2
- package/dist/types/usage/minimax-code.d.ts +0 -2
- package/dist/types/usage/ollama.d.ts +0 -5
- package/dist/types/usage/openai-codex-base-url.d.ts +0 -18
- package/dist/types/usage/openai-codex-reset.d.ts +0 -79
- package/dist/types/usage/openai-codex.d.ts +0 -3
- package/dist/types/usage/opencode-go.d.ts +0 -2
- package/dist/types/usage/shared.d.ts +0 -1
- package/dist/types/usage/zai.d.ts +0 -2
- package/dist/types/usage.d.ts +0 -346
- package/dist/types/utils/abort.d.ts +0 -25
- package/dist/types/utils/anthropic-auth.d.ts +0 -35
- package/dist/types/utils/block-symbols.d.ts +0 -20
- package/dist/types/utils/deterministic-id.d.ts +0 -16
- package/dist/types/utils/empty-completion-retry.d.ts +0 -21
- package/dist/types/utils/event-stream.d.ts +0 -30
- package/dist/types/utils/foundry.d.ts +0 -1
- package/dist/types/utils/google-validation.d.ts +0 -2
- package/dist/types/utils/harmony-leak.d.ts +0 -118
- package/dist/types/utils/http-inspector.d.ts +0 -30
- package/dist/types/utils/idle-iterator.d.ts +0 -137
- package/dist/types/utils/leaked-thinking-stream.d.ts +0 -29
- package/dist/types/utils/openai-http.d.ts +0 -54
- package/dist/types/utils/openrouter-headers.d.ts +0 -1
- package/dist/types/utils/parse-bind.d.ts +0 -23
- package/dist/types/utils/provider-response.d.ts +0 -3
- package/dist/types/utils/proxy.d.ts +0 -29
- package/dist/types/utils/request-debug.d.ts +0 -29
- package/dist/types/utils/retry-after.d.ts +0 -4
- package/dist/types/utils/retry.d.ts +0 -14
- package/dist/types/utils/schema/adapt.d.ts +0 -24
- package/dist/types/utils/schema/compatibility.d.ts +0 -30
- package/dist/types/utils/schema/dereference.d.ts +0 -11
- package/dist/types/utils/schema/draft.d.ts +0 -10
- package/dist/types/utils/schema/equality.d.ts +0 -4
- package/dist/types/utils/schema/fields.d.ts +0 -54
- package/dist/types/utils/schema/index.d.ts +0 -15
- package/dist/types/utils/schema/json-schema-validator.d.ts +0 -20
- package/dist/types/utils/schema/meta-validator.d.ts +0 -2
- package/dist/types/utils/schema/normalize.d.ts +0 -124
- package/dist/types/utils/schema/spill.d.ts +0 -8
- package/dist/types/utils/schema/stamps.d.ts +0 -17
- package/dist/types/utils/schema/strict-tool-validation.d.ts +0 -16
- package/dist/types/utils/schema/types.d.ts +0 -4
- package/dist/types/utils/schema/typescript.d.ts +0 -18
- package/dist/types/utils/schema/wire.d.ts +0 -92
- package/dist/types/utils/schema/zod-decontaminate.d.ts +0 -31
- package/dist/types/utils/sdk-stream-timeout.d.ts +0 -33
- package/dist/types/utils/sse-debug.d.ts +0 -5
- package/dist/types/utils/stream-markup-healing.d.ts +0 -87
- package/dist/types/utils/thinking-loop.d.ts +0 -102
- package/dist/types/utils/tool-call-loop-guard.d.ts +0 -26
- package/dist/types/utils/tool-choice.d.ts +0 -50
- package/dist/types/utils/validation.d.ts +0 -42
- package/dist/types/utils.d.ts +0 -24
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [16.2.14] - 2026-07-02
|
|
6
|
+
|
|
5
7
|
### Added
|
|
6
8
|
|
|
7
9
|
- Added opt-in support for Anthropic's server-side fallback beta (`server-side-fallback-2026-06-01`) on the `anthropic-messages` provider, including support for `AnthropicOptions.fallbacks`, mid-stream fallback content blocks, fallback billing/usage iterations, and automatic filtering of fallback blocks during cross-provider message transformations.
|
|
@@ -13,6 +15,7 @@
|
|
|
13
15
|
|
|
14
16
|
### Fixed
|
|
15
17
|
|
|
18
|
+
- Fixed `Cloud Code Assist API error (400): Invalid value at 'request.tools[N].function_declarations[i].parameters.properties[j].value.items'` on the Gemini CLI / Antigravity `parameters` wire path. `normalizeSchemaForCCA` now coerces 2020-12 boolean subschemas (`items: true`, `properties: {x: false}` — valid JSON Schema, so AJV validation passed them through) to `{}` in schema positions while preserving booleans in `enum`/`default` values, and strips JSON Schema keywords the CCA `Schema` proto has no field for (`$id`, `$anchor`, `$comment`, `uniqueItems`, `not`, `if`/`then`/`else`, `contains`/`minContains`/`maxContains`, `dependentRequired`/`dependentSchemas`, `contentEncoding`/`contentMediaType`/`contentSchema`, `deprecated`, `readOnly`, `writeOnly`), spilling human-meaningful ones into the description. These shapes commonly arrive from MCP-server tool schemas; one bad tool no longer 400s the whole request.
|
|
16
19
|
- Fixed an issue where broker usage fetch failures were not cached, causing redundant network requests during sequential ranking passes when the broker is offline.
|
|
17
20
|
- Fixed Xiaomi MiMo API key validation to use the supported `mimo-v2.5` model.
|
|
18
21
|
- Fixed certificate verification errors for custom gateways behind private CA bundles by ensuring `NODE_EXTRA_CA_CERTS` is respected across all provider fetches (including OpenAI-compatible, Codex, Ollama, Azure, and Google).
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "jeopi-ai",
|
|
4
|
-
"version": "16.2.
|
|
4
|
+
"version": "16.2.14",
|
|
5
5
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
6
6
|
"homepage": "https://github.com/akillness/jeopi",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -37,16 +37,16 @@
|
|
|
37
37
|
"fmt": "biome format --write ."
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@bufbuild/protobuf": "
|
|
41
|
-
"jeopi-catalog": "
|
|
42
|
-
"jeopi-utils": "
|
|
43
|
-
"jeopi-wire": "
|
|
44
|
-
"arktype": "
|
|
45
|
-
"zod": "
|
|
40
|
+
"@bufbuild/protobuf": "catalog:",
|
|
41
|
+
"jeopi-catalog": "catalog:",
|
|
42
|
+
"jeopi-utils": "catalog:",
|
|
43
|
+
"jeopi-wire": "catalog:",
|
|
44
|
+
"arktype": "catalog:",
|
|
45
|
+
"zod": "catalog:"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@bufbuild/protoc-gen-es": "
|
|
49
|
-
"@types/bun": "
|
|
48
|
+
"@bufbuild/protoc-gen-es": "catalog:",
|
|
49
|
+
"@types/bun": "catalog:"
|
|
50
50
|
},
|
|
51
51
|
"engines": {
|
|
52
52
|
"bun": ">=1.3.14"
|
package/src/auth-storage.ts
CHANGED
|
@@ -459,7 +459,7 @@ export type AuthStorageOptions = {
|
|
|
459
459
|
* so the TUI can show where a token came from (broker URL or local SQLite path).
|
|
460
460
|
*
|
|
461
461
|
* Examples:
|
|
462
|
-
* - `"local ~/.
|
|
462
|
+
* - `"local ~/.jeopi/agent/agent.db"`
|
|
463
463
|
* - `"broker http://omp.internal:8765"`
|
|
464
464
|
*/
|
|
465
465
|
sourceLabel?: string;
|
|
@@ -93,10 +93,11 @@ For Cloud Code Assist Claude tool declarations, schema MUST satisfy stricter con
|
|
|
93
93
|
|
|
94
94
|
### 3.2 Sanitization contract
|
|
95
95
|
|
|
96
|
-
1. Start with Google unsupported-key stripping behavior.
|
|
96
|
+
1. Start with Google unsupported-key stripping behavior, **plus** the CCA-proto-unknown keyword set (`CCA_PROTO_UNKNOWN_SCHEMA_FIELDS`): `$id`, `$anchor`, `$comment`, `uniqueItems`, `not`, `if`, `then`, `else`, `contains`, `minContains`, `maxContains`, `dependentRequired`, `dependentSchemas`, `contentEncoding`, `contentMediaType`, `contentSchema`, `deprecated`, `readOnly`, `writeOnly`. These keywords have no field in the CCA `Schema` proto; a leaked one 400s the whole request with "Unknown name".
|
|
97
97
|
2. **`nullable` keyword MUST be stripped** in CCA Claude path.
|
|
98
98
|
3. `type: ["T", "null"]` becomes `type: "T"` with no `nullable` marker.
|
|
99
99
|
4. Human-meaningful stripped keys are appended to `description` with the same spill format used by the Google dispatcher.
|
|
100
|
+
5. **Boolean subschemas MUST be coerced to `{}`** in schema positions (`items` values and `properties` map entries). `items: true` / `properties: {x: false}` are valid 2020-12 JSON Schema — AJV validation passes them — but the CCA proto requires a Schema message and rejects the request with `Invalid value at '...parameters.properties[N].value.items'`. Booleans in value positions (`enum` entries, `default`) MUST be preserved.
|
|
100
101
|
|
|
101
102
|
### 3.3 Combiner/union normalization contract
|
|
102
103
|
|
|
@@ -205,3 +205,34 @@ export const CCA_UNSUPPORTED_SCHEMA_FIELDS: Record<string, true> = {
|
|
|
205
205
|
$dynamicAnchor: true,
|
|
206
206
|
propertyNames: true,
|
|
207
207
|
};
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* JSON Schema keywords with no counterpart field in the Cloud Code Assist
|
|
211
|
+
* `Schema` proto (the legacy `parameters` wire shape used for Claude models
|
|
212
|
+
* and every Antigravity model). Any of these reaching the wire produces a
|
|
213
|
+
* 400 INVALID_ARGUMENT ("Unknown name ..."). Stripped only on the CCA
|
|
214
|
+
* `parameters` path — the Google `parametersJsonSchema` path accepts full
|
|
215
|
+
* JSON Schema and keeps them.
|
|
216
|
+
*/
|
|
217
|
+
export const CCA_PROTO_UNKNOWN_SCHEMA_FIELDS: Record<string, true> = {
|
|
218
|
+
$id: true,
|
|
219
|
+
$anchor: true,
|
|
220
|
+
$comment: true,
|
|
221
|
+
uniqueItems: true,
|
|
222
|
+
not: true,
|
|
223
|
+
if: true,
|
|
224
|
+
// biome-ignore lint/suspicious/noThenProperty: JSON Schema keyword
|
|
225
|
+
then: true,
|
|
226
|
+
else: true,
|
|
227
|
+
contains: true,
|
|
228
|
+
minContains: true,
|
|
229
|
+
maxContains: true,
|
|
230
|
+
dependentRequired: true,
|
|
231
|
+
dependentSchemas: true,
|
|
232
|
+
contentEncoding: true,
|
|
233
|
+
contentMediaType: true,
|
|
234
|
+
contentSchema: true,
|
|
235
|
+
deprecated: true,
|
|
236
|
+
readOnly: true,
|
|
237
|
+
writeOnly: true,
|
|
238
|
+
};
|
|
@@ -13,6 +13,7 @@ import { upgradeJsonSchemaTo202012 } from "./draft";
|
|
|
13
13
|
import { areJsonValuesEqual, mergeCompatibleEnumSchemas, mergePropertySchemas } from "./equality";
|
|
14
14
|
import {
|
|
15
15
|
ALL_CCA_TYPE_SPECIFIC_KEYS,
|
|
16
|
+
CCA_PROTO_UNKNOWN_SCHEMA_FIELDS,
|
|
16
17
|
CLOUD_CODE_ASSIST_SHARED_SCHEMA_KEYS,
|
|
17
18
|
CLOUD_CODE_ASSIST_TYPE_SPECIFIC_KEYS,
|
|
18
19
|
COMBINATOR_KEYS,
|
|
@@ -51,6 +52,14 @@ export interface NormalizeSchemaOptions {
|
|
|
51
52
|
foldOneOfIntoAnyOf: boolean;
|
|
52
53
|
dropNonScalarEnum: boolean;
|
|
53
54
|
rejectResidualIncompatibilities?: ReadonlyArray<ResidualSchemaIncompatibility>;
|
|
55
|
+
/**
|
|
56
|
+
* Coerce 2020-12 boolean subschemas (`items: true`, `properties: {x: false}`)
|
|
57
|
+
* to `{}` in schema positions. Boolean schemas are valid JSON Schema (so AJV
|
|
58
|
+
* validation passes them) but the Cloud Code Assist `Schema` proto requires
|
|
59
|
+
* a message, and a leaked boolean fails the whole request with
|
|
60
|
+
* `Invalid value at '...parameters.properties[N].value.items'` (400).
|
|
61
|
+
*/
|
|
62
|
+
coerceBooleanSubschemas?: boolean;
|
|
54
63
|
validateAndFallback?: { fallback: unknown };
|
|
55
64
|
}
|
|
56
65
|
|
|
@@ -84,6 +93,23 @@ function isGoogleUnsupportedSchemaField(key: string): boolean {
|
|
|
84
93
|
return Object.hasOwn(UNSUPPORTED_SCHEMA_FIELDS, key);
|
|
85
94
|
}
|
|
86
95
|
|
|
96
|
+
function isCcaUnsupportedSchemaField(key: string): boolean {
|
|
97
|
+
return Object.hasOwn(UNSUPPORTED_SCHEMA_FIELDS, key) || Object.hasOwn(CCA_PROTO_UNKNOWN_SCHEMA_FIELDS, key);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Replace a boolean subschema with `{}` when it sits in a schema position:
|
|
102
|
+
* a value inside a `properties` map, or the value of `items`. Only these
|
|
103
|
+
* positions are proto-mapped schema fields on the CCA wire; booleans in
|
|
104
|
+
* value positions (`enum` entries, `default`) are never touched because they
|
|
105
|
+
* arrive as array/scalar entries, not via this per-key assignment.
|
|
106
|
+
*/
|
|
107
|
+
function coerceBooleanSubschema(value: unknown, key: string, options: NormalizeSchemaWalkOptions): unknown {
|
|
108
|
+
if (options.coerceBooleanSubschemas !== true || typeof value !== "boolean") return value;
|
|
109
|
+
if (options.insideProperties || key === "items") return {};
|
|
110
|
+
return value;
|
|
111
|
+
}
|
|
112
|
+
|
|
87
113
|
function isMcpUnsupportedSchemaField(key: string): boolean {
|
|
88
114
|
return key === "$schema";
|
|
89
115
|
}
|
|
@@ -303,10 +329,14 @@ function normalizeSchemaObjectNode(value: JsonObject, options: NormalizeSchemaWa
|
|
|
303
329
|
continue;
|
|
304
330
|
}
|
|
305
331
|
if (options.stripNullableKeyword && key === "nullable") continue;
|
|
306
|
-
result[key] =
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
332
|
+
result[key] = coerceBooleanSubschema(
|
|
333
|
+
normalizeSchemaNode(entry, {
|
|
334
|
+
...options,
|
|
335
|
+
insideProperties: !options.insideProperties && key === "properties",
|
|
336
|
+
}),
|
|
337
|
+
key,
|
|
338
|
+
options,
|
|
339
|
+
);
|
|
310
340
|
}
|
|
311
341
|
applyDescriptionSpill(result, spill, options);
|
|
312
342
|
return applyNodePostProcessing(result, options);
|
|
@@ -325,10 +355,14 @@ function normalizeSchemaObjectNode(value: JsonObject, options: NormalizeSchemaWa
|
|
|
325
355
|
constValue = entry;
|
|
326
356
|
continue;
|
|
327
357
|
}
|
|
328
|
-
result[key] =
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
358
|
+
result[key] = coerceBooleanSubschema(
|
|
359
|
+
normalizeSchemaNode(entry, {
|
|
360
|
+
...options,
|
|
361
|
+
insideProperties: !options.insideProperties && key === "properties",
|
|
362
|
+
}),
|
|
363
|
+
key,
|
|
364
|
+
options,
|
|
365
|
+
);
|
|
332
366
|
}
|
|
333
367
|
|
|
334
368
|
if (options.normalizeTypeArrayToNullable && Array.isArray(result.type)) {
|
|
@@ -924,7 +958,7 @@ export function normalizeSchemaForGoogle(value: unknown): unknown {
|
|
|
924
958
|
|
|
925
959
|
export function normalizeSchemaForCCA(value: unknown): unknown {
|
|
926
960
|
return normalizeSchema(value, {
|
|
927
|
-
unsupportedFields:
|
|
961
|
+
unsupportedFields: isCcaUnsupportedSchemaField,
|
|
928
962
|
normalizeFieldNames: true,
|
|
929
963
|
collapseNullFields: false,
|
|
930
964
|
normalizeTypeArrayToNullable: true,
|
|
@@ -940,6 +974,7 @@ export function normalizeSchemaForCCA(value: unknown): unknown {
|
|
|
940
974
|
inferTypeForBareEnum: true,
|
|
941
975
|
dropNonScalarEnum: false,
|
|
942
976
|
foldOneOfIntoAnyOf: false,
|
|
977
|
+
coerceBooleanSubschemas: true,
|
|
943
978
|
rejectResidualIncompatibilities: ["type-array", "type-null", "nullable", "combiners"],
|
|
944
979
|
validateAndFallback: { fallback: CLOUD_CODE_ASSIST_CLAUDE_FALLBACK_SCHEMA },
|
|
945
980
|
});
|
|
@@ -1,30 +0,0 @@
|
|
|
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";
|
|
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;
|
|
@@ -1,73 +0,0 @@
|
|
|
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 } from "../auth-storage";
|
|
9
|
-
import type { CredentialDisableResponse, CredentialRefreshResponse, CredentialUploadResponse, HealthzResponse, SnapshotResponse, SnapshotStreamEvent, UsageResponse } from "./types";
|
|
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
|
-
fetchUsage(signal?: AbortSignal): Promise<UsageResponse>;
|
|
70
|
-
refreshCredential(id: number, signal?: AbortSignal): Promise<CredentialRefreshResponse>;
|
|
71
|
-
disableCredential(id: number, cause: string, signal?: AbortSignal): Promise<CredentialDisableResponse>;
|
|
72
|
-
uploadCredential(provider: string, credential: AuthCredential, signal?: AbortSignal): Promise<CredentialUploadResponse>;
|
|
73
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { AuthStorage } from "../auth-storage";
|
|
2
|
-
export interface AuthBrokerClientConfig {
|
|
3
|
-
url: string;
|
|
4
|
-
token: string;
|
|
5
|
-
}
|
|
6
|
-
export interface ResolveAuthBrokerConfigOptions {
|
|
7
|
-
agentDir?: string;
|
|
8
|
-
configValueResolver?: (config: string) => Promise<string | undefined>;
|
|
9
|
-
}
|
|
10
|
-
export interface DiscoverAuthStorageOptions {
|
|
11
|
-
agentDir?: string;
|
|
12
|
-
configValueResolver?: (config: string) => Promise<string | undefined>;
|
|
13
|
-
cachePath?: string;
|
|
14
|
-
sourceLabel?: string;
|
|
15
|
-
}
|
|
16
|
-
/** Path to the local bearer token file. Created by `omp auth-broker token`. */
|
|
17
|
-
export declare function getAuthBrokerTokenFilePath(): string;
|
|
18
|
-
/**
|
|
19
|
-
* Resolve broker connection configuration using the same precedence as the TUI:
|
|
20
|
-
*
|
|
21
|
-
* 1. `OMP_AUTH_BROKER_URL` / `OMP_AUTH_BROKER_TOKEN` env vars.
|
|
22
|
-
* 2. `auth.broker.url` / `auth.broker.token` in `<agentDir>/config.yml`.
|
|
23
|
-
* 3. `<config-root>/auth-broker.token` file (paired with a URL from env/config).
|
|
24
|
-
*
|
|
25
|
-
* Returns `null` when no broker URL is configured — callers should fall back to
|
|
26
|
-
* the local SQLite store. Throws when a URL is configured but no token is
|
|
27
|
-
* available, matching the TUI behavior.
|
|
28
|
-
*/
|
|
29
|
-
export declare function resolveAuthBrokerConfig(options?: ResolveAuthBrokerConfigOptions): Promise<AuthBrokerClientConfig | null>;
|
|
30
|
-
/**
|
|
31
|
-
* Create an AuthStorage instance, using the broker when configured and falling
|
|
32
|
-
* back to the local SQLite store otherwise. This is the single source of truth
|
|
33
|
-
* for the TUI and the catalog generator.
|
|
34
|
-
*/
|
|
35
|
-
export declare function discoverAuthStorage(options?: DiscoverAuthStorageOptions): Promise<AuthStorage>;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { type AuthStorage } from "../auth-storage";
|
|
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
|
-
}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import { type AuthCredential, type AuthCredentialStore, type OAuthCredential, type StoredAuthCredential } from "../auth-storage";
|
|
2
|
-
import type { OAuthCredentials } from "../registry/oauth/types";
|
|
3
|
-
import type { Provider } from "../types";
|
|
4
|
-
import type { UsageReport } from "../usage";
|
|
5
|
-
import { type AuthBrokerClient } from "./client";
|
|
6
|
-
import type { SnapshotResponse } from "./types";
|
|
7
|
-
export interface RemoteAuthCredentialStoreOptions {
|
|
8
|
-
client: AuthBrokerClient;
|
|
9
|
-
/**
|
|
10
|
-
* Initial snapshot. When omitted, callers must call
|
|
11
|
-
* {@link RemoteAuthCredentialStore.refreshSnapshot} before the first read.
|
|
12
|
-
*/
|
|
13
|
-
initialSnapshot?: SnapshotResponse;
|
|
14
|
-
/**
|
|
15
|
-
* Subscribe to the broker's SSE snapshot stream when available. Falls back
|
|
16
|
-
* to long-poll permanently when the broker returns 404. Default `true`.
|
|
17
|
-
*/
|
|
18
|
-
streamSnapshots?: boolean;
|
|
19
|
-
/**
|
|
20
|
-
* Called after broker-sourced full snapshots are applied. The constructor's
|
|
21
|
-
* initial snapshot intentionally does not trigger this hook.
|
|
22
|
-
*/
|
|
23
|
-
onSnapshot?: (snapshot: SnapshotResponse, generation: number) => void;
|
|
24
|
-
}
|
|
25
|
-
export declare class RemoteAuthCredentialStore implements AuthCredentialStore {
|
|
26
|
-
#private;
|
|
27
|
-
constructor(opts: RemoteAuthCredentialStoreOptions);
|
|
28
|
-
get client(): AuthBrokerClient;
|
|
29
|
-
get snapshot(): SnapshotResponse;
|
|
30
|
-
/** Re-hydrate the in-memory snapshot from the broker. */
|
|
31
|
-
refreshSnapshot(): Promise<SnapshotResponse>;
|
|
32
|
-
listAuthCredentials(provider?: string): StoredAuthCredential[];
|
|
33
|
-
/**
|
|
34
|
-
* In-memory update from a successful refresh through the broker. AuthStorage
|
|
35
|
-
* calls this after `#replaceCredentialAt`; the broker already persisted the
|
|
36
|
-
* authoritative row, so we just mirror it.
|
|
37
|
-
*/
|
|
38
|
-
updateAuthCredential(id: number, credential: AuthCredential): void;
|
|
39
|
-
deleteAuthCredential(id: number, disabledCause: string): void;
|
|
40
|
-
deleteAuthCredentialRemote(id: number, disabledCause: string): Promise<boolean>;
|
|
41
|
-
tryDisableAuthCredentialIfMatches(id: number, _expectedData: string, disabledCause: string): boolean;
|
|
42
|
-
waitForFreshSnapshot(maxWaitMs: number, opts?: {
|
|
43
|
-
signal?: AbortSignal;
|
|
44
|
-
}): Promise<boolean>;
|
|
45
|
-
prepareForRequest(credentialId: number, opts?: {
|
|
46
|
-
signal?: AbortSignal;
|
|
47
|
-
}): Promise<boolean>;
|
|
48
|
-
markCredentialSuspect(credentialId: number, opts?: {
|
|
49
|
-
signal?: AbortSignal;
|
|
50
|
-
}): Promise<void>;
|
|
51
|
-
replaceAuthCredentialsForProvider(_provider: string, _credentials: AuthCredential[]): StoredAuthCredential[];
|
|
52
|
-
upsertAuthCredentialForProvider(_provider: string, _credential: AuthCredential): StoredAuthCredential[];
|
|
53
|
-
deleteAuthCredentialsForProvider(_provider: string, _disabledCause: string): void;
|
|
54
|
-
/**
|
|
55
|
-
* Upsert a single credential through the broker. The broker server is the
|
|
56
|
-
* canonical writer — see `POST /v1/credential`. The redacted snapshot
|
|
57
|
-
* entries returned by the server replace the provider's rows in our local
|
|
58
|
-
* snapshot, and the global snapshot is then refreshed in the background so
|
|
59
|
-
* any concurrent peer (refresh, generation bump) stays in sync.
|
|
60
|
-
*/
|
|
61
|
-
upsertAuthCredentialRemote(provider: string, credential: AuthCredential): Promise<StoredAuthCredential[]>;
|
|
62
|
-
/**
|
|
63
|
-
* Replace-all semantics: disable every active credential for the provider,
|
|
64
|
-
* then upload each of the new credentials. Used by API-key login so a new
|
|
65
|
-
* key clobbers any previously stored key for the same provider.
|
|
66
|
-
*/
|
|
67
|
-
replaceAuthCredentialsRemote(provider: string, credentials: AuthCredential[]): Promise<StoredAuthCredential[]>;
|
|
68
|
-
/**
|
|
69
|
-
* Logout: disable every active credential for the provider on the broker,
|
|
70
|
-
* then drop them from the local snapshot. Refresh fetches the authoritative
|
|
71
|
-
* post-state in the background.
|
|
72
|
-
*/
|
|
73
|
-
deleteAuthCredentialsRemote(provider: string, disabledCause: string): Promise<void>;
|
|
74
|
-
getCache(key: string): string | null;
|
|
75
|
-
setCache(key: string, value: string, expiresAtSec: number): void;
|
|
76
|
-
cleanExpiredCache(): void;
|
|
77
|
-
/**
|
|
78
|
-
* Store-level hook consumed by `AuthStorage` — routes refresh through the
|
|
79
|
-
* broker so the actual refresh token never leaves the broker host. Returns
|
|
80
|
-
* the broker-redacted credential with {@link REMOTE_REFRESH_SENTINEL} in
|
|
81
|
-
* the `refresh` slot.
|
|
82
|
-
*/
|
|
83
|
-
refreshOAuthCredential(_provider: Provider, credentialId: number, _credential: OAuthCredential, signal?: AbortSignal): Promise<OAuthCredentials>;
|
|
84
|
-
/**
|
|
85
|
-
* Store-level hook consumed by `AuthStorage.fetchUsageReports()` — proxies
|
|
86
|
-
* to the broker's `/v1/usage` endpoint. The broker's egress IP isn't
|
|
87
|
-
* rate-limited by Anthropic's per-IP `/usage` cap the way a heavy
|
|
88
|
-
* residential laptop is, so all credentials surface every cycle.
|
|
89
|
-
*/
|
|
90
|
-
fetchUsageReports(signal?: AbortSignal): Promise<UsageReport[] | null>;
|
|
91
|
-
/**
|
|
92
|
-
* Per-credential usage hook consumed by `AuthStorage.#getUsageReport`. Pulls
|
|
93
|
-
* the aggregate broker `/v1/usage` once and serves all callers from the
|
|
94
|
-
* same response (coalesced + cached), then matches the credential to a
|
|
95
|
-
* report by provider + identity (accountId / email / projectId).
|
|
96
|
-
*
|
|
97
|
-
* The broker already aggregates with its own 30s TTL on the server side; our
|
|
98
|
-
* 15s client TTL is below that so we usually re-use the broker's cache too.
|
|
99
|
-
*/
|
|
100
|
-
getUsageReport(provider: Provider, credential: OAuthCredential, signal?: AbortSignal): Promise<UsageReport | null>;
|
|
101
|
-
close(): void;
|
|
102
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
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";
|
|
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
|
-
export interface AuthBrokerServerHandle {
|
|
36
|
-
/** Bound URL (`http://host:port`). */
|
|
37
|
-
url: string;
|
|
38
|
-
port: number;
|
|
39
|
-
hostname: string;
|
|
40
|
-
close(): Promise<void>;
|
|
41
|
-
}
|
|
42
|
-
/** Boot the broker. Caller owns lifecycle; `handle.close()` to stop. */
|
|
43
|
-
export declare function startAuthBroker(opts: AuthBrokerServerOptions): AuthBrokerServerHandle;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { SnapshotResponse } from "./types";
|
|
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>;
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wire types shared between the auth-broker server and clients.
|
|
3
|
-
*
|
|
4
|
-
* The broker holds OAuth refresh tokens and exposes a redacted snapshot;
|
|
5
|
-
* clients use `access` tokens directly and call back to the broker when a
|
|
6
|
-
* credential expires or a 401 surfaces on a supposedly-fresh credential.
|
|
7
|
-
*/
|
|
8
|
-
import type { AuthCredential, AuthCredentialSnapshot, AuthCredentialSnapshotEntry } from "../auth-storage";
|
|
9
|
-
import type { UsageReport } from "../usage";
|
|
10
|
-
/** GET /v1/healthz response body. */
|
|
11
|
-
export interface HealthzResponse {
|
|
12
|
-
ok: boolean;
|
|
13
|
-
version?: string;
|
|
14
|
-
}
|
|
15
|
-
export interface RefresherSchedule {
|
|
16
|
-
enabled: boolean;
|
|
17
|
-
intervalMs: number;
|
|
18
|
-
skewMs: number;
|
|
19
|
-
nextSweepInMs: number;
|
|
20
|
-
}
|
|
21
|
-
export type SnapshotEntry = AuthCredentialSnapshotEntry & {
|
|
22
|
-
rotatesInMs: number | null;
|
|
23
|
-
};
|
|
24
|
-
/** GET /v1/snapshot response body. */
|
|
25
|
-
export interface SnapshotResponse extends Omit<AuthCredentialSnapshot, "credentials"> {
|
|
26
|
-
serverNowMs: number;
|
|
27
|
-
refresher: RefresherSchedule;
|
|
28
|
-
credentials: SnapshotEntry[];
|
|
29
|
-
}
|
|
30
|
-
/** GET /v1/usage response body — matches the local `AuthStorage.fetchUsageReports` shape. */
|
|
31
|
-
export interface UsageResponse {
|
|
32
|
-
generatedAt: number;
|
|
33
|
-
reports: UsageReport[];
|
|
34
|
-
}
|
|
35
|
-
/** POST /v1/credential/:id/refresh response body. */
|
|
36
|
-
export interface CredentialRefreshResponse {
|
|
37
|
-
entry: AuthCredentialSnapshotEntry;
|
|
38
|
-
}
|
|
39
|
-
/** POST /v1/credential/:id/disable request body. */
|
|
40
|
-
export interface CredentialDisableRequest {
|
|
41
|
-
cause: string;
|
|
42
|
-
}
|
|
43
|
-
/** POST /v1/credential/:id/disable response body. */
|
|
44
|
-
export interface CredentialDisableResponse {
|
|
45
|
-
ok: boolean;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* POST /v1/credential request body. The OAuth `refresh` must be the *real*
|
|
49
|
-
* refresh token (not the sentinel) — the broker is the canonical writer.
|
|
50
|
-
*/
|
|
51
|
-
export interface CredentialUploadRequest {
|
|
52
|
-
provider: string;
|
|
53
|
-
credential: AuthCredential;
|
|
54
|
-
}
|
|
55
|
-
/** POST /v1/credential response body — redacted snapshot of the provider's rows after upsert. */
|
|
56
|
-
export interface CredentialUploadResponse {
|
|
57
|
-
entries: AuthCredentialSnapshotEntry[];
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* SSE event kinds emitted on `GET /v1/snapshot/stream`. The same value is set
|
|
61
|
-
* as the SSE `event:` name (load-bearing for clients) **and** embedded as a
|
|
62
|
-
* `kind` field inside the JSON body so a Zod discriminated union can validate
|
|
63
|
-
* the payload without consulting the line metadata.
|
|
64
|
-
*/
|
|
65
|
-
export type SnapshotStreamEventKind = "snapshot" | "entry" | "removed";
|
|
66
|
-
/** Initial frame emitted on connect — the full {@link SnapshotResponse}. */
|
|
67
|
-
export interface SnapshotStreamSnapshotEvent extends SnapshotResponse {
|
|
68
|
-
kind: "snapshot";
|
|
69
|
-
}
|
|
70
|
-
/** Single credential added/changed (upsert or refresh). */
|
|
71
|
-
export interface SnapshotStreamEntryEvent {
|
|
72
|
-
kind: "entry";
|
|
73
|
-
generation: number;
|
|
74
|
-
serverNowMs: number;
|
|
75
|
-
refresher: RefresherSchedule;
|
|
76
|
-
entry: SnapshotEntry;
|
|
77
|
-
}
|
|
78
|
-
/** Single credential disabled/deleted. */
|
|
79
|
-
export interface SnapshotStreamRemovedEvent {
|
|
80
|
-
kind: "removed";
|
|
81
|
-
generation: number;
|
|
82
|
-
serverNowMs: number;
|
|
83
|
-
refresher: RefresherSchedule;
|
|
84
|
-
id: number;
|
|
85
|
-
}
|
|
86
|
-
/** Discriminated union of every event the snapshot stream emits. */
|
|
87
|
-
export type SnapshotStreamEvent = SnapshotStreamSnapshotEvent | SnapshotStreamEntryEvent | SnapshotStreamRemovedEvent;
|
|
88
|
-
/**
|
|
89
|
-
* Default bearer-protected route prefix. The broker exposes `/v1/healthz`
|
|
90
|
-
* unauthenticated for liveness probes; everything else requires a bearer.
|
|
91
|
-
*/
|
|
92
|
-
export declare const AUTH_BROKER_API_PREFIX = "/v1";
|
|
93
|
-
/** Default port when none is configured. Loopback-only, no external exposure. */
|
|
94
|
-
export declare const DEFAULT_AUTH_BROKER_BIND = "127.0.0.1:8765";
|
|
95
|
-
/** Default broker→provider refresh skew. Refresh credentials this close to expiry. */
|
|
96
|
-
export declare const DEFAULT_REFRESH_SKEW_MS: number;
|
|
97
|
-
/** Default broker refresh-loop cadence. */
|
|
98
|
-
export declare const DEFAULT_REFRESH_INTERVAL_MS = 60000;
|
|
99
|
-
/** Default freshness window for the encrypted local broker snapshot cache. */
|
|
100
|
-
export declare const DEFAULT_SNAPSHOT_CACHE_TTL_MS: number;
|
|
101
|
-
/** Keepalive cadence for `GET /v1/snapshot/stream` SSE comments. */
|
|
102
|
-
export declare const DEFAULT_STREAM_KEEPALIVE_MS = 20000;
|
|
103
|
-
/**
|
|
104
|
-
* Bun.serve `idleTimeout` (seconds) used by the broker. Default Bun idle
|
|
105
|
-
* timeout (10s) would close long-lived SSE connections between keepalives.
|
|
106
|
-
*/
|
|
107
|
-
export declare const DEFAULT_SERVER_IDLE_TIMEOUT_S = 255;
|