@antseed/provider-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # @antseed/provider-core
2
+
3
+ Shared infrastructure for building Antseed provider plugins. Handles HTTP relaying, authentication, token management, and model validation so plugin authors can focus on provider-specific logic.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @antseed/provider-core
9
+ ```
10
+
11
+ Peer dependency: `@antseed/node >= 0.1.0`
12
+
13
+ ## Key Exports
14
+
15
+ ### BaseProvider
16
+
17
+ Implements the `Provider` interface with built-in HTTP relay support. Most provider plugins use this as their foundation.
18
+
19
+ ```ts
20
+ import { BaseProvider, StaticTokenProvider } from '@antseed/provider-core';
21
+
22
+ const provider = new BaseProvider({
23
+ name: 'my-provider',
24
+ models: ['model-a', 'model-b'],
25
+ pricing: { defaults: { inputUsdPerMillion: 10, outputUsdPerMillion: 10 } },
26
+ relay: {
27
+ baseUrl: 'https://api.example.com',
28
+ authHeaderName: 'Authorization',
29
+ authHeaderValue: '',
30
+ tokenProvider: new StaticTokenProvider('Bearer sk-...'),
31
+ maxConcurrency: 10,
32
+ allowedModels: ['model-a', 'model-b'],
33
+ },
34
+ });
35
+ ```
36
+
37
+ ### Token Providers
38
+
39
+ - **`StaticTokenProvider`** -- Wraps a static API key with no refresh logic.
40
+ - **`OAuthTokenProvider`** -- Manages OAuth access/refresh token pairs with automatic renewal.
41
+ - **`createTokenProvider()`** -- Factory that creates the right provider based on auth type.
42
+
43
+ ### Utilities
44
+
45
+ - **`swapAuthHeader()`** -- Injects/replaces authentication headers on outgoing requests.
46
+ - **`validateRequestModel()`** -- Validates request body `model` field against an allow-list.
47
+ - **`KNOWN_AUTH_HEADERS`** -- Standard auth header names (x-api-key, Authorization, etc.).
48
+
49
+ ### HttpRelay
50
+
51
+ Low-level HTTP relay with concurrency control, SSE streaming support, and model validation. Used internally by `BaseProvider`.
52
+
53
+ ## Usage in Plugins
54
+
55
+ ```ts
56
+ import type { AntseedProviderPlugin } from '@antseed/node';
57
+ import { BaseProvider, StaticTokenProvider } from '@antseed/provider-core';
58
+
59
+ const plugin: AntseedProviderPlugin = {
60
+ name: 'my-provider',
61
+ displayName: 'My Provider',
62
+ version: '0.1.0',
63
+ type: 'provider',
64
+ description: 'My custom provider',
65
+ configSchema: [
66
+ { key: 'API_KEY', label: 'API Key', type: 'secret', required: true, description: 'API key' },
67
+ ],
68
+ createProvider(config) {
69
+ return new BaseProvider({
70
+ name: 'my-provider',
71
+ models: ['default-model'],
72
+ pricing: { defaults: { inputUsdPerMillion: 10, outputUsdPerMillion: 10 } },
73
+ relay: {
74
+ baseUrl: 'https://api.example.com',
75
+ authHeaderName: 'Authorization',
76
+ authHeaderValue: '',
77
+ tokenProvider: new StaticTokenProvider(`Bearer ${config['API_KEY']}`),
78
+ maxConcurrency: 10,
79
+ allowedModels: ['default-model'],
80
+ },
81
+ });
82
+ },
83
+ };
84
+
85
+ export default plugin;
86
+ ```
@@ -0,0 +1,19 @@
1
+ import type { SerializedHttpRequest } from '@antseed/node';
2
+ /** Set of all known auth header names (lowercase). */
3
+ export declare const KNOWN_AUTH_HEADERS: Set<string>;
4
+ /**
5
+ * Strips all known auth headers and injects the seller's auth.
6
+ * Returns a NEW object (no mutation of the original).
7
+ */
8
+ export declare function swapAuthHeader(request: SerializedHttpRequest, config: {
9
+ authHeaderName: string;
10
+ authHeaderValue: string;
11
+ extraHeaders?: Record<string, string>;
12
+ }): SerializedHttpRequest;
13
+ /**
14
+ * Validate request against allowed models.
15
+ * Parses JSON body and enforces strict top-level `"model"` allow-list.
16
+ * Returns null if ok, error string if rejected.
17
+ */
18
+ export declare function validateRequestModel(request: SerializedHttpRequest, allowedModels: string[]): string | null;
19
+ //# sourceMappingURL=auth-swap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-swap.d.ts","sourceRoot":"","sources":["../src/auth-swap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE3D,sDAAsD;AACtD,eAAO,MAAM,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAEzC,CAAC;AAEH;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACjG,qBAAqB,CAqCvB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,qBAAqB,EAC9B,aAAa,EAAE,MAAM,EAAE,GACtB,MAAM,GAAG,IAAI,CA2Bf"}
@@ -0,0 +1,73 @@
1
+ /** Set of all known auth header names (lowercase). */
2
+ export const KNOWN_AUTH_HEADERS = new Set([
3
+ 'authorization', 'x-api-key', 'x-goog-api-key',
4
+ ]);
5
+ /**
6
+ * Strips all known auth headers and injects the seller's auth.
7
+ * Returns a NEW object (no mutation of the original).
8
+ */
9
+ export function swapAuthHeader(request, config) {
10
+ const newHeaders = {};
11
+ for (const [key, value] of Object.entries(request.headers)) {
12
+ if (!KNOWN_AUTH_HEADERS.has(key.toLowerCase())) {
13
+ newHeaders[key] = value;
14
+ }
15
+ }
16
+ newHeaders[config.authHeaderName] = config.authHeaderValue;
17
+ // Inject any extra headers (e.g. anthropic-beta for OAuth).
18
+ // For anthropic-beta, merge with existing values (comma-separated)
19
+ // so the buyer's beta flags (e.g. context-management) are preserved.
20
+ if (config.extraHeaders) {
21
+ for (const [key, value] of Object.entries(config.extraHeaders)) {
22
+ const lower = key.toLowerCase();
23
+ if (lower === 'anthropic-beta' && newHeaders[key]) {
24
+ // Merge: deduplicate comma-separated beta flags
25
+ const existing = new Set(newHeaders[key].split(',').map((s) => s.trim()));
26
+ for (const flag of value.split(',').map((s) => s.trim())) {
27
+ existing.add(flag);
28
+ }
29
+ newHeaders[key] = [...existing].join(',');
30
+ }
31
+ else {
32
+ newHeaders[key] = value;
33
+ }
34
+ }
35
+ }
36
+ return {
37
+ requestId: request.requestId,
38
+ method: request.method,
39
+ path: request.path,
40
+ headers: newHeaders,
41
+ body: request.body,
42
+ };
43
+ }
44
+ /**
45
+ * Validate request against allowed models.
46
+ * Parses JSON body and enforces strict top-level `"model"` allow-list.
47
+ * Returns null if ok, error string if rejected.
48
+ */
49
+ export function validateRequestModel(request, allowedModels) {
50
+ // If allowedModels is empty, allow everything
51
+ if (allowedModels.length === 0) {
52
+ return null;
53
+ }
54
+ let payload;
55
+ try {
56
+ payload = JSON.parse(new TextDecoder().decode(request.body));
57
+ }
58
+ catch {
59
+ return "Invalid JSON request body";
60
+ }
61
+ if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
62
+ return 'Request body must be a JSON object containing a "model" field';
63
+ }
64
+ const model = payload["model"];
65
+ if (typeof model !== "string" || model.trim() === "") {
66
+ return 'Request is missing a valid "model" field';
67
+ }
68
+ if (!allowedModels.includes(model)) {
69
+ return `Model "${model}" is not in the allowed list`;
70
+ }
71
+ return null;
72
+ }
73
+ //# sourceMappingURL=auth-swap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-swap.js","sourceRoot":"","sources":["../src/auth-swap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { Provider, SerializedHttpRequest, SerializedHttpResponse } from '@antseed/node';
2
+ import { type RelayConfig } from './http-relay.js';
3
+ export interface BaseProviderConfig {
4
+ name: string;
5
+ models: string[];
6
+ pricing: Provider['pricing'];
7
+ relay: RelayConfig;
8
+ }
9
+ /**
10
+ * Convenience base class that wires HttpRelay to the Provider interface.
11
+ * Pattern adapted from provider-anthropic's AnthropicProvider.
12
+ */
13
+ export declare class BaseProvider implements Provider {
14
+ readonly name: string;
15
+ readonly models: string[];
16
+ readonly pricing: Provider['pricing'];
17
+ readonly maxConcurrency: number;
18
+ private readonly _relay;
19
+ private _activeCount;
20
+ private readonly _pending;
21
+ constructor(config: BaseProviderConfig);
22
+ private _resolvePending;
23
+ init(): Promise<void>;
24
+ handleRequest(req: SerializedHttpRequest): Promise<SerializedHttpResponse>;
25
+ getCapacity(): {
26
+ current: number;
27
+ max: number;
28
+ };
29
+ }
30
+ //# sourceMappingURL=base-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-provider.d.ts","sourceRoot":"","sources":["../src/base-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,qBAAqB,EAAE,sBAAsB,EAA+B,MAAM,eAAe,CAAC;AAC1H,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC7B,KAAK,EAAE,WAAW,CAAC;CACpB;AAED;;;GAGG;AACH,qBAAa,YAAa,YAAW,QAAQ;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAEhC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,YAAY,CAAK;IAEzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAGrB;gBAEQ,MAAM,EAAE,kBAAkB;IAgBtC,OAAO,CAAC,eAAe;IAQjB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrB,aAAa,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAmBhF,WAAW,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;CAMhD"}
@@ -0,0 +1,65 @@
1
+ import { HttpRelay } from './http-relay.js';
2
+ /**
3
+ * Convenience base class that wires HttpRelay to the Provider interface.
4
+ * Pattern adapted from provider-anthropic's AnthropicProvider.
5
+ */
6
+ export class BaseProvider {
7
+ name;
8
+ models;
9
+ pricing;
10
+ maxConcurrency;
11
+ _relay;
12
+ _activeCount = 0;
13
+ _pending = new Map();
14
+ constructor(config) {
15
+ this.name = config.name;
16
+ this.models = config.models;
17
+ this.pricing = config.pricing;
18
+ this.maxConcurrency = config.relay.maxConcurrency;
19
+ this._relay = new HttpRelay(config.relay, {
20
+ onResponse: (response) => {
21
+ this._resolvePending(response.requestId, response);
22
+ },
23
+ onResponseChunk: (_chunk) => {
24
+ // Chunks are accumulated by HttpRelay into a complete response
25
+ },
26
+ });
27
+ }
28
+ _resolvePending(requestId, response) {
29
+ const entry = this._pending.get(requestId);
30
+ if (entry) {
31
+ this._pending.delete(requestId);
32
+ entry.resolve(response);
33
+ }
34
+ }
35
+ async init() {
36
+ if (this._relay['_config'].tokenProvider) {
37
+ await this._relay['_config'].tokenProvider.getToken();
38
+ }
39
+ }
40
+ async handleRequest(req) {
41
+ this._activeCount++;
42
+ try {
43
+ const responsePromise = new Promise((resolve, reject) => {
44
+ this._pending.set(req.requestId, { resolve, reject });
45
+ });
46
+ // Fire the relay (it calls onResponse when done)
47
+ await this._relay.handleRequest(req);
48
+ return await responsePromise;
49
+ }
50
+ catch (err) {
51
+ this._pending.delete(req.requestId);
52
+ throw err;
53
+ }
54
+ finally {
55
+ this._activeCount--;
56
+ }
57
+ }
58
+ getCapacity() {
59
+ return {
60
+ current: this._activeCount,
61
+ max: this.maxConcurrency,
62
+ };
63
+ }
64
+ }
65
+ //# sourceMappingURL=base-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-provider.js","sourceRoot":"","sources":["../src/base-provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAoB,MAAM,iBAAiB,CAAC;AAS9D;;;GAGG;AACH,MAAM,OAAO,YAAY;IACd,IAAI,CAAS;IACb,MAAM,CAAW;IACjB,OAAO,CAAsB;IAC7B,cAAc,CAAS;IAEf,MAAM,CAAY;IAC3B,YAAY,GAAG,CAAC,CAAC;IAER,QAAQ,GAAG,IAAI,GAAG,EAGhC,CAAC;IAEJ,YAAY,MAA0B;QACpC,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC;QAElD,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE;YACxC,UAAU,EAAE,CAAC,QAAgC,EAAE,EAAE;gBAC/C,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YACrD,CAAC;YACD,eAAe,EAAE,CAAC,MAAmC,EAAE,EAAE;gBACvD,+DAA+D;YACjE,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAEO,eAAe,CAAC,SAAiB,EAAE,QAAgC;QACzE,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAChC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,aAAa,EAAE,CAAC;YACzC,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC;QACxD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,GAA0B;QAC5C,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,eAAe,GAAG,IAAI,OAAO,CAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC9E,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACxD,CAAC,CAAC,CAAC;YAEH,iDAAiD;YACjD,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YAErC,OAAO,MAAM,eAAe,CAAC;QAC/B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACpC,MAAM,GAAG,CAAC;QACZ,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;IAED,WAAW;QACT,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,YAAY;YAC1B,GAAG,EAAE,IAAI,CAAC,cAAc;SACzB,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,26 @@
1
+ import type { TokenProvider } from '@antseed/node';
2
+ import type { SerializedHttpRequest, SerializedHttpResponse, SerializedHttpResponseChunk } from '@antseed/node';
3
+ export interface RelayConfig {
4
+ baseUrl: string;
5
+ authHeaderName: string;
6
+ authHeaderValue: string;
7
+ tokenProvider?: TokenProvider;
8
+ extraHeaders?: Record<string, string>;
9
+ maxConcurrency: number;
10
+ allowedModels: string[];
11
+ timeoutMs?: number;
12
+ }
13
+ export interface RelayCallbacks {
14
+ onResponse: (response: SerializedHttpResponse) => void;
15
+ onResponseChunk?: (chunk: SerializedHttpResponseChunk) => void;
16
+ }
17
+ export declare class HttpRelay {
18
+ private readonly _config;
19
+ private readonly _callbacks;
20
+ private _activeCount;
21
+ constructor(config: RelayConfig, callbacks: RelayCallbacks);
22
+ getActiveCount(): number;
23
+ private _sendError;
24
+ handleRequest(request: SerializedHttpRequest): Promise<void>;
25
+ }
26
+ //# sourceMappingURL=http-relay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-relay.d.ts","sourceRoot":"","sources":["../src/http-relay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC;AAchH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,CAAC,QAAQ,EAAE,sBAAsB,KAAK,IAAI,CAAC;IACvD,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,2BAA2B,KAAK,IAAI,CAAC;CAChE;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiB;IAC5C,OAAO,CAAC,YAAY,CAAK;gBAEb,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc;IAK1D,cAAc,IAAI,MAAM;IAIxB,OAAO,CAAC,UAAU;IASZ,aAAa,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;CAoInE"}
@@ -0,0 +1,153 @@
1
+ import { swapAuthHeader, validateRequestModel } from './auth-swap.js';
2
+ /** Hop-by-hop headers that must not be forwarded. */
3
+ const HOP_BY_HOP_HEADERS = new Set([
4
+ 'connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization',
5
+ 'te', 'trailers', 'transfer-encoding', 'upgrade',
6
+ ]);
7
+ /** Internal headers used only within Antseed routing. */
8
+ const INTERNAL_HEADERS = new Set([
9
+ 'x-antseed-provider',
10
+ ]);
11
+ export class HttpRelay {
12
+ _config;
13
+ _callbacks;
14
+ _activeCount = 0;
15
+ constructor(config, callbacks) {
16
+ this._config = config;
17
+ this._callbacks = callbacks;
18
+ }
19
+ getActiveCount() {
20
+ return this._activeCount;
21
+ }
22
+ _sendError(requestId, statusCode, error) {
23
+ this._callbacks.onResponse({
24
+ requestId,
25
+ statusCode,
26
+ headers: { 'content-type': 'application/json' },
27
+ body: new TextEncoder().encode(JSON.stringify({ error })),
28
+ });
29
+ }
30
+ async handleRequest(request) {
31
+ // Validate model against allowedModels
32
+ const validationError = validateRequestModel(request, this._config.allowedModels);
33
+ if (validationError) {
34
+ this._sendError(request.requestId, 403, validationError);
35
+ return;
36
+ }
37
+ // Check concurrency
38
+ if (this._activeCount >= this._config.maxConcurrency) {
39
+ this._sendError(request.requestId, 429, 'Max concurrency reached');
40
+ return;
41
+ }
42
+ // Increment active count
43
+ this._activeCount++;
44
+ try {
45
+ // Resolve dynamic auth token if provider uses OAuth / keychain
46
+ let effectiveConfig = {
47
+ authHeaderName: this._config.authHeaderName,
48
+ authHeaderValue: this._config.authHeaderValue,
49
+ extraHeaders: this._config.extraHeaders,
50
+ };
51
+ if (this._config.tokenProvider) {
52
+ const freshToken = await this._config.tokenProvider.getToken();
53
+ // Preserve Bearer prefix for OAuth providers that use Authorization header
54
+ const isBearer = this._config.authHeaderName === 'authorization';
55
+ const headerValue = isBearer ? `Bearer ${freshToken}` : freshToken;
56
+ effectiveConfig = { ...effectiveConfig, authHeaderValue: headerValue };
57
+ }
58
+ // Swap auth headers
59
+ const swappedRequest = swapAuthHeader(request, effectiveConfig);
60
+ // Build upstream URL
61
+ const base = this._config.baseUrl.replace(/\/+$/, '');
62
+ const path = request.path.startsWith('/') ? request.path : `/${request.path}`;
63
+ const url = `${base}${path}`;
64
+ // Build fetch headers, stripping hop-by-hop
65
+ const fetchHeaders = {};
66
+ for (const [key, value] of Object.entries(swappedRequest.headers)) {
67
+ const lower = key.toLowerCase();
68
+ if (!HOP_BY_HOP_HEADERS.has(lower) && !INTERNAL_HEADERS.has(lower) && lower !== 'host' && lower !== 'content-length' && lower !== 'accept-encoding') {
69
+ fetchHeaders[key] = value;
70
+ }
71
+ }
72
+ const timeoutMs = this._config.timeoutMs ?? 120_000;
73
+ const controller = new AbortController();
74
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
75
+ let fetchResponse;
76
+ try {
77
+ fetchResponse = await fetch(url, {
78
+ method: swappedRequest.method,
79
+ headers: fetchHeaders,
80
+ body: swappedRequest.method !== 'GET' && swappedRequest.method !== 'HEAD'
81
+ ? Buffer.from(swappedRequest.body)
82
+ : undefined,
83
+ signal: controller.signal,
84
+ });
85
+ }
86
+ finally {
87
+ clearTimeout(timeout);
88
+ }
89
+ const contentType = fetchResponse.headers.get('content-type') ?? '';
90
+ const isSSE = contentType.includes('text/event-stream');
91
+ // Build response headers, stripping hop-by-hop and encoding headers.
92
+ // Node.js fetch auto-decompresses gzip/br responses, so we must strip
93
+ // content-encoding to prevent the client from double-decompressing.
94
+ const responseHeaders = {};
95
+ fetchResponse.headers.forEach((value, key) => {
96
+ const lower = key.toLowerCase();
97
+ if (!HOP_BY_HOP_HEADERS.has(lower) && lower !== 'content-encoding' && lower !== 'content-length') {
98
+ responseHeaders[lower] = value;
99
+ }
100
+ });
101
+ if (isSSE && fetchResponse.body) {
102
+ // Accumulate SSE body and send as a complete response so that
103
+ // upstream response headers (request-id, usage metadata, etc.)
104
+ // are preserved for the buyer.
105
+ const reader = fetchResponse.body.getReader();
106
+ const chunks = [];
107
+ try {
108
+ while (true) {
109
+ const { done, value } = await reader.read();
110
+ if (done)
111
+ break;
112
+ chunks.push(value);
113
+ }
114
+ }
115
+ catch (err) {
116
+ chunks.push(new TextEncoder().encode(`event: error\ndata: ${err instanceof Error ? err.message : 'stream error'}\n\n`));
117
+ }
118
+ const totalLength = chunks.reduce((sum, c) => sum + c.length, 0);
119
+ const body = new Uint8Array(totalLength);
120
+ let offset = 0;
121
+ for (const c of chunks) {
122
+ body.set(c, offset);
123
+ offset += c.length;
124
+ }
125
+ this._callbacks.onResponse({
126
+ requestId: request.requestId,
127
+ statusCode: fetchResponse.status,
128
+ headers: responseHeaders,
129
+ body,
130
+ });
131
+ }
132
+ else {
133
+ // Complete response
134
+ const body = new Uint8Array(await fetchResponse.arrayBuffer());
135
+ this._callbacks.onResponse({
136
+ requestId: request.requestId,
137
+ statusCode: fetchResponse.status,
138
+ headers: responseHeaders,
139
+ body,
140
+ });
141
+ }
142
+ }
143
+ catch (err) {
144
+ const errMsg = err instanceof Error ? err.message : String(err);
145
+ const sanitized = errMsg.replace(/sk-ant-[a-zA-Z0-9_-]+/g, 'sk-***');
146
+ this._sendError(request.requestId, 502, `Upstream error: ${sanitized}`);
147
+ }
148
+ finally {
149
+ this._activeCount--;
150
+ }
151
+ }
152
+ }
153
+ //# sourceMappingURL=http-relay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-relay.js","sourceRoot":"","sources":["../src/http-relay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { HttpRelay, type RelayConfig, type RelayCallbacks } from './http-relay.js';
2
+ export { swapAuthHeader, validateRequestModel, KNOWN_AUTH_HEADERS } from './auth-swap.js';
3
+ export { StaticTokenProvider, OAuthTokenProvider, createTokenProvider, type AuthType } from './token-providers.js';
4
+ export type { TokenProvider, TokenProviderState } from './token-providers.js';
5
+ export { BaseProvider, type BaseProviderConfig } from './base-provider.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC1F,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACnH,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { HttpRelay } from './http-relay.js';
2
+ export { swapAuthHeader, validateRequestModel, KNOWN_AUTH_HEADERS } from './auth-swap.js';
3
+ export { StaticTokenProvider, OAuthTokenProvider, createTokenProvider } from './token-providers.js';
4
+ export { BaseProvider } from './base-provider.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyC,MAAM,iBAAiB,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC1F,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAiB,MAAM,sBAAsB,CAAC;AAEnH,OAAO,EAAE,YAAY,EAA2B,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,47 @@
1
+ import type { TokenProvider, TokenProviderState } from '@antseed/node';
2
+ export type { TokenProvider, TokenProviderState };
3
+ /** Wraps a static API key. No refresh logic. */
4
+ export declare class StaticTokenProvider implements TokenProvider {
5
+ private readonly token;
6
+ constructor(token: string);
7
+ getToken(): Promise<string>;
8
+ stop(): void;
9
+ getState(): TokenProviderState;
10
+ }
11
+ type RefreshRequestEncoding = 'form' | 'json';
12
+ /**
13
+ * Manages an OAuth access/refresh token pair.
14
+ * Transparently refreshes the access token when it nears expiry.
15
+ */
16
+ export declare class OAuthTokenProvider implements TokenProvider {
17
+ private state;
18
+ private refreshPromise;
19
+ private readonly tokenEndpoint;
20
+ private readonly requestEncoding;
21
+ private readonly clientId;
22
+ constructor(opts: {
23
+ accessToken: string;
24
+ refreshToken: string;
25
+ expiresAt: number;
26
+ tokenEndpoint?: string;
27
+ requestEncoding?: RefreshRequestEncoding;
28
+ clientId?: string;
29
+ });
30
+ getToken(): Promise<string>;
31
+ stop(): void;
32
+ /** Expose current state for persistence. */
33
+ getState(): TokenProviderState;
34
+ private isExpiringSoon;
35
+ private refresh;
36
+ }
37
+ export type AuthType = 'apikey' | 'oauth';
38
+ /**
39
+ * Create the appropriate TokenProvider from config values.
40
+ */
41
+ export declare function createTokenProvider(opts: {
42
+ authType?: AuthType;
43
+ authValue: string;
44
+ refreshToken?: string;
45
+ expiresAt?: number;
46
+ }): TokenProvider;
47
+ //# sourceMappingURL=token-providers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-providers.d.ts","sourceRoot":"","sources":["../src/token-providers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEvE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,CAAC;AAsBlD,gDAAgD;AAChD,qBAAa,mBAAoB,YAAW,aAAa;IAC3C,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,MAAM;IACpC,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAGjC,IAAI,IAAI,IAAI;IACZ,QAAQ,IAAI,kBAAkB;CAG/B;AAYD,KAAK,sBAAsB,GAAG,MAAM,GAAG,MAAM,CAAC;AAE9C;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,aAAa;IACtD,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,cAAc,CAAgC;IACtD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAyB;IACzD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;gBAElC,IAAI,EAAE;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,eAAe,CAAC,EAAE,sBAAsB,CAAC;QACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;IAWK,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAajC,IAAI,IAAI,IAAI;IAEZ,4CAA4C;IAC5C,QAAQ,IAAI,kBAAkB;IAI9B,OAAO,CAAC,cAAc;YAIR,OAAO;CA2EtB;AAMD,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1C;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,aAAa,CAkBhB"}