tolvyn 1.0.7 → 1.0.8
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/dist/cjs/failopen.d.ts +9 -0
- package/dist/cjs/failopen.d.ts.map +1 -1
- package/dist/cjs/failopen.js +31 -1
- package/dist/cjs/failopen.js.map +1 -1
- package/dist/cjs/google.d.ts.map +1 -1
- package/dist/cjs/google.js +8 -2
- package/dist/cjs/google.js.map +1 -1
- package/dist/esm/failopen.d.ts +9 -0
- package/dist/esm/failopen.d.ts.map +1 -1
- package/dist/esm/failopen.js +30 -1
- package/dist/esm/failopen.js.map +1 -1
- package/dist/esm/google.d.ts.map +1 -1
- package/dist/esm/google.js +8 -2
- package/dist/esm/google.js.map +1 -1
- package/package.json +1 -1
- package/src/failopen.ts +35 -1
- package/src/google.ts +8 -2
package/dist/cjs/failopen.d.ts
CHANGED
|
@@ -21,5 +21,14 @@ export declare function shouldNotFailOpen(error: unknown): boolean;
|
|
|
21
21
|
* → https://api.anthropic.com/v1/messages
|
|
22
22
|
*/
|
|
23
23
|
export declare function buildFallbackUrl(originalUrl: URL, fallbackBaseUrl: string): URL;
|
|
24
|
+
/**
|
|
25
|
+
* Rewrite `headers` in place to authenticate a direct provider call.
|
|
26
|
+
*
|
|
27
|
+
* Strips every inbound auth header (Authorization/x-api-key/x-goog-api-key —
|
|
28
|
+
* each may carry the TOLVYN key) and sets the single header the provider's
|
|
29
|
+
* direct API expects, with the provider's own key. Fixes ND-09 (Bearer sent to
|
|
30
|
+
* Anthropic → 401) and ND-11 (the TOLVYN key in x-api-key leaking on fallback).
|
|
31
|
+
*/
|
|
32
|
+
export declare function applyFallbackAuth(headers: Headers, provider: string, fallbackKey: string): void;
|
|
24
33
|
export declare function makeFailOpenFetch(fallbackKey: string, directUrl: string, provider: string): typeof globalThis.fetch;
|
|
25
34
|
//# sourceMappingURL=failopen.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"failopen.d.ts","sourceRoot":"","sources":["../../src/failopen.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAoCpD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASzD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,GAAG,GAAG,CAa/E;AAED,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,UAAU,CAAC,KAAK,CAgCzB"}
|
|
1
|
+
{"version":3,"file":"failopen.d.ts","sourceRoot":"","sources":["../../src/failopen.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAoCpD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASzD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,GAAG,GAAG,CAa/E;AAYD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,IAAI,CAUN;AAED,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,UAAU,CAAC,KAAK,CAgCzB"}
|
package/dist/cjs/failopen.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.isProxyError = isProxyError;
|
|
7
7
|
exports.shouldNotFailOpen = shouldNotFailOpen;
|
|
8
8
|
exports.buildFallbackUrl = buildFallbackUrl;
|
|
9
|
+
exports.applyFallbackAuth = applyFallbackAuth;
|
|
9
10
|
exports.makeFailOpenFetch = makeFailOpenFetch;
|
|
10
11
|
const PROXY_PREFIX_RE = /^\/v1\/proxy\/(?:openai|anthropic|google)\//;
|
|
11
12
|
function isProxyError(error) {
|
|
@@ -79,6 +80,35 @@ function buildFallbackUrl(originalUrl, fallbackBaseUrl) {
|
|
|
79
80
|
newUrl.pathname = finalPath;
|
|
80
81
|
return newUrl;
|
|
81
82
|
}
|
|
83
|
+
// The header each provider's DIRECT API reads the API key from. The TOLVYN
|
|
84
|
+
// proxy accepts Authorization/x-api-key/x-goog-api-key interchangeably, but the
|
|
85
|
+
// providers themselves do NOT: Anthropic authenticates only via x-api-key and
|
|
86
|
+
// Google only via x-goog-api-key — sending Bearer to them 401s.
|
|
87
|
+
const PROVIDER_AUTH_HEADER = {
|
|
88
|
+
openai: 'Authorization',
|
|
89
|
+
anthropic: 'x-api-key',
|
|
90
|
+
google: 'x-goog-api-key',
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Rewrite `headers` in place to authenticate a direct provider call.
|
|
94
|
+
*
|
|
95
|
+
* Strips every inbound auth header (Authorization/x-api-key/x-goog-api-key —
|
|
96
|
+
* each may carry the TOLVYN key) and sets the single header the provider's
|
|
97
|
+
* direct API expects, with the provider's own key. Fixes ND-09 (Bearer sent to
|
|
98
|
+
* Anthropic → 401) and ND-11 (the TOLVYN key in x-api-key leaking on fallback).
|
|
99
|
+
*/
|
|
100
|
+
function applyFallbackAuth(headers, provider, fallbackKey) {
|
|
101
|
+
headers.delete('Authorization');
|
|
102
|
+
headers.delete('x-api-key');
|
|
103
|
+
headers.delete('x-goog-api-key');
|
|
104
|
+
const header = PROVIDER_AUTH_HEADER[provider.toLowerCase()] ?? 'Authorization';
|
|
105
|
+
if (header === 'Authorization') {
|
|
106
|
+
headers.set('Authorization', `Bearer ${fallbackKey}`);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
headers.set(header, fallbackKey);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
82
112
|
function makeFailOpenFetch(fallbackKey, directUrl, provider) {
|
|
83
113
|
return async function failOpenFetch(input, init) {
|
|
84
114
|
try {
|
|
@@ -100,7 +130,7 @@ function makeFailOpenFetch(fallbackKey, directUrl, provider) {
|
|
|
100
130
|
const url = buildFallbackUrl(new URL(originalUrl), directUrl);
|
|
101
131
|
const newInit = { ...(init ?? {}) };
|
|
102
132
|
const headers = new Headers(init?.headers ?? {});
|
|
103
|
-
headers
|
|
133
|
+
applyFallbackAuth(headers, provider, fallbackKey);
|
|
104
134
|
newInit.headers = headers;
|
|
105
135
|
return fetch(url.toString(), newInit);
|
|
106
136
|
}
|
package/dist/cjs/failopen.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"failopen.js","sourceRoot":"","sources":["../../src/failopen.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAIH,oCAoCC;AAED,8CASC;AAmBD,4CAaC;AAED,8CAoCC;
|
|
1
|
+
{"version":3,"file":"failopen.js","sourceRoot":"","sources":["../../src/failopen.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/google.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../src/google.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,cAAc,EACf,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../src/google.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,cAAc,EACf,MAAM,uBAAuB,CAAC;AAW/B,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAID,qBAAa,MAAO,SAAQ,kBAAkB;IAC5C,SAAgB,eAAe,EAAE,OAAO,CAAC;IACzC,SAAgB,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACvD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;gBAE5C,OAAO,GAAE,mBAAwB;IAgCpC,kBAAkB,CACzB,WAAW,EAAE,WAAW,EACxB,cAAc,CAAC,EAAE,cAAc;CAoClC"}
|
package/dist/cjs/google.js
CHANGED
|
@@ -8,7 +8,11 @@ const generative_ai_1 = require("@google/generative-ai");
|
|
|
8
8
|
const failopen_1 = require("./failopen");
|
|
9
9
|
// The proxy base URL is prepended to Google API paths (/v1beta/models/...).
|
|
10
10
|
// The TOLVYN proxy strips /v1/proxy/google and forwards the remainder to Google.
|
|
11
|
-
|
|
11
|
+
// ND-10: NO trailing slash. @google/generative-ai builds `${baseUrl}/${apiVersion}/...`
|
|
12
|
+
// WITHOUT collapsing a double slash (unlike the OpenAI/Anthropic SDKs), so a
|
|
13
|
+
// trailing slash here produces `.../proxy/google//v1beta/...`. This intentionally
|
|
14
|
+
// reverses ND-07's trailing-slash "consistency" for the Google provider only.
|
|
15
|
+
const GOOGLE_DEFAULT_PROXY_URL = 'https://proxy.tolvyn.io/v1/proxy/google';
|
|
12
16
|
// ND-05: renamed from TolvynGoogle → Google so stack traces and constructor.name
|
|
13
17
|
// match the public API. Old name remains re-exportable via index.ts alias.
|
|
14
18
|
class Google extends generative_ai_1.GoogleGenerativeAI {
|
|
@@ -45,7 +49,9 @@ class Google extends generative_ai_1.GoogleGenerativeAI {
|
|
|
45
49
|
}
|
|
46
50
|
getGenerativeModel(modelParams, requestOptions) {
|
|
47
51
|
const mergedOptions = {
|
|
48
|
-
|
|
52
|
+
// ND-10: strip any trailing slash so an env/option override can't
|
|
53
|
+
// reintroduce the double-slash the Google SDK won't collapse.
|
|
54
|
+
baseUrl: this._tolvynProxyUrl.replace(/\/+$/, ''),
|
|
49
55
|
customHeaders: this._tolvynHeaders,
|
|
50
56
|
...requestOptions,
|
|
51
57
|
};
|
package/dist/cjs/google.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/google.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,yDAI+B;AAC/B,yCAA0C;AAE1C,4EAA4E;AAC5E,iFAAiF;AACjF,MAAM,wBAAwB,GAAG,
|
|
1
|
+
{"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/google.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/failopen.d.ts
CHANGED
|
@@ -21,5 +21,14 @@ export declare function shouldNotFailOpen(error: unknown): boolean;
|
|
|
21
21
|
* → https://api.anthropic.com/v1/messages
|
|
22
22
|
*/
|
|
23
23
|
export declare function buildFallbackUrl(originalUrl: URL, fallbackBaseUrl: string): URL;
|
|
24
|
+
/**
|
|
25
|
+
* Rewrite `headers` in place to authenticate a direct provider call.
|
|
26
|
+
*
|
|
27
|
+
* Strips every inbound auth header (Authorization/x-api-key/x-goog-api-key —
|
|
28
|
+
* each may carry the TOLVYN key) and sets the single header the provider's
|
|
29
|
+
* direct API expects, with the provider's own key. Fixes ND-09 (Bearer sent to
|
|
30
|
+
* Anthropic → 401) and ND-11 (the TOLVYN key in x-api-key leaking on fallback).
|
|
31
|
+
*/
|
|
32
|
+
export declare function applyFallbackAuth(headers: Headers, provider: string, fallbackKey: string): void;
|
|
24
33
|
export declare function makeFailOpenFetch(fallbackKey: string, directUrl: string, provider: string): typeof globalThis.fetch;
|
|
25
34
|
//# sourceMappingURL=failopen.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"failopen.d.ts","sourceRoot":"","sources":["../../src/failopen.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAoCpD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASzD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,GAAG,GAAG,CAa/E;AAED,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,UAAU,CAAC,KAAK,CAgCzB"}
|
|
1
|
+
{"version":3,"file":"failopen.d.ts","sourceRoot":"","sources":["../../src/failopen.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAoCpD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASzD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,GAAG,GAAG,CAa/E;AAYD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,IAAI,CAUN;AAED,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,UAAU,CAAC,KAAK,CAgCzB"}
|
package/dist/esm/failopen.js
CHANGED
|
@@ -73,6 +73,35 @@ export function buildFallbackUrl(originalUrl, fallbackBaseUrl) {
|
|
|
73
73
|
newUrl.pathname = finalPath;
|
|
74
74
|
return newUrl;
|
|
75
75
|
}
|
|
76
|
+
// The header each provider's DIRECT API reads the API key from. The TOLVYN
|
|
77
|
+
// proxy accepts Authorization/x-api-key/x-goog-api-key interchangeably, but the
|
|
78
|
+
// providers themselves do NOT: Anthropic authenticates only via x-api-key and
|
|
79
|
+
// Google only via x-goog-api-key — sending Bearer to them 401s.
|
|
80
|
+
const PROVIDER_AUTH_HEADER = {
|
|
81
|
+
openai: 'Authorization',
|
|
82
|
+
anthropic: 'x-api-key',
|
|
83
|
+
google: 'x-goog-api-key',
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Rewrite `headers` in place to authenticate a direct provider call.
|
|
87
|
+
*
|
|
88
|
+
* Strips every inbound auth header (Authorization/x-api-key/x-goog-api-key —
|
|
89
|
+
* each may carry the TOLVYN key) and sets the single header the provider's
|
|
90
|
+
* direct API expects, with the provider's own key. Fixes ND-09 (Bearer sent to
|
|
91
|
+
* Anthropic → 401) and ND-11 (the TOLVYN key in x-api-key leaking on fallback).
|
|
92
|
+
*/
|
|
93
|
+
export function applyFallbackAuth(headers, provider, fallbackKey) {
|
|
94
|
+
headers.delete('Authorization');
|
|
95
|
+
headers.delete('x-api-key');
|
|
96
|
+
headers.delete('x-goog-api-key');
|
|
97
|
+
const header = PROVIDER_AUTH_HEADER[provider.toLowerCase()] ?? 'Authorization';
|
|
98
|
+
if (header === 'Authorization') {
|
|
99
|
+
headers.set('Authorization', `Bearer ${fallbackKey}`);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
headers.set(header, fallbackKey);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
76
105
|
export function makeFailOpenFetch(fallbackKey, directUrl, provider) {
|
|
77
106
|
return async function failOpenFetch(input, init) {
|
|
78
107
|
try {
|
|
@@ -94,7 +123,7 @@ export function makeFailOpenFetch(fallbackKey, directUrl, provider) {
|
|
|
94
123
|
const url = buildFallbackUrl(new URL(originalUrl), directUrl);
|
|
95
124
|
const newInit = { ...(init ?? {}) };
|
|
96
125
|
const headers = new Headers(init?.headers ?? {});
|
|
97
|
-
headers
|
|
126
|
+
applyFallbackAuth(headers, provider, fallbackKey);
|
|
98
127
|
newInit.headers = headers;
|
|
99
128
|
return fetch(url.toString(), newInit);
|
|
100
129
|
}
|
package/dist/esm/failopen.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"failopen.js","sourceRoot":"","sources":["../../src/failopen.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"failopen.js","sourceRoot":"","sources":["../../src/failopen.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/google.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../src/google.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,cAAc,EACf,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../src/google.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,cAAc,EACf,MAAM,uBAAuB,CAAC;AAW/B,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAID,qBAAa,MAAO,SAAQ,kBAAkB;IAC5C,SAAgB,eAAe,EAAE,OAAO,CAAC;IACzC,SAAgB,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACvD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;gBAE5C,OAAO,GAAE,mBAAwB;IAgCpC,kBAAkB,CACzB,WAAW,EAAE,WAAW,EACxB,cAAc,CAAC,EAAE,cAAc;CAoClC"}
|
package/dist/esm/google.js
CHANGED
|
@@ -5,7 +5,11 @@ import { GoogleGenerativeAI, } from '@google/generative-ai';
|
|
|
5
5
|
import { isProxyError } from './failopen';
|
|
6
6
|
// The proxy base URL is prepended to Google API paths (/v1beta/models/...).
|
|
7
7
|
// The TOLVYN proxy strips /v1/proxy/google and forwards the remainder to Google.
|
|
8
|
-
|
|
8
|
+
// ND-10: NO trailing slash. @google/generative-ai builds `${baseUrl}/${apiVersion}/...`
|
|
9
|
+
// WITHOUT collapsing a double slash (unlike the OpenAI/Anthropic SDKs), so a
|
|
10
|
+
// trailing slash here produces `.../proxy/google//v1beta/...`. This intentionally
|
|
11
|
+
// reverses ND-07's trailing-slash "consistency" for the Google provider only.
|
|
12
|
+
const GOOGLE_DEFAULT_PROXY_URL = 'https://proxy.tolvyn.io/v1/proxy/google';
|
|
9
13
|
// ND-05: renamed from TolvynGoogle → Google so stack traces and constructor.name
|
|
10
14
|
// match the public API. Old name remains re-exportable via index.ts alias.
|
|
11
15
|
export class Google extends GoogleGenerativeAI {
|
|
@@ -42,7 +46,9 @@ export class Google extends GoogleGenerativeAI {
|
|
|
42
46
|
}
|
|
43
47
|
getGenerativeModel(modelParams, requestOptions) {
|
|
44
48
|
const mergedOptions = {
|
|
45
|
-
|
|
49
|
+
// ND-10: strip any trailing slash so an env/option override can't
|
|
50
|
+
// reintroduce the double-slash the Google SDK won't collapse.
|
|
51
|
+
baseUrl: this._tolvynProxyUrl.replace(/\/+$/, ''),
|
|
46
52
|
customHeaders: this._tolvynHeaders,
|
|
47
53
|
...requestOptions,
|
|
48
54
|
};
|
package/dist/esm/google.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/google.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,kBAAkB,GAGnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,4EAA4E;AAC5E,iFAAiF;AACjF,MAAM,wBAAwB,GAAG,
|
|
1
|
+
{"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/google.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tolvyn",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Drop-in replacement for the OpenAI/Anthropic SDK — routes through TOLVYN for cost attribution, budget enforcement, and audit logging.",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
package/src/failopen.ts
CHANGED
|
@@ -85,6 +85,40 @@ export function buildFallbackUrl(originalUrl: URL, fallbackBaseUrl: string): URL
|
|
|
85
85
|
return newUrl;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
// The header each provider's DIRECT API reads the API key from. The TOLVYN
|
|
89
|
+
// proxy accepts Authorization/x-api-key/x-goog-api-key interchangeably, but the
|
|
90
|
+
// providers themselves do NOT: Anthropic authenticates only via x-api-key and
|
|
91
|
+
// Google only via x-goog-api-key — sending Bearer to them 401s.
|
|
92
|
+
const PROVIDER_AUTH_HEADER: Record<string, string> = {
|
|
93
|
+
openai: 'Authorization',
|
|
94
|
+
anthropic: 'x-api-key',
|
|
95
|
+
google: 'x-goog-api-key',
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Rewrite `headers` in place to authenticate a direct provider call.
|
|
100
|
+
*
|
|
101
|
+
* Strips every inbound auth header (Authorization/x-api-key/x-goog-api-key —
|
|
102
|
+
* each may carry the TOLVYN key) and sets the single header the provider's
|
|
103
|
+
* direct API expects, with the provider's own key. Fixes ND-09 (Bearer sent to
|
|
104
|
+
* Anthropic → 401) and ND-11 (the TOLVYN key in x-api-key leaking on fallback).
|
|
105
|
+
*/
|
|
106
|
+
export function applyFallbackAuth(
|
|
107
|
+
headers: Headers,
|
|
108
|
+
provider: string,
|
|
109
|
+
fallbackKey: string,
|
|
110
|
+
): void {
|
|
111
|
+
headers.delete('Authorization');
|
|
112
|
+
headers.delete('x-api-key');
|
|
113
|
+
headers.delete('x-goog-api-key');
|
|
114
|
+
const header = PROVIDER_AUTH_HEADER[provider.toLowerCase()] ?? 'Authorization';
|
|
115
|
+
if (header === 'Authorization') {
|
|
116
|
+
headers.set('Authorization', `Bearer ${fallbackKey}`);
|
|
117
|
+
} else {
|
|
118
|
+
headers.set(header, fallbackKey);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
88
122
|
export function makeFailOpenFetch(
|
|
89
123
|
fallbackKey: string,
|
|
90
124
|
directUrl: string,
|
|
@@ -115,7 +149,7 @@ export function makeFailOpenFetch(
|
|
|
115
149
|
|
|
116
150
|
const newInit: RequestInit = { ...(init ?? {}) };
|
|
117
151
|
const headers = new Headers((init?.headers as HeadersInit) ?? {});
|
|
118
|
-
headers
|
|
152
|
+
applyFallbackAuth(headers, provider, fallbackKey);
|
|
119
153
|
newInit.headers = headers;
|
|
120
154
|
|
|
121
155
|
return fetch(url.toString(), newInit);
|
package/src/google.ts
CHANGED
|
@@ -10,7 +10,11 @@ import { isProxyError } from './failopen';
|
|
|
10
10
|
|
|
11
11
|
// The proxy base URL is prepended to Google API paths (/v1beta/models/...).
|
|
12
12
|
// The TOLVYN proxy strips /v1/proxy/google and forwards the remainder to Google.
|
|
13
|
-
|
|
13
|
+
// ND-10: NO trailing slash. @google/generative-ai builds `${baseUrl}/${apiVersion}/...`
|
|
14
|
+
// WITHOUT collapsing a double slash (unlike the OpenAI/Anthropic SDKs), so a
|
|
15
|
+
// trailing slash here produces `.../proxy/google//v1beta/...`. This intentionally
|
|
16
|
+
// reverses ND-07's trailing-slash "consistency" for the Google provider only.
|
|
17
|
+
const GOOGLE_DEFAULT_PROXY_URL = 'https://proxy.tolvyn.io/v1/proxy/google';
|
|
14
18
|
|
|
15
19
|
export interface TolvynGoogleOptions {
|
|
16
20
|
tolvynApiKey?: string;
|
|
@@ -70,7 +74,9 @@ export class Google extends GoogleGenerativeAI {
|
|
|
70
74
|
requestOptions?: RequestOptions
|
|
71
75
|
) {
|
|
72
76
|
const mergedOptions: RequestOptions = {
|
|
73
|
-
|
|
77
|
+
// ND-10: strip any trailing slash so an env/option override can't
|
|
78
|
+
// reintroduce the double-slash the Google SDK won't collapse.
|
|
79
|
+
baseUrl: this._tolvynProxyUrl.replace(/\/+$/, ''),
|
|
74
80
|
customHeaders: this._tolvynHeaders,
|
|
75
81
|
...requestOptions,
|
|
76
82
|
};
|