tolvyn 1.0.4 → 1.0.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.
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,UAAU,EAAE,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAMnD,MAAM,WAAW,mBACf,SAAQ,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,SAAS,CAAC;IACjD,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;AA6CD,qBAAa,MAAO,SAAQ,UAAU;IACpC,SAAgB,eAAe,EAAE,OAAO,CAAC;IACzC,SAAgB,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACvD,SAAgB,eAAe,EAAE,MAAM,CAAC;gBAE5B,OAAO,GAAE,mBAAwB;CAgD9C"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,UAAU,EAAE,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAMnD,MAAM,WAAW,mBACf,SAAQ,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,SAAS,CAAC;IACjD,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;AAED,qBAAa,MAAO,SAAQ,UAAU;IACpC,SAAgB,eAAe,EAAE,OAAO,CAAC;IACzC,SAAgB,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACvD,SAAgB,eAAe,EAAE,MAAM,CAAC;gBAE5B,OAAO,GAAE,mBAAwB;CAgD9C"}
@@ -11,38 +11,6 @@ const openai_1 = __importDefault(require("openai"));
11
11
  const failopen_1 = require("./failopen");
12
12
  const OPENAI_DEFAULT_PROXY_URL = 'https://proxy.tolvyn.io/v1/proxy/openai/';
13
13
  const OPENAI_DIRECT_URL = 'https://api.openai.com/v1';
14
- function makeFailOpenFetch(fallbackKey, directUrl, provider) {
15
- return async function failOpenFetch(input, init) {
16
- try {
17
- const res = await fetch(input, init);
18
- if (res.status === 503) {
19
- throw Object.assign(new Error('503 from proxy'), { status: 503 });
20
- }
21
- return res;
22
- }
23
- catch (err) {
24
- if ((0, failopen_1.shouldNotFailOpen)(err) || !(0, failopen_1.isProxyError)(err))
25
- throw err;
26
- console.error(`TOLVYN proxy unreachable — routing direct to ${provider} (fail-open)`);
27
- const originalUrl = typeof input === 'string'
28
- ? input
29
- : input instanceof URL
30
- ? input.href
31
- : input.url;
32
- const url = new URL(originalUrl);
33
- const directBase = new URL(directUrl);
34
- url.hostname = directBase.hostname;
35
- url.protocol = directBase.protocol;
36
- url.port = directBase.port;
37
- url.pathname = url.pathname; // keep path intact
38
- const newInit = { ...(init ?? {}) };
39
- const headers = new Headers(init?.headers ?? {});
40
- headers.set('Authorization', `Bearer ${fallbackKey}`);
41
- newInit.headers = headers;
42
- return fetch(url.toString(), newInit);
43
- }
44
- };
45
- }
46
14
  class OpenAI extends openai_1.default {
47
15
  constructor(options = {}) {
48
16
  const tolvynApiKey = options.tolvynApiKey ?? process.env['TOLVYN_API_KEY'];
@@ -75,7 +43,7 @@ class OpenAI extends openai_1.default {
75
43
  defaultHeaders,
76
44
  };
77
45
  if (failOpen && fallbackKey && !superOptions.fetch) {
78
- superOptions.fetch = makeFailOpenFetch(fallbackKey, OPENAI_DIRECT_URL, 'OpenAI');
46
+ superOptions.fetch = (0, failopen_1.makeFailOpenFetch)(fallbackKey, OPENAI_DIRECT_URL, 'OpenAI');
79
47
  }
80
48
  super(superOptions);
81
49
  this._tolvynFailOpen = failOpen;
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":";;;;;;AAAA;;GAEG;AACH,oDAAmD;AACnD,yCAA+C;AAE/C,MAAM,wBAAwB,GAAG,0CAA0C,CAAC;AAC5E,MAAM,iBAAiB,GAAG,2BAA2B,CAAC;AAgBtD,MAAa,MAAO,SAAQ,gBAAU;IAKpC,YAAY,UAA+B,EAAE;QAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC3E,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GACZ,OAAO,CAAC,QAAQ;YAChB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;YAC/B,wBAAwB,CAAC;QAE3B,MAAM,cAAc,GAA2B,EAAE,CAAC;QAClD,IAAI,OAAO,CAAC,IAAI;YAAS,cAAc,CAAC,eAAe,CAAC,GAAW,OAAO,CAAC,IAAI,CAAC;QAChF,IAAI,OAAO,CAAC,OAAO;YAAM,cAAc,CAAC,kBAAkB,CAAC,GAAQ,OAAO,CAAC,OAAO,CAAC;QACnF,IAAI,OAAO,CAAC,OAAO;YAAM,cAAc,CAAC,kBAAkB,CAAC,GAAQ,OAAO,CAAC,OAAO,CAAC;QACnF,IAAI,OAAO,CAAC,KAAK;YAAQ,cAAc,CAAC,gBAAgB,CAAC,GAAU,OAAO,CAAC,KAAK,CAAC;QACjF,IAAI,OAAO,CAAC,IAAI;YAAS,cAAc,CAAC,eAAe,CAAC,GAAW,OAAO,CAAC,IAAI,CAAC;QAChF,IAAI,OAAO,CAAC,WAAW;YAAE,cAAc,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;QAEvF,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC1E,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;QAE1C,MAAM,EACJ,YAAY,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EACxD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,GAAG,EAClD,QAAQ,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,EACjC,GAAG,IAAI,EACR,GAAG,OAAO,CAAC;QAEZ,MAAM,YAAY,GAAkB;YAClC,GAAG,IAAI;YACP,MAAM,EAAE,YAAY;YACpB,OAAO,EAAE,QAAQ;YACjB,cAAc;SACf,CAAC;QAEF,IAAI,QAAQ,IAAI,WAAW,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;YACnD,YAAY,CAAC,KAAK,GAAG,IAAA,4BAAiB,EAAC,WAAW,EAAE,iBAAiB,EAAE,QAAQ,CAAC,CAAC;QACnF,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,CAAC;QAEpB,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC;QAChC,IAAI,CAAC,kBAAkB,GAAG,WAAW,CAAC;QACtC,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC;IAClC,CAAC;CACF;AArDD,wBAqDC"}
@@ -3,5 +3,23 @@
3
3
  */
4
4
  export declare function isProxyError(error: unknown): boolean;
5
5
  export declare function shouldNotFailOpen(error: unknown): boolean;
6
+ /**
7
+ * Build the direct-provider URL from a proxy request URL.
8
+ *
9
+ * Strips the /v1/proxy/{provider}/ prefix from the request path, then prepends
10
+ * the fallback base URL's path (e.g. "/v1" for OpenAI, "" for Anthropic) so
11
+ * the final URL hits the real provider endpoint.
12
+ *
13
+ * Example (OpenAI):
14
+ * originalUrl: https://proxy.tolvyn.io/v1/proxy/openai/chat/completions
15
+ * fallbackBase: https://api.openai.com/v1
16
+ * → https://api.openai.com/v1/chat/completions
17
+ *
18
+ * Example (Anthropic):
19
+ * originalUrl: https://proxy.tolvyn.io/v1/proxy/anthropic/v1/messages
20
+ * fallbackBase: https://api.anthropic.com
21
+ * → https://api.anthropic.com/v1/messages
22
+ */
23
+ export declare function buildFallbackUrl(originalUrl: URL, fallbackBaseUrl: string): URL;
6
24
  export declare function makeFailOpenFetch(fallbackKey: string, directUrl: string, provider: string): typeof globalThis.fetch;
7
25
  //# sourceMappingURL=failopen.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"failopen.d.ts","sourceRoot":"","sources":["../../src/failopen.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAoCpD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASzD;AAED,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,UAAU,CAAC,KAAK,CAoCzB"}
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"}
@@ -5,7 +5,9 @@
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.isProxyError = isProxyError;
7
7
  exports.shouldNotFailOpen = shouldNotFailOpen;
8
+ exports.buildFallbackUrl = buildFallbackUrl;
8
9
  exports.makeFailOpenFetch = makeFailOpenFetch;
10
+ const PROXY_PREFIX_RE = /^\/v1\/proxy\/(?:openai|anthropic|google)\//;
9
11
  function isProxyError(error) {
10
12
  if (!error || typeof error !== 'object')
11
13
  return false;
@@ -48,6 +50,35 @@ function shouldNotFailOpen(error) {
48
50
  }
49
51
  return false;
50
52
  }
53
+ /**
54
+ * Build the direct-provider URL from a proxy request URL.
55
+ *
56
+ * Strips the /v1/proxy/{provider}/ prefix from the request path, then prepends
57
+ * the fallback base URL's path (e.g. "/v1" for OpenAI, "" for Anthropic) so
58
+ * the final URL hits the real provider endpoint.
59
+ *
60
+ * Example (OpenAI):
61
+ * originalUrl: https://proxy.tolvyn.io/v1/proxy/openai/chat/completions
62
+ * fallbackBase: https://api.openai.com/v1
63
+ * → https://api.openai.com/v1/chat/completions
64
+ *
65
+ * Example (Anthropic):
66
+ * originalUrl: https://proxy.tolvyn.io/v1/proxy/anthropic/v1/messages
67
+ * fallbackBase: https://api.anthropic.com
68
+ * → https://api.anthropic.com/v1/messages
69
+ */
70
+ function buildFallbackUrl(originalUrl, fallbackBaseUrl) {
71
+ const fb = new URL(fallbackBaseUrl);
72
+ const fbBasePath = fb.pathname.replace(/\/$/, ''); // "/v1" or ""
73
+ const stripped = originalUrl.pathname.replace(PROXY_PREFIX_RE, '/');
74
+ const finalPath = fbBasePath + stripped;
75
+ const newUrl = new URL(originalUrl.toString());
76
+ newUrl.protocol = fb.protocol;
77
+ newUrl.hostname = fb.hostname;
78
+ newUrl.port = fb.port;
79
+ newUrl.pathname = finalPath;
80
+ return newUrl;
81
+ }
51
82
  function makeFailOpenFetch(fallbackKey, directUrl, provider) {
52
83
  return async function failOpenFetch(input, init) {
53
84
  try {
@@ -66,11 +97,7 @@ function makeFailOpenFetch(fallbackKey, directUrl, provider) {
66
97
  : input instanceof URL
67
98
  ? input.href
68
99
  : input.url;
69
- const url = new URL(originalUrl);
70
- const directBase = new URL(directUrl);
71
- url.hostname = directBase.hostname;
72
- url.protocol = directBase.protocol;
73
- url.port = directBase.port;
100
+ const url = buildFallbackUrl(new URL(originalUrl), directUrl);
74
101
  const newInit = { ...(init ?? {}) };
75
102
  const headers = new Headers(init?.headers ?? {});
76
103
  headers.set('Authorization', `Bearer ${fallbackKey}`);
@@ -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":";AAAA;;GAEG;;AAIH,oCAoCC;AAED,8CASC;AAmBD,4CAaC;AAED,8CAoCC;AAvHD,MAAM,eAAe,GAAG,6CAA6C,CAAC;AAEtE,SAAgB,YAAY,CAAC,KAAc;IACzC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,GAAG,GAAG,KAAgC,CAAC;IAE7C,4DAA4D;IAC5D,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAC9B,IAAI,KAAK,cAAc;QACvB,IAAI,KAAK,YAAY;QACrB,IAAI,KAAK,WAAW;QACpB,IAAI,KAAK,WAAW;QACpB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CACxB,EAAE,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sBAAsB;IACtB,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;IAClD,IAAI,MAAM,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAEhC,qBAAqB;IACrB,MAAM,OAAO,GAAG,OAAO,GAAG,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACzE,IACE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;QAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;QAC7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;QAChC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EACxC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sCAAsC;IACtC,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3B,IAAI,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE9C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAgB,iBAAiB,CAAC,KAAc;IAC9C,uEAAuE;IACvE,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;IAClD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,gBAAgB,CAAC,WAAgB,EAAE,eAAuB;IACxE,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAC;IACpC,MAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc;IAEjE,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;IAExC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC/C,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAC,QAAQ,CAAC;IAC9B,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAC,QAAQ,CAAC;IAC9B,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC;IACtB,MAAM,CAAC,QAAQ,GAAG,SAAS,CAAC;IAC5B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAgB,iBAAiB,CAC/B,WAAmB,EACnB,SAAiB,EACjB,QAAgB;IAEhB,OAAO,KAAK,UAAU,aAAa,CACjC,KAAwB,EACxB,IAAkB;QAElB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACrC,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACvB,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACpE,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC;gBAAE,MAAM,GAAG,CAAC;YAC5D,OAAO,CAAC,KAAK,CACX,gDAAgD,QAAQ,cAAc,CACvE,CAAC;YACF,MAAM,WAAW,GACf,OAAO,KAAK,KAAK,QAAQ;gBACvB,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,KAAK,YAAY,GAAG;oBACtB,CAAC,CAAC,KAAK,CAAC,IAAI;oBACZ,CAAC,CAAE,KAAiB,CAAC,GAAG,CAAC;YAC7B,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC,CAAC;YAE9D,MAAM,OAAO,GAAgB,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;YACjD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAE,IAAI,EAAE,OAAuB,IAAI,EAAE,CAAC,CAAC;YAClE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,WAAW,EAAE,CAAC,CAAC;YACtD,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;YAE1B,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;QACxC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -7,7 +7,7 @@ exports.TolvynGoogle = void 0;
7
7
  const generative_ai_1 = require("@google/generative-ai");
8
8
  // The proxy base URL is prepended to Google API paths (/v1beta/models/...).
9
9
  // The TOLVYN proxy strips /v1/proxy/google and forwards the remainder to Google.
10
- const GOOGLE_DEFAULT_PROXY_URL = 'https://proxy.tolvyn.io/v1/proxy/google';
10
+ const GOOGLE_DEFAULT_PROXY_URL = 'https://proxy.tolvyn.io/v1/proxy/google/';
11
11
  class TolvynGoogle extends generative_ai_1.GoogleGenerativeAI {
12
12
  constructor(options = {}) {
13
13
  const tolvynApiKey = options.tolvynApiKey ?? process.env['TOLVYN_API_KEY'];
@@ -1 +1 @@
1
- {"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/google.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,yDAI+B;AAE/B,4EAA4E;AAC5E,iFAAiF;AACjF,MAAM,wBAAwB,GAAG,yCAAyC,CAAC;AAe3E,MAAa,YAAa,SAAQ,kCAAkB;IAMlD,YAAY,UAA+B,EAAE;QAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC3E,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;QACJ,CAAC;QAED,yDAAyD;QACzD,uEAAuE;QACvE,KAAK,CAAC,YAAY,CAAC,CAAC;QAEpB,IAAI,CAAC,eAAe;YAClB,OAAO,CAAC,QAAQ;gBAChB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;gBAC/B,wBAAwB,CAAC;QAE3B,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QACzB,IAAI,OAAO,CAAC,IAAI;YAAS,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,GAAW,OAAO,CAAC,IAAI,CAAC;QACrF,IAAI,OAAO,CAAC,OAAO;YAAM,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,GAAQ,OAAO,CAAC,OAAO,CAAC;QACxF,IAAI,OAAO,CAAC,OAAO;YAAM,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,GAAQ,OAAO,CAAC,OAAO,CAAC;QACxF,IAAI,OAAO,CAAC,KAAK;YAAQ,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,GAAU,OAAO,CAAC,KAAK,CAAC;QACtF,IAAI,OAAO,CAAC,IAAI;YAAS,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,GAAW,OAAO,CAAC,IAAI,CAAC;QACrF,IAAI,OAAO,CAAC,WAAW;YAAE,IAAI,CAAC,cAAc,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;QAE5F,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;QAChD,IAAI,CAAC,kBAAkB;YACrB,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC1D,CAAC;IAEQ,kBAAkB,CACzB,WAAwB,EACxB,cAA+B;QAE/B,MAAM,aAAa,GAAmB;YACpC,OAAO,EAAE,IAAI,CAAC,eAAe;YAC7B,aAAa,EAAE,IAAI,CAAC,cAAc;YAClC,GAAG,cAAc;SAClB,CAAC;QACF,OAAO,KAAK,CAAC,kBAAkB,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC9D,CAAC;CACF;AA/CD,oCA+CC"}
1
+ {"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/google.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,yDAI+B;AAE/B,4EAA4E;AAC5E,iFAAiF;AACjF,MAAM,wBAAwB,GAAG,0CAA0C,CAAC;AAe5E,MAAa,YAAa,SAAQ,kCAAkB;IAMlD,YAAY,UAA+B,EAAE;QAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC3E,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;QACJ,CAAC;QAED,yDAAyD;QACzD,uEAAuE;QACvE,KAAK,CAAC,YAAY,CAAC,CAAC;QAEpB,IAAI,CAAC,eAAe;YAClB,OAAO,CAAC,QAAQ;gBAChB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;gBAC/B,wBAAwB,CAAC;QAE3B,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QACzB,IAAI,OAAO,CAAC,IAAI;YAAS,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,GAAW,OAAO,CAAC,IAAI,CAAC;QACrF,IAAI,OAAO,CAAC,OAAO;YAAM,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,GAAQ,OAAO,CAAC,OAAO,CAAC;QACxF,IAAI,OAAO,CAAC,OAAO;YAAM,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,GAAQ,OAAO,CAAC,OAAO,CAAC;QACxF,IAAI,OAAO,CAAC,KAAK;YAAQ,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,GAAU,OAAO,CAAC,KAAK,CAAC;QACtF,IAAI,OAAO,CAAC,IAAI;YAAS,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,GAAW,OAAO,CAAC,IAAI,CAAC;QACrF,IAAI,OAAO,CAAC,WAAW;YAAE,IAAI,CAAC,cAAc,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;QAE5F,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;QAChD,IAAI,CAAC,kBAAkB;YACrB,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC1D,CAAC;IAEQ,kBAAkB,CACzB,WAAwB,EACxB,cAA+B;QAE/B,MAAM,aAAa,GAAmB;YACpC,OAAO,EAAE,IAAI,CAAC,eAAe;YAC7B,aAAa,EAAE,IAAI,CAAC,cAAc;YAClC,GAAG,cAAc;SAClB,CAAC;QACF,OAAO,KAAK,CAAC,kBAAkB,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC9D,CAAC;CACF;AA/CD,oCA+CC"}
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,UAAU,EAAE,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAMnD,MAAM,WAAW,mBACf,SAAQ,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,SAAS,CAAC;IACjD,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;AA6CD,qBAAa,MAAO,SAAQ,UAAU;IACpC,SAAgB,eAAe,EAAE,OAAO,CAAC;IACzC,SAAgB,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACvD,SAAgB,eAAe,EAAE,MAAM,CAAC;gBAE5B,OAAO,GAAE,mBAAwB;CAgD9C"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,UAAU,EAAE,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAMnD,MAAM,WAAW,mBACf,SAAQ,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,SAAS,CAAC;IACjD,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;AAED,qBAAa,MAAO,SAAQ,UAAU;IACpC,SAAgB,eAAe,EAAE,OAAO,CAAC;IACzC,SAAgB,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACvD,SAAgB,eAAe,EAAE,MAAM,CAAC;gBAE5B,OAAO,GAAE,mBAAwB;CAgD9C"}
@@ -2,41 +2,9 @@
2
2
  * TOLVYN OpenAI wrapper — thin drop-in over the official openai package.
3
3
  */
4
4
  import OpenAIBase from 'openai';
5
- import { isProxyError, shouldNotFailOpen } from './failopen';
5
+ import { makeFailOpenFetch } from './failopen';
6
6
  const OPENAI_DEFAULT_PROXY_URL = 'https://proxy.tolvyn.io/v1/proxy/openai/';
7
7
  const OPENAI_DIRECT_URL = 'https://api.openai.com/v1';
8
- function makeFailOpenFetch(fallbackKey, directUrl, provider) {
9
- return async function failOpenFetch(input, init) {
10
- try {
11
- const res = await fetch(input, init);
12
- if (res.status === 503) {
13
- throw Object.assign(new Error('503 from proxy'), { status: 503 });
14
- }
15
- return res;
16
- }
17
- catch (err) {
18
- if (shouldNotFailOpen(err) || !isProxyError(err))
19
- throw err;
20
- console.error(`TOLVYN proxy unreachable — routing direct to ${provider} (fail-open)`);
21
- const originalUrl = typeof input === 'string'
22
- ? input
23
- : input instanceof URL
24
- ? input.href
25
- : input.url;
26
- const url = new URL(originalUrl);
27
- const directBase = new URL(directUrl);
28
- url.hostname = directBase.hostname;
29
- url.protocol = directBase.protocol;
30
- url.port = directBase.port;
31
- url.pathname = url.pathname; // keep path intact
32
- const newInit = { ...(init ?? {}) };
33
- const headers = new Headers(init?.headers ?? {});
34
- headers.set('Authorization', `Bearer ${fallbackKey}`);
35
- newInit.headers = headers;
36
- return fetch(url.toString(), newInit);
37
- }
38
- };
39
- }
40
8
  export class OpenAI extends OpenAIBase {
41
9
  constructor(options = {}) {
42
10
  const tolvynApiKey = options.tolvynApiKey ?? process.env['TOLVYN_API_KEY'];
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,UAA6B,MAAM,QAAQ,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,wBAAwB,GAAG,0CAA0C,CAAC;AAC5E,MAAM,iBAAiB,GAAG,2BAA2B,CAAC;AAgBtD,MAAM,OAAO,MAAO,SAAQ,UAAU;IAKpC,YAAY,UAA+B,EAAE;QAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC3E,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GACZ,OAAO,CAAC,QAAQ;YAChB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;YAC/B,wBAAwB,CAAC;QAE3B,MAAM,cAAc,GAA2B,EAAE,CAAC;QAClD,IAAI,OAAO,CAAC,IAAI;YAAS,cAAc,CAAC,eAAe,CAAC,GAAW,OAAO,CAAC,IAAI,CAAC;QAChF,IAAI,OAAO,CAAC,OAAO;YAAM,cAAc,CAAC,kBAAkB,CAAC,GAAQ,OAAO,CAAC,OAAO,CAAC;QACnF,IAAI,OAAO,CAAC,OAAO;YAAM,cAAc,CAAC,kBAAkB,CAAC,GAAQ,OAAO,CAAC,OAAO,CAAC;QACnF,IAAI,OAAO,CAAC,KAAK;YAAQ,cAAc,CAAC,gBAAgB,CAAC,GAAU,OAAO,CAAC,KAAK,CAAC;QACjF,IAAI,OAAO,CAAC,IAAI;YAAS,cAAc,CAAC,eAAe,CAAC,GAAW,OAAO,CAAC,IAAI,CAAC;QAChF,IAAI,OAAO,CAAC,WAAW;YAAE,cAAc,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;QAEvF,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC1E,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;QAE1C,MAAM,EACJ,YAAY,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EACxD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,GAAG,EAClD,QAAQ,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,EACjC,GAAG,IAAI,EACR,GAAG,OAAO,CAAC;QAEZ,MAAM,YAAY,GAAkB;YAClC,GAAG,IAAI;YACP,MAAM,EAAE,YAAY;YACpB,OAAO,EAAE,QAAQ;YACjB,cAAc;SACf,CAAC;QAEF,IAAI,QAAQ,IAAI,WAAW,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;YACnD,YAAY,CAAC,KAAK,GAAG,iBAAiB,CAAC,WAAW,EAAE,iBAAiB,EAAE,QAAQ,CAAC,CAAC;QACnF,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,CAAC;QAEpB,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC;QAChC,IAAI,CAAC,kBAAkB,GAAG,WAAW,CAAC;QACtC,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC;IAClC,CAAC;CACF"}
@@ -3,5 +3,23 @@
3
3
  */
4
4
  export declare function isProxyError(error: unknown): boolean;
5
5
  export declare function shouldNotFailOpen(error: unknown): boolean;
6
+ /**
7
+ * Build the direct-provider URL from a proxy request URL.
8
+ *
9
+ * Strips the /v1/proxy/{provider}/ prefix from the request path, then prepends
10
+ * the fallback base URL's path (e.g. "/v1" for OpenAI, "" for Anthropic) so
11
+ * the final URL hits the real provider endpoint.
12
+ *
13
+ * Example (OpenAI):
14
+ * originalUrl: https://proxy.tolvyn.io/v1/proxy/openai/chat/completions
15
+ * fallbackBase: https://api.openai.com/v1
16
+ * → https://api.openai.com/v1/chat/completions
17
+ *
18
+ * Example (Anthropic):
19
+ * originalUrl: https://proxy.tolvyn.io/v1/proxy/anthropic/v1/messages
20
+ * fallbackBase: https://api.anthropic.com
21
+ * → https://api.anthropic.com/v1/messages
22
+ */
23
+ export declare function buildFallbackUrl(originalUrl: URL, fallbackBaseUrl: string): URL;
6
24
  export declare function makeFailOpenFetch(fallbackKey: string, directUrl: string, provider: string): typeof globalThis.fetch;
7
25
  //# sourceMappingURL=failopen.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"failopen.d.ts","sourceRoot":"","sources":["../../src/failopen.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAoCpD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASzD;AAED,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,UAAU,CAAC,KAAK,CAoCzB"}
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,6 +1,7 @@
1
1
  /**
2
2
  * Fail-open helpers: detect proxy unreachability and retry direct.
3
3
  */
4
+ const PROXY_PREFIX_RE = /^\/v1\/proxy\/(?:openai|anthropic|google)\//;
4
5
  export function isProxyError(error) {
5
6
  if (!error || typeof error !== 'object')
6
7
  return false;
@@ -43,6 +44,35 @@ export function shouldNotFailOpen(error) {
43
44
  }
44
45
  return false;
45
46
  }
47
+ /**
48
+ * Build the direct-provider URL from a proxy request URL.
49
+ *
50
+ * Strips the /v1/proxy/{provider}/ prefix from the request path, then prepends
51
+ * the fallback base URL's path (e.g. "/v1" for OpenAI, "" for Anthropic) so
52
+ * the final URL hits the real provider endpoint.
53
+ *
54
+ * Example (OpenAI):
55
+ * originalUrl: https://proxy.tolvyn.io/v1/proxy/openai/chat/completions
56
+ * fallbackBase: https://api.openai.com/v1
57
+ * → https://api.openai.com/v1/chat/completions
58
+ *
59
+ * Example (Anthropic):
60
+ * originalUrl: https://proxy.tolvyn.io/v1/proxy/anthropic/v1/messages
61
+ * fallbackBase: https://api.anthropic.com
62
+ * → https://api.anthropic.com/v1/messages
63
+ */
64
+ export function buildFallbackUrl(originalUrl, fallbackBaseUrl) {
65
+ const fb = new URL(fallbackBaseUrl);
66
+ const fbBasePath = fb.pathname.replace(/\/$/, ''); // "/v1" or ""
67
+ const stripped = originalUrl.pathname.replace(PROXY_PREFIX_RE, '/');
68
+ const finalPath = fbBasePath + stripped;
69
+ const newUrl = new URL(originalUrl.toString());
70
+ newUrl.protocol = fb.protocol;
71
+ newUrl.hostname = fb.hostname;
72
+ newUrl.port = fb.port;
73
+ newUrl.pathname = finalPath;
74
+ return newUrl;
75
+ }
46
76
  export function makeFailOpenFetch(fallbackKey, directUrl, provider) {
47
77
  return async function failOpenFetch(input, init) {
48
78
  try {
@@ -61,11 +91,7 @@ export function makeFailOpenFetch(fallbackKey, directUrl, provider) {
61
91
  : input instanceof URL
62
92
  ? input.href
63
93
  : input.url;
64
- const url = new URL(originalUrl);
65
- const directBase = new URL(directUrl);
66
- url.hostname = directBase.hostname;
67
- url.protocol = directBase.protocol;
68
- url.port = directBase.port;
94
+ const url = buildFallbackUrl(new URL(originalUrl), directUrl);
69
95
  const newInit = { ...(init ?? {}) };
70
96
  const headers = new Headers(init?.headers ?? {});
71
97
  headers.set('Authorization', `Bearer ${fallbackKey}`);
@@ -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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"}
@@ -4,7 +4,7 @@
4
4
  import { GoogleGenerativeAI, } from '@google/generative-ai';
5
5
  // The proxy base URL is prepended to Google API paths (/v1beta/models/...).
6
6
  // The TOLVYN proxy strips /v1/proxy/google and forwards the remainder to Google.
7
- const GOOGLE_DEFAULT_PROXY_URL = 'https://proxy.tolvyn.io/v1/proxy/google';
7
+ const GOOGLE_DEFAULT_PROXY_URL = 'https://proxy.tolvyn.io/v1/proxy/google/';
8
8
  export class TolvynGoogle extends GoogleGenerativeAI {
9
9
  constructor(options = {}) {
10
10
  const tolvynApiKey = options.tolvynApiKey ?? process.env['TOLVYN_API_KEY'];
@@ -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;AAE/B,4EAA4E;AAC5E,iFAAiF;AACjF,MAAM,wBAAwB,GAAG,yCAAyC,CAAC;AAe3E,MAAM,OAAO,YAAa,SAAQ,kBAAkB;IAMlD,YAAY,UAA+B,EAAE;QAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC3E,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;QACJ,CAAC;QAED,yDAAyD;QACzD,uEAAuE;QACvE,KAAK,CAAC,YAAY,CAAC,CAAC;QAEpB,IAAI,CAAC,eAAe;YAClB,OAAO,CAAC,QAAQ;gBAChB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;gBAC/B,wBAAwB,CAAC;QAE3B,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QACzB,IAAI,OAAO,CAAC,IAAI;YAAS,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,GAAW,OAAO,CAAC,IAAI,CAAC;QACrF,IAAI,OAAO,CAAC,OAAO;YAAM,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,GAAQ,OAAO,CAAC,OAAO,CAAC;QACxF,IAAI,OAAO,CAAC,OAAO;YAAM,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,GAAQ,OAAO,CAAC,OAAO,CAAC;QACxF,IAAI,OAAO,CAAC,KAAK;YAAQ,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,GAAU,OAAO,CAAC,KAAK,CAAC;QACtF,IAAI,OAAO,CAAC,IAAI;YAAS,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,GAAW,OAAO,CAAC,IAAI,CAAC;QACrF,IAAI,OAAO,CAAC,WAAW;YAAE,IAAI,CAAC,cAAc,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;QAE5F,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;QAChD,IAAI,CAAC,kBAAkB;YACrB,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC1D,CAAC;IAEQ,kBAAkB,CACzB,WAAwB,EACxB,cAA+B;QAE/B,MAAM,aAAa,GAAmB;YACpC,OAAO,EAAE,IAAI,CAAC,eAAe;YAC7B,aAAa,EAAE,IAAI,CAAC,cAAc;YAClC,GAAG,cAAc;SAClB,CAAC;QACF,OAAO,KAAK,CAAC,kBAAkB,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC9D,CAAC;CACF"}
1
+ {"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/google.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,kBAAkB,GAGnB,MAAM,uBAAuB,CAAC;AAE/B,4EAA4E;AAC5E,iFAAiF;AACjF,MAAM,wBAAwB,GAAG,0CAA0C,CAAC;AAe5E,MAAM,OAAO,YAAa,SAAQ,kBAAkB;IAMlD,YAAY,UAA+B,EAAE;QAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC3E,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;QACJ,CAAC;QAED,yDAAyD;QACzD,uEAAuE;QACvE,KAAK,CAAC,YAAY,CAAC,CAAC;QAEpB,IAAI,CAAC,eAAe;YAClB,OAAO,CAAC,QAAQ;gBAChB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;gBAC/B,wBAAwB,CAAC;QAE3B,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QACzB,IAAI,OAAO,CAAC,IAAI;YAAS,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,GAAW,OAAO,CAAC,IAAI,CAAC;QACrF,IAAI,OAAO,CAAC,OAAO;YAAM,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,GAAQ,OAAO,CAAC,OAAO,CAAC;QACxF,IAAI,OAAO,CAAC,OAAO;YAAM,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,GAAQ,OAAO,CAAC,OAAO,CAAC;QACxF,IAAI,OAAO,CAAC,KAAK;YAAQ,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,GAAU,OAAO,CAAC,KAAK,CAAC;QACtF,IAAI,OAAO,CAAC,IAAI;YAAS,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,GAAW,OAAO,CAAC,IAAI,CAAC;QACrF,IAAI,OAAO,CAAC,WAAW;YAAE,IAAI,CAAC,cAAc,CAAC,uBAAuB,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;QAE5F,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;QAChD,IAAI,CAAC,kBAAkB;YACrB,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC1D,CAAC;IAEQ,kBAAkB,CACzB,WAAwB,EACxB,cAA+B;QAE/B,MAAM,aAAa,GAAmB;YACpC,OAAO,EAAE,IAAI,CAAC,eAAe;YAC7B,aAAa,EAAE,IAAI,CAAC,cAAc;YAClC,GAAG,cAAc;SAClB,CAAC;QACF,OAAO,KAAK,CAAC,kBAAkB,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC9D,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tolvyn",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
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/client.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * TOLVYN OpenAI wrapper — thin drop-in over the official openai package.
3
3
  */
4
4
  import OpenAIBase, { ClientOptions } from 'openai';
5
- import { isProxyError, shouldNotFailOpen } from './failopen';
5
+ import { makeFailOpenFetch } from './failopen';
6
6
 
7
7
  const OPENAI_DEFAULT_PROXY_URL = 'https://proxy.tolvyn.io/v1/proxy/openai/';
8
8
  const OPENAI_DIRECT_URL = 'https://api.openai.com/v1';
@@ -21,49 +21,6 @@ export interface TolvynOpenAIOptions
21
21
  openAIApiKey?: string;
22
22
  }
23
23
 
24
- function makeFailOpenFetch(
25
- fallbackKey: string,
26
- directUrl: string,
27
- provider: string
28
- ): typeof globalThis.fetch {
29
- return async function failOpenFetch(
30
- input: RequestInfo | URL,
31
- init?: RequestInit
32
- ): Promise<Response> {
33
- try {
34
- const res = await fetch(input, init);
35
- if (res.status === 503) {
36
- throw Object.assign(new Error('503 from proxy'), { status: 503 });
37
- }
38
- return res;
39
- } catch (err: unknown) {
40
- if (shouldNotFailOpen(err) || !isProxyError(err)) throw err;
41
- console.error(
42
- `TOLVYN proxy unreachable — routing direct to ${provider} (fail-open)`
43
- );
44
- const originalUrl =
45
- typeof input === 'string'
46
- ? input
47
- : input instanceof URL
48
- ? input.href
49
- : (input as Request).url;
50
- const url = new URL(originalUrl);
51
- const directBase = new URL(directUrl);
52
- url.hostname = directBase.hostname;
53
- url.protocol = directBase.protocol;
54
- url.port = directBase.port;
55
- url.pathname = url.pathname; // keep path intact
56
-
57
- const newInit: RequestInit = { ...(init ?? {}) };
58
- const headers = new Headers((init?.headers as HeadersInit) ?? {});
59
- headers.set('Authorization', `Bearer ${fallbackKey}`);
60
- newInit.headers = headers;
61
-
62
- return fetch(url.toString(), newInit);
63
- }
64
- };
65
- }
66
-
67
24
  export class OpenAI extends OpenAIBase {
68
25
  public readonly _tolvynFailOpen: boolean;
69
26
  public readonly _tolvynFallbackKey: string | undefined;
package/src/failopen.ts CHANGED
@@ -2,6 +2,8 @@
2
2
  * Fail-open helpers: detect proxy unreachability and retry direct.
3
3
  */
4
4
 
5
+ const PROXY_PREFIX_RE = /^\/v1\/proxy\/(?:openai|anthropic|google)\//;
6
+
5
7
  export function isProxyError(error: unknown): boolean {
6
8
  if (!error || typeof error !== 'object') return false;
7
9
  const err = error as Record<string, unknown>;
@@ -51,14 +53,46 @@ export function shouldNotFailOpen(error: unknown): boolean {
51
53
  return false;
52
54
  }
53
55
 
56
+ /**
57
+ * Build the direct-provider URL from a proxy request URL.
58
+ *
59
+ * Strips the /v1/proxy/{provider}/ prefix from the request path, then prepends
60
+ * the fallback base URL's path (e.g. "/v1" for OpenAI, "" for Anthropic) so
61
+ * the final URL hits the real provider endpoint.
62
+ *
63
+ * Example (OpenAI):
64
+ * originalUrl: https://proxy.tolvyn.io/v1/proxy/openai/chat/completions
65
+ * fallbackBase: https://api.openai.com/v1
66
+ * → https://api.openai.com/v1/chat/completions
67
+ *
68
+ * Example (Anthropic):
69
+ * originalUrl: https://proxy.tolvyn.io/v1/proxy/anthropic/v1/messages
70
+ * fallbackBase: https://api.anthropic.com
71
+ * → https://api.anthropic.com/v1/messages
72
+ */
73
+ export function buildFallbackUrl(originalUrl: URL, fallbackBaseUrl: string): URL {
74
+ const fb = new URL(fallbackBaseUrl);
75
+ const fbBasePath = fb.pathname.replace(/\/$/, ''); // "/v1" or ""
76
+
77
+ const stripped = originalUrl.pathname.replace(PROXY_PREFIX_RE, '/');
78
+ const finalPath = fbBasePath + stripped;
79
+
80
+ const newUrl = new URL(originalUrl.toString());
81
+ newUrl.protocol = fb.protocol;
82
+ newUrl.hostname = fb.hostname;
83
+ newUrl.port = fb.port;
84
+ newUrl.pathname = finalPath;
85
+ return newUrl;
86
+ }
87
+
54
88
  export function makeFailOpenFetch(
55
89
  fallbackKey: string,
56
90
  directUrl: string,
57
- provider: string
91
+ provider: string,
58
92
  ): typeof globalThis.fetch {
59
93
  return async function failOpenFetch(
60
94
  input: RequestInfo | URL,
61
- init?: RequestInit
95
+ init?: RequestInit,
62
96
  ): Promise<Response> {
63
97
  try {
64
98
  const res = await fetch(input, init);
@@ -69,7 +103,7 @@ export function makeFailOpenFetch(
69
103
  } catch (err: unknown) {
70
104
  if (shouldNotFailOpen(err) || !isProxyError(err)) throw err;
71
105
  console.error(
72
- `TOLVYN proxy unreachable — routing direct to ${provider} (fail-open)`
106
+ `TOLVYN proxy unreachable — routing direct to ${provider} (fail-open)`,
73
107
  );
74
108
  const originalUrl =
75
109
  typeof input === 'string'
@@ -77,11 +111,7 @@ export function makeFailOpenFetch(
77
111
  : input instanceof URL
78
112
  ? input.href
79
113
  : (input as Request).url;
80
- const url = new URL(originalUrl);
81
- const directBase = new URL(directUrl);
82
- url.hostname = directBase.hostname;
83
- url.protocol = directBase.protocol;
84
- url.port = directBase.port;
114
+ const url = buildFallbackUrl(new URL(originalUrl), directUrl);
85
115
 
86
116
  const newInit: RequestInit = { ...(init ?? {}) };
87
117
  const headers = new Headers((init?.headers as HeadersInit) ?? {});
package/src/google.ts CHANGED
@@ -9,7 +9,7 @@ import {
9
9
 
10
10
  // The proxy base URL is prepended to Google API paths (/v1beta/models/...).
11
11
  // The TOLVYN proxy strips /v1/proxy/google and forwards the remainder to Google.
12
- const GOOGLE_DEFAULT_PROXY_URL = 'https://proxy.tolvyn.io/v1/proxy/google';
12
+ const GOOGLE_DEFAULT_PROXY_URL = 'https://proxy.tolvyn.io/v1/proxy/google/';
13
13
 
14
14
  export interface TolvynGoogleOptions {
15
15
  tolvynApiKey?: string;