@oh-my-pi/pi-ai 17.1.3 → 17.1.5
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 +57 -0
- package/README.md +1 -1
- package/dist/types/auth-broker/client.d.ts +7 -1
- package/dist/types/auth-broker/remote-store.d.ts +4 -1
- package/dist/types/auth-broker/types.d.ts +6 -1
- package/dist/types/auth-broker/wire-schema-resource.d.ts +53 -0
- package/dist/types/auth-broker/wire-schemas.d.ts +3 -564
- package/dist/types/auth-storage.d.ts +55 -0
- package/dist/types/providers/anthropic.d.ts +1 -7
- package/dist/types/providers/claude-code-fingerprint.d.ts +15 -0
- package/dist/types/providers/cursor.d.ts +29 -7
- package/dist/types/providers/openai-anthropic-shim.d.ts +2 -0
- package/dist/types/providers/openai-codex/request-transformer.d.ts +5 -4
- package/dist/types/providers/openai-codex-responses.d.ts +3 -0
- package/dist/types/registry/alibaba-token-plan.d.ts +11 -0
- package/dist/types/registry/oauth/anthropic-constants.d.ts +12 -0
- package/dist/types/registry/oauth/anthropic.d.ts +1 -0
- package/dist/types/registry/oauth/index.d.ts +1 -0
- package/dist/types/registry/oauth/types.d.ts +8 -0
- package/dist/types/types.d.ts +71 -1
- package/dist/types/usage/minimax-code.d.ts +1 -0
- package/dist/types/usage.d.ts +10 -0
- package/package.json +4 -4
- package/src/auth-broker/client.ts +63 -32
- package/src/auth-broker/discover.ts +15 -6
- package/src/auth-broker/remote-store.ts +12 -0
- package/src/auth-broker/server.ts +14 -10
- package/src/auth-broker/types.ts +7 -0
- package/src/auth-broker/wire-schema-resource.ts +487 -0
- package/src/auth-broker/wire-schemas.ts +40 -350
- package/src/auth-storage.ts +279 -29
- package/src/error/flags.ts +1 -1
- package/src/providers/__tests__/kimi-code-thinking.test.ts +136 -6
- package/src/providers/amazon-bedrock.ts +3 -4
- package/src/providers/anthropic.ts +129 -36
- package/src/providers/azure-openai-responses.ts +36 -5
- package/src/providers/claude-code-fingerprint.ts +19 -0
- package/src/providers/cursor.ts +514 -38
- package/src/providers/kimi.ts +1 -0
- package/src/providers/openai-anthropic-shim.ts +6 -0
- package/src/providers/openai-codex/request-transformer.ts +27 -7
- package/src/providers/openai-codex-responses.ts +37 -14
- package/src/providers/openai-completions.ts +6 -1
- package/src/providers/openai-responses.ts +14 -8
- package/src/providers/openai-shared.ts +48 -40
- package/src/registry/alibaba-token-plan.ts +103 -21
- package/src/registry/oauth/anthropic-constants.ts +12 -0
- package/src/registry/oauth/anthropic.ts +3 -1
- package/src/registry/oauth/index.ts +1 -0
- package/src/registry/oauth/types.ts +8 -0
- package/src/stream.ts +7 -2
- package/src/types.ts +79 -1
- package/src/usage/alibaba-token-plan.ts +34 -6
- package/src/usage/claude.ts +7 -2
- package/src/usage/minimax-code.ts +280 -19
- package/src/usage/openai-codex.ts +61 -14
- package/src/usage.ts +10 -0
- package/src/utils/leaked-thinking-stream.ts +116 -35
- package/src/utils.ts +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,63 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [17.1.5] - 2026-07-27
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Fixed OpenAI Responses replay treating a tool output as paired with a matching call that appeared later in the input, or a tool call as paired with an earlier output. Pair repair now respects wire order before preserving or synthesizing each side.
|
|
10
|
+
- Fixed adaptive-thinking Anthropic models omitting the interleaved-thinking beta on signature-enforcing proxies, which caused persisted interleaved assistant turns to fail on replay ([#6717](https://github.com/can1357/oh-my-pi/issues/6717)).
|
|
11
|
+
- Kimi Code now sends its session-stable prompt cache key on both supported transports: `prompt_cache_key` for OpenAI-compatible requests and `metadata.user_id` for Anthropic-compatible requests. Explicit keys survive side-channel session IDs, while `cacheRetention: "none"` still disables automatic affinity ([#6049](https://github.com/can1357/oh-my-pi/issues/6049)).
|
|
12
|
+
- Fresh encrypted auth-broker snapshot caches are revalidated within a short startup budget, so one-shot clients see newly imported or revoked credentials immediately when the broker is reachable while retaining cache fallback for transport and server failures.
|
|
13
|
+
- Fixed custom `anthropic-messages` endpoints dropping native web-search call/result blocks in the leaked-thinking wrapper, preserving signed continuation history in source order without carrying a preceding text signature onto later unsigned blocks ([#6703](https://github.com/can1357/oh-my-pi/issues/6703)).
|
|
14
|
+
|
|
15
|
+
## [17.1.4] - 2026-07-26
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- MiniMax Token Plan accounts now report quota in `omp usage`. `GET /v1/token_plan/remains` returns one bucket per plan quota, each carrying a rolling interval window and a weekly window, so `minimax-code` surfaces real remaining percentages instead of an empty report. A model the plan does not include comes back looking like an untouched quota; those buckets are dropped from the report and named in its metadata. The mainland id `minimax-code-cn` is untouched.
|
|
20
|
+
- OAuth logins now stamp `authorizedAt` (epoch ms of the interactive login) on the stored credential, and every refresh-persist path preserves it. Anthropic expires the whole OAuth grant family ~30 days after authorization regardless of refresh-token rotation (observed as `invalid_grant: "Refresh token expired"` on the latest rotated token, exactly 30 days after login, across four production accounts), so the login anchor is what makes re-login deadlines computable. Exported `ANTHROPIC_OAUTH_GRANT_TTL_MS` alongside the anthropic OAuth flow.
|
|
21
|
+
- Added `GET /v1/credentials/disabled` to the auth broker and `AuthBrokerClient.listDisabledCredentials`: disabled-credential tombstones (`DisabledCredentialSummary` — identity, verbatim disable cause, disable timestamp; never token material) so auto-disabled accounts stay visible to clients instead of silently vanishing from the snapshot. `AuthStorage.listDisabledCredentials` serves the same data locally from SQLite; clients of brokers predating the endpoint get an empty list (404 mapped, no error).
|
|
22
|
+
- Added `AuthStorage.revalidateCredentials()` and the optional `AuthCredentialStore.refreshSnapshot` hook: remote broker stores re-fetch `GET /v1/snapshot` on demand so callers pairing live per-credential data with stored identities (`omp usage`) never render against the up-to-an-hour-stale disk-cached snapshot; local SQLite stores are always current and only reload.
|
|
23
|
+
- Added an optional per-request `codexSseMaxAttempts` stream option to bound Codex SSE pre-response retries while preserving the six-attempt default when omitted.
|
|
24
|
+
- Fixed Cursor requests failing with `Connect error internal: Unable to parse image: ...` whenever the session history contained an image: `rootPromptMessagesJson` image parts now embed a `data:<mime>;base64,` URI instead of bare base64, matching the convention used by the OpenAI-completions provider ([#6564](https://github.com/can1357/oh-my-pi/pull/6564)).
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- Fixed OpenAI Responses native history replay sending output-only `status` fields back as input, preventing `input[N].status` failures in long-running sessions. ([#6513](https://github.com/can1357/oh-my-pi/pull/6513) by [@Ant39140](https://github.com/Ant39140))
|
|
29
|
+
- Cursor no longer discards a local tool result when the transport fails mid-execution. The provider waits for in-flight exec dispatches before pushing `done`, but the error path skipped that wait, so a handler decoded from the last chunk landed its result after the Agent had already finalized the call from the terminal error and cleared its buffer — losing the real outcome of a tool that may already have run side effects. Both exits now drain the same barrier.
|
|
30
|
+
- Cursor exec handlers returning the bare-result form no longer record a failed call as successful. When an SDK handler returns only a protocol result (no paired `toolResult`), the synthesized transcript entry was always `"Tool produced no transcript result"` with `isError: false`, even for a `rejected` or `error` result — so Cursor saw a failure while the rebuilt transcript showed success. The synthesized entry now derives its state and message from the result's own oneof variant — including MCP, where an application-level tool failure rides inside the `success` variant as `is_error` rather than as a separate variant.
|
|
31
|
+
- Fixed Cursor models silently failing to maintain the todo list. Cursor resolves its native `update_todos`/`read_todos` tools server-side, but the bridge looked for them under flattened `updateTodosToolCall`/`readTodosToolCall` properties, which a decoded `agent.v1.ToolCall` never has — the variant only arrives through the `tool` oneof — so no native todo call was ever recognized. The synthesized `todo` tool call was also emitted as locally runnable with a `{todos}` payload the local tool's schema rejects, so any update that did surface ended as a validation error and local todo state never followed Cursor's. Todo calls are now read from the oneof, both native todo blocks are marked as already-resolved, and local state is mirrored from the server's confirmed success snapshot (leaving state untouched on `UpdateTodosError`). `TODO_STATUS_CANCELLED` now maps to `abandoned` instead of reverting the task to `pending`.
|
|
32
|
+
- Hardened Cursor todo mirroring against partial `read_todos` responses: a read narrowed by `status_filter`/`id_filter`, or one returning fewer rows than the server's own `total_count`, is a subset rather than the list, and is no longer treated as authoritative. Previously such a response would have deleted every task it omitted.
|
|
33
|
+
- Fixed an empty `update_todos` response whose `total_count` is nonzero being mirrored as an authoritative clear, deleting every local task at once. The count-mismatch guard skipped empty responses entirely; only a matching zero count is a genuine clear now. An empty `read_todos` stays refused outright, since proto3 decodes an unset `total_count` as `0` and it cannot be told apart from a filtered read that matched nothing.
|
|
34
|
+
- Fixed a Cursor todo call being left unpaired when the completion frame carried no `tool_call` at all. `ToolCallCompletedUpdate.tool_call` is optional, but the block was already marked as server-resolved by the started frame, so nothing emitted a placeholder for it and every transcript rebuild stripped the interaction. It now settles as "nothing to mirror", the same as a refused snapshot.
|
|
35
|
+
- Fixed local Cursor exec calls (`read`/`write`/`grep`/`delete`/`bash`/`lsp`/MCP) vanishing from rebuilt transcripts when the tool produced no result. The assistant block is synthesized and marked server-resolved before the handler runs, so the three result-less paths — no handler installed, a handler returning nothing, and a thrown handler — left the call unpaired. Each now pairs a result carrying the same text the server receives.
|
|
36
|
+
- Fixed Cursor MCP tool calls being unrecognized on the wire. `ToolCall.tool` is a protobuf oneof, so a decoded message exposes the variant as `{ case, value }` and never as a flat `mcpToolCall` property — the same trap that made native todo calls invisible while hand-shaped fixtures kept passing. Both the streamed start and the completion arg merge now go through a shared selector.
|
|
37
|
+
- Fixed a streamed Cursor MCP block being named from `name` while its paired result used `toolName`, so the two disagreed whenever the server sent different values. Both now prefer `toolName`.
|
|
38
|
+
- Fixed the Cursor stream emitting `done` while a tool handler decoded from the final chunk was still running. Server messages are dispatched fire-and-forget so the socket keeps draining, but nothing waited for them: when an exec request, `turnEnded` and the stream close arrived in one chunk, the turn finished before the handler produced its result, and the result missed the buffer drain that pairs it with its call. In-flight dispatches are now awaited after the transport completes.
|
|
39
|
+
- Fixed a server-resolved Cursor todo call leaving its transcript block stuck pending: the synthetic completion was emitted under a freshly generated id instead of the streamed call id the interactive transcript filed the block under, so the card animated indefinitely. The settled call id is now handed to the sync handler.
|
|
40
|
+
- Fixed server-resolved Cursor todo blocks disappearing from rebuilt transcripts: nothing produced a `toolResult` for them, and `buildSessionContext` strips any `toolCall` left unpaired, so the interaction vanished on reload, branch switch, or transcript rebuild. The result the host builds is now persisted verbatim — it carries the `details.phases` the todo renderer rebuilds the list from, which a summary-only result would have replayed as `0 tasks`.
|
|
41
|
+
- Fixed a refused or failed Cursor todo call leaving its card animating forever. Only a successful snapshot settled the block, so a `read_todos` narrowed by a filter and a server `UpdateTodosError` both went unanswered — no `tool_execution_end`, and no `toolResult` to keep the block from being stripped on rebuild. Every completed native todo call now settles. A server error is carried through as a failed result rather than collapsed into the benign "nothing to mirror" case, which would have replayed the failure as a success.
|
|
42
|
+
- Hardened Cursor todo mirroring against snapshots whose rows collide on content. Cursor's wire model identifies todos by `id` and can represent two rows sharing the same text; the local list is keyed by content alone and the `todo` tool rejects a duplicate outright, so importing such a pair would leave every task-targeted `done`/`drop`/`rm` resolving to the first row and the second unreachable. The snapshot is now refused like any other that cannot be represented locally — local state is left untouched and the call still settles as a no-op.
|
|
43
|
+
- Hardened Cursor todo mirroring against ambiguous empty `read_todos` responses. `total_count` is a proto3 scalar, so an unset field decodes as `0` and is indistinguishable from a genuinely empty list; accepting `todos=[]` + `total_count=0` would clear every local task. Empty and mismatched reads are now refused — `update_todos` remains the authoritative clear path.
|
|
44
|
+
- Fixed refused Cursor todo results claiming `"No todo changes"`. A server-accepted `update_todos` can still be declined locally (content collision, etc.), so the persisted fallback now reads `"Todo snapshot not mirrored"` instead of implying the remote call changed nothing.
|
|
45
|
+
- Hardened Cursor todo mirroring against snapshots carrying unresolved `TodoItem.dependencies`. The wire model blocks a row behind other rows by `id`; the local list has no ids and no edges, so an imported dependent row files as plain `pending` and `nextActionableTask` then offers work the server considers blocked. Snapshots with an edge pointing at a row that is not yet `completed`/`abandoned` are now refused like any other that cannot be represented locally. Edges whose blockers already finished constrain nothing and still mirror.
|
|
46
|
+
- Extended the Cursor todo `total_count` mismatch guard to `update_todos`. A partial or size-limited merge response is as incomplete as a filtered read, but the check only applied to reads, so an update returning fewer rows than its own count was mirrored as the full list and deleted every task it omitted. An empty update still syncs — it remains the authoritative clear path, unlike an ambiguous empty read.
|
|
47
|
+
- Hardened Cursor todo mirroring against rows with empty `content`. `content` is a proto3 string, so a missing or default value arrives as `""`; the local list is keyed by content and rejects a falsy one before lookup, leaving the imported row unreachable to every task-targeted `done`/`drop`/`rm`. Such snapshots are now refused like any other that cannot be represented locally.
|
|
48
|
+
- Fixed a deterministic circular-import TDZ that crashed `packages/catalog`'s test process with `ReferenceError: Cannot access 'claudeCodeVersion' before initialization`: `registry/oauth/anthropic.ts` imported `claudeCodeVersion` from `providers/anthropic.ts`, which transitively pulls the registry back in (`providers/anthropic` → `stream` → `registry` → `registry/oauth/anthropic`), so the module-level `claude-code/${claudeCodeVersion}` bootstrap user-agent const read the binding while `providers/anthropic.ts` was still mid-initialization. `claudeCodeVersion` now lives in a zero-import leaf module (`providers/claude-code-fingerprint.ts`) that `providers/anthropic.ts`, `registry/oauth/anthropic.ts`, and `usage/claude.ts` all import from, removing the cycle at the source rather than deferring the read.
|
|
49
|
+
- Fixed a circular initialization between the Anthropic provider and OAuth registry that could throw before `claudeCodeVersion` was initialized when package tests or consumers loaded modules in parallel ([#6628](https://github.com/can1357/oh-my-pi/pull/6628) by [@anatoli-tsinovoy](https://github.com/anatoli-tsinovoy)).
|
|
50
|
+
- Stopped the account-level Codex `rate_limit.limit_reached` flag from being applied to individual chat windows. Codex reports one shared flag for the whole account, so a window with real headroom was marked `exhausted` because a different window (or a separate metered feature) was at its limit, which over-blocked sibling accounts during credential selection. Each window's status now reflects only its own usage
|
|
51
|
+
- Scoped Codex reactive backoff per meter: a `usage_limit_reached` from a Spark request no longer persists a block that ordinary chat requests honour, and the reverse. Blocks written before scoping used a shared scope meaning "block everything", so requests still honour it and reconciliation still heals it
|
|
52
|
+
- Implemented `scopeLimits` for the Codex ranking strategy so a request gates only on the windows it actually consumes: `-spark` models spend the Spark meter and every other model spends the 5h/weekly chat windows, instead of OR-ing every window and meter into one provider-wide block
|
|
53
|
+
- Fixed native Anthropic adaptive-only models (Opus 4.6+, Sonnet 4.6+, Fable/Mythos 5) keeping thinking ON when reasoning was meant to be off. `mapOptionsForApi` never consulted `disableReasoning` on the Anthropic branch, so a caller-side disable left adaptive thinking at full effort; and `disableThinkingIfToolChoiceForced` deleted `output_config.effort` alongside `thinking`, which for adaptive-only models silently re-enabled adaptive thinking (a bare omission defaults to adaptive-ON). Both paths now omit `thinking` and pin the lowest adaptive effort, so `disableReasoning` and forced `tool_choice` turns (e.g. the delivery reviewer's `report_delivery`) actually suppress reasoning instead of returning a thinking block with `end_turn` ([#6589](https://github.com/can1357/oh-my-pi/issues/6589)).
|
|
54
|
+
- Fixed Bedrock Converse dropping captured Claude thinking signatures when replaying application-inference-profile ARN models, restoring adaptive-thinking multi-turn conversations ([#6610](https://github.com/can1357/oh-my-pi/issues/6610)).
|
|
55
|
+
- Fixed the `alibaba-token-plan` login only supporting the international Singapore endpoint, which rejected China (Beijing) Token Plan `sk-sp-` keys with `401 invalid_api_key`. Login now selects a region (International / China (Beijing) / Custom), validates the key against that region's `/models` endpoint, and stores the chosen base URL in the credential so inference and discovery both target it ([#6682](https://github.com/can1357/oh-my-pi/issues/6682)).
|
|
56
|
+
- Fixed statusless provider capacity errors such as `no_capacity` and high-demand responses being treated as terminal instead of retryable. ([#6503](https://github.com/can1357/oh-my-pi/issues/6503))
|
|
57
|
+
- Fixed QwenCloud Token Plan quota reporting to call the current console usage RPC and document how to capture its optional Cookie during login.
|
|
58
|
+
- Fixed Cursor exec-channel MCP calls such as `web_search` omitting `toolCall` blocks when no interaction block arrives, which rendered their tool cards below the final assistant answer or dropped them on transcript replay. ([#6501](https://github.com/can1357/oh-my-pi/issues/6501))
|
|
59
|
+
- Fixed Claude scoped weekly limits (e.g. `Claude 7 Day (Fable)`) with `is_active: false` being dropped by the `/usage` parser, rendering as `not reported` in `omp usage` despite carrying real utilization. Live payloads mark only the currently binding limit active — an account pinned at a 100% Fable cap reports its 77% shared weekly row as inactive too — so `is_active` signals severity ranking, not bucket existence, and is now ignored. Exhaustion gating is unchanged: tier rows still hard-block only at confirmed 100% with a future reset.
|
|
60
|
+
- Fixed a TDZ crash (`Cannot access 'claudeCodeVersion' before initialization`) when `providers/anthropic` was the first module loaded: `providers/anthropic` → `stream` → `registry` → `registry/oauth/anthropic` circled back into the still-initializing provider module. The Claude Code fingerprint constants now live in the leaf module `providers/claude-code-fingerprint` (star re-exported from `providers/anthropic`, so import paths are unchanged).
|
|
61
|
+
|
|
5
62
|
## [17.1.3] - 2026-07-24
|
|
6
63
|
|
|
7
64
|
### Fixed
|
package/README.md
CHANGED
|
@@ -73,7 +73,7 @@ Unified LLM API with automatic model discovery, provider configuration, token an
|
|
|
73
73
|
- **Xiaomi MiMo** (requires `XIAOMI_API_KEY`)
|
|
74
74
|
- **ZenMux** (requires `ZENMUX_API_KEY`)
|
|
75
75
|
- **Qwen Portal** (supports `QWEN_OAUTH_TOKEN` or `QWEN_PORTAL_API_KEY`)
|
|
76
|
-
- **QwenCloud Token Plan** (supports `/login alibaba-token-plan`, `ALIBABA_TOKEN_PLAN_API_KEY`, or `BAILIAN_TOKEN_PLAN_API_KEY`; interactive login optionally stores a `home.qwencloud.com` Cookie request header for best-effort 5-hour and 7-day quota reporting)
|
|
76
|
+
- **QwenCloud Token Plan** (supports `/login alibaba-token-plan`, `ALIBABA_TOKEN_PLAN_API_KEY`, or `BAILIAN_TOKEN_PLAN_API_KEY`; interactive login first selects a region — International (Singapore, default), China (Beijing) for 百炼 Token Plan keys, or a custom base URL — since region keys are non-interchangeable, then optionally stores a `home.qwencloud.com` Cookie request header for best-effort 5-hour and 7-day quota reporting)
|
|
77
77
|
To enable quota reporting, sign in to the Token Plan dashboard, copy the `Cookie` request-header value from a `home.qwencloud.com` request in browser developer tools, and paste it at the second login prompt. Press Enter to skip; the Cookie is sensitive and session-lived, so rerun login when it expires.
|
|
78
78
|
- **Cloudflare AI Gateway** (requires `CLOUDFLARE_AI_GATEWAY_API_KEY` and provider-specific gateway base URL)
|
|
79
79
|
- **Ollama** (local OpenAI-compatible runtime; optional `OLLAMA_API_KEY`)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AuthCredential } from "../auth-storage.js";
|
|
1
|
+
import type { AuthCredential, DisabledCredentialSummary } from "../auth-storage.js";
|
|
2
2
|
import type { ClientUsageReportRequest, ClientUsageReportResponse, ClientUsageSummaryResponse, CredentialBlockRequest, CredentialBlockResponse, CredentialBlocksDeleteResponse, CredentialDisableResponse, CredentialRefreshResponse, CredentialUploadResponse, HealthzResponse, SnapshotResponse, SnapshotStreamEvent, UsageHistoryResponse, UsageResponse, UsageStaleResponse } from "./types.js";
|
|
3
3
|
export interface AuthBrokerClientOptions {
|
|
4
4
|
/** Base URL (e.g. `https://broker.tailnet:8765`). Trailing slashes are trimmed. */
|
|
@@ -74,6 +74,12 @@ export declare class AuthBrokerClient {
|
|
|
74
74
|
notifyUsageStale(signal?: AbortSignal): Promise<UsageStaleResponse>;
|
|
75
75
|
refreshCredential(id: number, signal?: AbortSignal): Promise<CredentialRefreshResponse>;
|
|
76
76
|
disableCredential(id: number, cause: string, signal?: AbortSignal): Promise<CredentialDisableResponse>;
|
|
77
|
+
/**
|
|
78
|
+
* Disabled-credential tombstones (identity + cause, no token material).
|
|
79
|
+
* Returns an empty list against brokers predating `GET
|
|
80
|
+
* /v1/credentials/disabled` (404).
|
|
81
|
+
*/
|
|
82
|
+
listDisabledCredentials(provider?: string, signal?: AbortSignal): Promise<DisabledCredentialSummary[]>;
|
|
77
83
|
uploadCredential(provider: string, credential: AuthCredential, signal?: AbortSignal): Promise<CredentialUploadResponse>;
|
|
78
84
|
upsertCredentialBlock(id: number, block: CredentialBlockRequest, signal?: AbortSignal): Promise<CredentialBlockResponse>;
|
|
79
85
|
deleteCredentialBlocks(id: number, signal?: AbortSignal): Promise<CredentialBlocksDeleteResponse>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AuthCredential, type AuthCredentialStore, type OAuthCredential, type StoredAuthCredential, type StoredCredentialBlock } from "../auth-storage.js";
|
|
1
|
+
import { type AuthCredential, type AuthCredentialStore, type DisabledCredentialSummary, type OAuthCredential, type StoredAuthCredential, type StoredCredentialBlock } from "../auth-storage.js";
|
|
2
2
|
import type { OAuthCredentials } from "../registry/oauth/types.js";
|
|
3
3
|
import type { Provider } from "../types.js";
|
|
4
4
|
import type { ObservedUsageEntry, UsageReport } from "../usage.js";
|
|
@@ -44,10 +44,13 @@ export declare class RemoteAuthCredentialStore implements AuthCredentialStore {
|
|
|
44
44
|
/** Re-hydrate the in-memory snapshot from the broker. */
|
|
45
45
|
refreshSnapshot(): Promise<SnapshotResponse>;
|
|
46
46
|
listAuthCredentials(provider?: string): StoredAuthCredential[];
|
|
47
|
+
/** Broker-backed disabled tombstones; empty against brokers predating the endpoint. */
|
|
48
|
+
listDisabledCredentials(provider?: string, signal?: AbortSignal): Promise<DisabledCredentialSummary[]>;
|
|
47
49
|
getCredentialBlock(credentialId: number, providerKey: string, blockScope: string): number | undefined;
|
|
48
50
|
getCredentialBlockReconcileAfter(credentialId: number, providerKey: string, blockScope: string): number | undefined;
|
|
49
51
|
listCredentialBlocks(credentialIds: readonly number[]): StoredCredentialBlock[];
|
|
50
52
|
upsertCredentialBlock(block: StoredCredentialBlock): void;
|
|
53
|
+
deleteCredentialBlock(_credentialId: number, _providerKey: string, _blockScope: string): void;
|
|
51
54
|
deleteCredentialBlocks(credentialId: number): void;
|
|
52
55
|
cleanExpiredCredentialBlocks(nowMs: number): void;
|
|
53
56
|
/**
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* clients use `access` tokens directly and call back to the broker when a
|
|
6
6
|
* credential expires or a 401 surfaces on a supposedly-fresh credential.
|
|
7
7
|
*/
|
|
8
|
-
import type { AuthCredential, AuthCredentialSnapshot, AuthCredentialSnapshotEntry, StoredCredentialBlock } from "../auth-storage.js";
|
|
8
|
+
import type { AuthCredential, AuthCredentialSnapshot, AuthCredentialSnapshotEntry, DisabledCredentialSummary, StoredCredentialBlock } from "../auth-storage.js";
|
|
9
9
|
import type { ClientUsageClientSummary, ClientUsageReport, UsageHistoryEntry, UsageReport } from "../usage.js";
|
|
10
10
|
/** GET /v1/healthz response body. */
|
|
11
11
|
export interface HealthzResponse {
|
|
@@ -66,6 +66,11 @@ export interface CredentialDisableRequest {
|
|
|
66
66
|
export interface CredentialDisableResponse {
|
|
67
67
|
ok: boolean;
|
|
68
68
|
}
|
|
69
|
+
/** GET /v1/credentials/disabled response body — tombstones of auto-disabled rows. */
|
|
70
|
+
export interface DisabledCredentialsResponse {
|
|
71
|
+
generatedAt: number;
|
|
72
|
+
disabled: DisabledCredentialSummary[];
|
|
73
|
+
}
|
|
69
74
|
/** POST /v1/credential/:id/block request body. */
|
|
70
75
|
export type CredentialBlockRequest = CredentialBlockSnapshot;
|
|
71
76
|
/** POST /v1/credential/:id/block response body. */
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ArkType schemas for the auth-broker wire protocol.
|
|
3
|
+
*
|
|
4
|
+
* Shared between the server (validates inbound request bodies) and the client
|
|
5
|
+
* (validates responses from the broker). Schemas mirror the TypeScript types
|
|
6
|
+
* in `./types.ts` 1:1; the types remain the source of truth for static typing,
|
|
7
|
+
* and `Type` is asserted-compatible with them where possible.
|
|
8
|
+
*
|
|
9
|
+
* Envelope and fixed-shape schemas use `"+": "reject"` so unknown keys are
|
|
10
|
+
* rejected — the previous implementation used a hand-rolled `hasOnlyFields`
|
|
11
|
+
* allowlist for the same effect. The OAuth credential schema is the deliberate
|
|
12
|
+
* exception (standard type keeps extra keys): it preserves provider-specific extension fields so
|
|
13
|
+
* they round-trip through the broker instead of being dropped (see below).
|
|
14
|
+
*/
|
|
15
|
+
import { type Type } from "arktype";
|
|
16
|
+
import { type ApiKeyCredential, type AuthCredential, type AuthCredentialSnapshotEntry, type DisabledCredentialSummary, type OAuthCredential, type RemoteOAuthCredential, type SnapshotCredential } from "../auth-storage.js";
|
|
17
|
+
import type { ClientUsageReportRequest, ClientUsageReportResponse, ClientUsageSummaryResponse, CredentialBlockRequest, CredentialBlockResponse, CredentialBlockSnapshot, CredentialBlocksDeleteResponse, CredentialDisableResponse, CredentialRefreshResponse, CredentialUploadRequest, CredentialUploadResponse, DisabledCredentialsResponse, HealthzResponse, RefresherSchedule, SnapshotEntry, SnapshotResponse, SnapshotStreamEntryEvent, SnapshotStreamEvent, SnapshotStreamRemovedEvent, SnapshotStreamSnapshotEvent, UsageHistoryResponse, UsageResponse, UsageStaleResponse } from "./types.js";
|
|
18
|
+
export interface AuthBrokerWireSchemas {
|
|
19
|
+
readonly oauthCredentialSchema: Type<OAuthCredential>;
|
|
20
|
+
readonly remoteOauthCredentialSchema: Type<RemoteOAuthCredential>;
|
|
21
|
+
readonly apiKeyCredentialSchema: Type<ApiKeyCredential>;
|
|
22
|
+
readonly writableAuthCredentialSchema: Type<AuthCredential>;
|
|
23
|
+
readonly snapshotCredentialSchema: Type<SnapshotCredential>;
|
|
24
|
+
readonly credentialSnapshotEntrySchema: Type<AuthCredentialSnapshotEntry>;
|
|
25
|
+
readonly credentialBlockSnapshotSchema: Type<CredentialBlockSnapshot>;
|
|
26
|
+
readonly snapshotEntrySchema: Type<SnapshotEntry>;
|
|
27
|
+
readonly refresherScheduleSchema: Type<RefresherSchedule>;
|
|
28
|
+
readonly snapshotResponseSchema: Type<SnapshotResponse>;
|
|
29
|
+
readonly snapshotStreamSnapshotEventSchema: Type<SnapshotStreamSnapshotEvent>;
|
|
30
|
+
readonly snapshotStreamEntryEventSchema: Type<SnapshotStreamEntryEvent>;
|
|
31
|
+
readonly snapshotStreamRemovedEventSchema: Type<SnapshotStreamRemovedEvent>;
|
|
32
|
+
readonly snapshotStreamEventSchema: Type<SnapshotStreamEvent>;
|
|
33
|
+
readonly healthzResponseSchema: Type<HealthzResponse>;
|
|
34
|
+
readonly usageResponseSchema: Type<UsageResponse>;
|
|
35
|
+
readonly usageHistoryResponseSchema: Type<UsageHistoryResponse>;
|
|
36
|
+
readonly clientUsageReportRequestSchema: Type<ClientUsageReportRequest>;
|
|
37
|
+
readonly clientUsageReportResponseSchema: Type<ClientUsageReportResponse>;
|
|
38
|
+
readonly clientUsageSummaryResponseSchema: Type<ClientUsageSummaryResponse>;
|
|
39
|
+
readonly credentialRefreshResponseSchema: Type<CredentialRefreshResponse>;
|
|
40
|
+
readonly credentialDisableRequestSchema: Type<{
|
|
41
|
+
cause?: string;
|
|
42
|
+
}>;
|
|
43
|
+
readonly credentialDisableResponseSchema: Type<CredentialDisableResponse>;
|
|
44
|
+
readonly disabledCredentialSummarySchema: Type<DisabledCredentialSummary>;
|
|
45
|
+
readonly disabledCredentialsResponseSchema: Type<DisabledCredentialsResponse>;
|
|
46
|
+
readonly credentialBlockRequestSchema: Type<CredentialBlockRequest>;
|
|
47
|
+
readonly credentialBlockResponseSchema: Type<CredentialBlockResponse>;
|
|
48
|
+
readonly credentialBlocksDeleteResponseSchema: Type<CredentialBlocksDeleteResponse>;
|
|
49
|
+
readonly usageStaleResponseSchema: Type<UsageStaleResponse>;
|
|
50
|
+
readonly credentialUploadRequestSchema: Type<CredentialUploadRequest>;
|
|
51
|
+
readonly credentialUploadResponseSchema: Type<CredentialUploadResponse>;
|
|
52
|
+
}
|
|
53
|
+
export declare function getAuthBrokerWireSchemas(): AuthBrokerWireSchemas;
|