@hilbras/omnihilbras 1.71.0 → 1.75.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,165 @@
1
+ import { type HttpTransport } from '../transport.js';
2
+ import type { ChatChunk, ChatRequest, ChatResponse, Model, ProviderAdapter, ProviderCapabilities, ProviderCredential, ProviderHealth, ProviderRequestContext } from '../types.js';
3
+ /**
4
+ * Claude Code — an Anthropic subscription reached by OAuth, not an Anthropic API key.
5
+ *
6
+ * ## Why this is a separate provider from `anthropic`
7
+ *
8
+ * `api.anthropic.com` with an `x-api-key` is metered per token and sold separately from a Claude
9
+ * subscription. A Claude Code credential is an OAuth grant for `user:inference`, carried as a bearer
10
+ * token. Both reach the same `/v1/messages` endpoint, but they are different accounts with different
11
+ * billing, so they get different provider ids and different cards — the same reasoning as `kimi` versus
12
+ * `kimi-code`.
13
+ *
14
+ * ## What was verified, and what was taken on trust
15
+ *
16
+ * ```
17
+ * POST https://api.anthropic.com/v1/oauth/token -> 400 {"type":"error","error":{"type":"invalid_request_error","message":"Unsupported grant_type: None"}}
18
+ * GET https://claude.ai/oauth/authorize -> 403 "Just a moment..." (Cloudflare interstitial)
19
+ * POST https://api.anthropic.com/v1/messages -> 401 x-api-key header is required
20
+ * ```
21
+ *
22
+ * The 400 and the 401 are the useful ones: a real service answering with a *typed refusal* rather than
23
+ * a 404. The `authorize` endpoint returning a Cloudflare challenge is the reason this flow **must** be a
24
+ * browser redirect — there is no API to call for an authorization code, and a server-side fetch of that
25
+ * URL would receive an HTML challenge page rather than a code.
26
+ *
27
+ * The client id is Anthropic's own published value, copied rather than registered. A wrong one fails at
28
+ * the first exchange with `invalid_grant`, which is visible and safe.
29
+ *
30
+ * ## The risk, stated once and not repeated as a warning on every line
31
+ *
32
+ * Anthropic's consumer terms do not permit using a Claude subscription for third-party API access. 9router
33
+ * ships this provider with `deprecated: true` and a `RISK_NOTICE`. The operator decides; this file's job is
34
+ * to be honest about what the credential is rather than to editorialise on every line of it.
35
+ */
36
+ export declare const CLAUDE_CODE: {
37
+ /** The API host, which serves both the token exchange and `/v1/messages`. */
38
+ readonly server: "https://api.anthropic.com";
39
+ /** The authorization host, which is a different origin and answers through a browser challenge. */
40
+ readonly authorizeOrigin: "https://claude.ai";
41
+ /**
42
+ * Anthropic's public Claude Code client id.
43
+ *
44
+ * Copied from Anthropic's own published integrations rather than registered here, because the token
45
+ * endpoint is bound to it and an unregistered id is refused with `invalid_grant`.
46
+ */
47
+ readonly clientId: "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
48
+ readonly authorizePath: "/oauth/authorize";
49
+ readonly tokenPath: "/v1/oauth/token";
50
+ readonly messagesPath: "/v1/messages";
51
+ /** Scoped to inference and profile only — **not** `org:create_api_key`, which would mint API keys. */
52
+ readonly scopes: readonly ["org:create_api_key", "user:profile", "user:inference"];
53
+ readonly grantType: "authorization_code";
54
+ readonly refreshGrantType: "refresh_token";
55
+ readonly apiVersion: "2023-06-01";
56
+ };
57
+ export declare const claudeCodeProviderId = "claude-code";
58
+ /**
59
+ * The callback path a sign-in returns to.
60
+ *
61
+ * **Declared here but owned by the gateway.** `apps/gateway/src/oauth.ts` re-exports its own copy
62
+ * under the same name and is the authority the route table and the cross-site exemption both read.
63
+ * This value is the one the adapter's own docs and `exchangeClaudeCodeCode` describe, and the two
64
+ * must agree or a redirect lands on a path nothing serves. Cline's callback is declared the same
65
+ * way for the same reason: a path is a gateway decision, and a provider module must not be a second
66
+ * place that decides one.
67
+ */
68
+ export declare const claudeCodeCallbackPath = "/v1/oauth/claude-code/callback";
69
+ export type ClaudeCodeAdapterOptions = {
70
+ transport?: HttpTransport;
71
+ timeoutMs?: number;
72
+ onTokensRefreshed?: (credential: ProviderCredential) => void | Promise<void>;
73
+ now?: () => number;
74
+ };
75
+ export declare class ClaudeCodeAdapter implements ProviderAdapter {
76
+ readonly id = "claude-code";
77
+ readonly name = "Claude Code";
78
+ readonly capabilities: ProviderCapabilities;
79
+ private readonly baseUrl;
80
+ private readonly transport;
81
+ private readonly onTokensRefreshed?;
82
+ private readonly now;
83
+ private readonly headers;
84
+ /** Renewed credentials keyed by the access token they replaced. */
85
+ private readonly renewed;
86
+ constructor(options?: ClaudeCodeAdapterOptions);
87
+ /**
88
+ * The catalog, from the models endpoint rather than a list written here.
89
+ *
90
+ * **A hardcoded model list is a claim that goes stale silently**, and this provider has an obvious
91
+ * temptation: 9router names five ids, one of which (`claude-fable-5`) could not be confirmed against the
92
+ * API. Asking Anthropic is the only answer that is current when it is read.
93
+ */
94
+ listModels(context?: ProviderRequestContext): Promise<Model[]>;
95
+ chat(request: ChatRequest, context?: ProviderRequestContext): Promise<ChatResponse>;
96
+ streamChat(request: ChatRequest, context?: ProviderRequestContext): AsyncIterable<ChatChunk>;
97
+ /**
98
+ * Reads `/v1/models`, which is free and never bills.
99
+ *
100
+ * A health check that spends money would be a real cost on every sweep — and a check that launches a
101
+ * browser was a defect already fixed in the credential-lifecycle work. A free authenticated read is both.
102
+ */
103
+ healthCheck(context?: ProviderRequestContext): Promise<ProviderHealth>;
104
+ /** The token, renewed without asking the user to sign in again. */
105
+ private credential;
106
+ private url;
107
+ /**
108
+ * An OAuth grant goes in `Authorization: Bearer`, which is the header Anthropic reads it from.
109
+ *
110
+ * `x-api-key` is accepted too, so the same card works for someone who obtained a key by another route —
111
+ * but the OAuth path is the one this adapter is for, and it is the one the credential decides.
112
+ */
113
+ private requestHeaders;
114
+ private toRequestBody;
115
+ private toChatResponse;
116
+ }
117
+ /**
118
+ * The URL the user opens, with a PKCE challenge.
119
+ *
120
+ * The verifier is supplied rather than minted here so the caller can keep it: a PKCE flow whose verifier
121
+ * does not survive until the callback cannot exchange its own code. `generatePkcePair` produces one.
122
+ *
123
+ * `code=true` is what tells Claude Code to return the code on the callback rather than running a CLI — it
124
+ * is a request for a redirect we can read, and omitting it produces a page with no code on it.
125
+ */
126
+ export declare function claudeCodeAuthorizeUrl(input: {
127
+ redirectUri: string;
128
+ state: string;
129
+ codeChallenge: string;
130
+ }): string;
131
+ /**
132
+ * Exchanges an authorization code for tokens.
133
+ *
134
+ * Anthropic's callback puts the code in the query and repeats the state after a `#`, and 9router's client
135
+ * splits on that separator before exchanging. Both halves are handled here, because the alternative is an
136
+ * exchange rejected with `invalid_grant` for a code that was correct.
137
+ *
138
+ * The 4xx is read for `error_description` — a wrong `state` and a wrong `code_verifier` both answer 400 and
139
+ * mean different things to the user — so the transport flag is used rather than a generic refusal.
140
+ */
141
+ export declare function exchangeClaudeCodeCode(input: {
142
+ code: string;
143
+ state?: string;
144
+ codeVerifier: string;
145
+ redirectUri: string;
146
+ transport?: HttpTransport;
147
+ signal?: AbortSignal;
148
+ }): Promise<ProviderCredential>;
149
+ /**
150
+ * Splits `code#state`, which is what Claude Code's callback answers with.
151
+ *
152
+ * The `#` half is the state Anthropic echoed, and it is checked against the one we sent. A crossed state
153
+ * means the code belongs to a different sign-in, so it is refused rather than exchanged.
154
+ */
155
+ export declare function splitCallbackFragment(raw: string, expectedState?: string): {
156
+ code: string;
157
+ state?: string;
158
+ };
159
+ /**
160
+ * Whether the credential is definitely expired. Three answers, because the third is the load-bearing one:
161
+ * `true` is definitely expired, `false` is definitely not, and `undefined` means *this adapter cannot say*
162
+ * — so the gateway asks the provider rather than ejecting a working connection.
163
+ */
164
+ export declare function claudeCodeCredentialExpired(credential: ProviderCredential | undefined, now: number): boolean | undefined;
165
+ //# sourceMappingURL=claude-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/adapters/claude-code.ts"],"names":[],"mappings":"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"}