tolvyn 1.0.3 → 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.
@@ -9,6 +9,8 @@ export interface TolvynAnthropicOptions extends Omit<ClientOptions, 'apiKey' | '
9
9
  service?: string;
10
10
  feature?: string;
11
11
  agent?: string;
12
+ user?: string;
13
+ endCustomer?: string;
12
14
  failOpen?: boolean;
13
15
  anthropicApiKey?: string;
14
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/anthropic.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,aAAa,EAAE,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMjE,MAAM,WAAW,sBACf,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,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,SAAU,SAAQ,aAAa;IAC1C,SAAgB,eAAe,EAAE,OAAO,CAAC;IACzC,SAAgB,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;gBAE3C,OAAO,GAAE,sBAA2B;CA4CjD"}
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/anthropic.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,aAAa,EAAE,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMjE,MAAM,WAAW,sBACf,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,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,SAAU,SAAQ,aAAa;IAC1C,SAAgB,eAAe,EAAE,OAAO,CAAC;IACzC,SAAgB,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;gBAE3C,OAAO,GAAE,sBAA2B;CA+CjD"}
@@ -29,9 +29,13 @@ class Anthropic extends sdk_1.default {
29
29
  defaultHeaders['X-Tolvyn-Feature'] = options.feature;
30
30
  if (options.agent)
31
31
  defaultHeaders['X-Tolvyn-Agent'] = options.agent;
32
+ if (options.user)
33
+ defaultHeaders['X-Tolvyn-User'] = options.user;
34
+ if (options.endCustomer)
35
+ defaultHeaders['X-Tolvyn-End-Customer'] = options.endCustomer;
32
36
  const fallbackKey = options.anthropicApiKey ?? process.env['ANTHROPIC_API_KEY'];
33
37
  const failOpen = options.failOpen ?? true;
34
- const { tolvynApiKey: _tk, proxyUrl: _pu, team: _t, service: _sv, feature: _f, agent: _a, failOpen: _fo, anthropicApiKey: _aak, ...rest } = options;
38
+ const { tolvynApiKey: _tk, proxyUrl: _pu, team: _t, service: _sv, feature: _f, agent: _a, user: _u, endCustomer: _ec, failOpen: _fo, anthropicApiKey: _aak, ...rest } = options;
35
39
  const superOptions = {
36
40
  ...rest,
37
41
  apiKey: tolvynApiKey,
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/anthropic.ts"],"names":[],"mappings":";;;;;;AAAA;;GAEG;AACH,4DAAiE;AACjE,yCAA+C;AAE/C,MAAM,2BAA2B,GAAG,6CAA6C,CAAC;AAClF,MAAM,oBAAoB,GAAG,2BAA2B,CAAC;AAczD,MAAa,SAAU,SAAQ,aAAa;IAI1C,YAAY,UAAkC,EAAE;QAC9C,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,2BAA2B,CAAC;QAE9B,MAAM,cAAc,GAA2B,EAAE,CAAC;QAClD,IAAI,OAAO,CAAC,IAAI;YAAK,cAAc,CAAC,eAAe,CAAC,GAAM,OAAO,CAAC,IAAI,CAAC;QACvE,IAAI,OAAO,CAAC,OAAO;YAAE,cAAc,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;QAC1E,IAAI,OAAO,CAAC,OAAO;YAAE,cAAc,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;QAC1E,IAAI,OAAO,CAAC,KAAK;YAAI,cAAc,CAAC,gBAAgB,CAAC,GAAK,OAAO,CAAC,KAAK,CAAC;QAExE,MAAM,WAAW,GAAG,OAAO,CAAC,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QAChF,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,QAAQ,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAC5D,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,oBAAoB,EAAE,WAAW,CAAC,CAAC;QACzF,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,CAAC;QAEpB,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC;QAChC,IAAI,CAAC,kBAAkB,GAAG,WAAW,CAAC;IACxC,CAAC;CACF;AAhDD,8BAgDC"}
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/anthropic.ts"],"names":[],"mappings":";;;;;;AAAA;;GAEG;AACH,4DAAiE;AACjE,yCAA+C;AAE/C,MAAM,2BAA2B,GAAG,6CAA6C,CAAC;AAClF,MAAM,oBAAoB,GAAG,2BAA2B,CAAC;AAgBzD,MAAa,SAAU,SAAQ,aAAa;IAI1C,YAAY,UAAkC,EAAE;QAC9C,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,2BAA2B,CAAC;QAE9B,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,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QAChF,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,eAAe,EAAE,IAAI,EACpC,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,oBAAoB,EAAE,WAAW,CAAC,CAAC;QACzF,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,CAAC;QAEpB,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC;QAChC,IAAI,CAAC,kBAAkB,GAAG,WAAW,CAAC;IACxC,CAAC;CACF;AAnDD,8BAmDC"}
@@ -9,6 +9,8 @@ export interface TolvynOpenAIOptions extends Omit<ClientOptions, 'apiKey' | 'bas
9
9
  service?: string;
10
10
  feature?: string;
11
11
  agent?: string;
12
+ user?: string;
13
+ endCustomer?: string;
12
14
  failOpen?: boolean;
13
15
  openAIApiKey?: string;
14
16
  }
@@ -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,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;CA6C9C"}
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'];
@@ -61,9 +29,13 @@ class OpenAI extends openai_1.default {
61
29
  defaultHeaders['X-Tolvyn-Feature'] = options.feature;
62
30
  if (options.agent)
63
31
  defaultHeaders['X-Tolvyn-Agent'] = options.agent;
32
+ if (options.user)
33
+ defaultHeaders['X-Tolvyn-User'] = options.user;
34
+ if (options.endCustomer)
35
+ defaultHeaders['X-Tolvyn-End-Customer'] = options.endCustomer;
64
36
  const fallbackKey = options.openAIApiKey ?? process.env['OPENAI_API_KEY'];
65
37
  const failOpen = options.failOpen ?? true;
66
- const { tolvynApiKey: _tk, proxyUrl: _pu, team: _t, service: _sv, feature: _f, agent: _a, failOpen: _fo, openAIApiKey: _oak, ...rest } = options;
38
+ const { tolvynApiKey: _tk, proxyUrl: _pu, team: _t, service: _sv, feature: _f, agent: _a, user: _u, endCustomer: _ec, failOpen: _fo, openAIApiKey: _oak, ...rest } = options;
67
39
  const superOptions = {
68
40
  ...rest,
69
41
  apiKey: tolvynApiKey,
@@ -71,7 +43,7 @@ class OpenAI extends openai_1.default {
71
43
  defaultHeaders,
72
44
  };
73
45
  if (failOpen && fallbackKey && !superOptions.fetch) {
74
- superOptions.fetch = makeFailOpenFetch(fallbackKey, OPENAI_DIRECT_URL, 'OpenAI');
46
+ superOptions.fetch = (0, failopen_1.makeFailOpenFetch)(fallbackKey, OPENAI_DIRECT_URL, 'OpenAI');
75
47
  }
76
48
  super(superOptions);
77
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":"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"}
@@ -9,6 +9,8 @@ export interface TolvynGoogleOptions {
9
9
  service?: string;
10
10
  feature?: string;
11
11
  agent?: string;
12
+ user?: string;
13
+ endCustomer?: string;
12
14
  failOpen?: boolean;
13
15
  googleApiKey?: string;
14
16
  }
@@ -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;AAM/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,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,YAAa,SAAQ,kBAAkB;IAClD,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;IA4BpC,kBAAkB,CACzB,WAAW,EAAE,WAAW,EACxB,cAAc,CAAC,EAAE,cAAc;CASlC"}
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;AAM/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;AAED,qBAAa,YAAa,SAAQ,kBAAkB;IAClD,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;IA8BpC,kBAAkB,CACzB,WAAW,EAAE,WAAW,EACxB,cAAc,CAAC,EAAE,cAAc;CASlC"}
@@ -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'];
@@ -30,6 +30,10 @@ class TolvynGoogle extends generative_ai_1.GoogleGenerativeAI {
30
30
  this._tolvynHeaders['X-Tolvyn-Feature'] = options.feature;
31
31
  if (options.agent)
32
32
  this._tolvynHeaders['X-Tolvyn-Agent'] = options.agent;
33
+ if (options.user)
34
+ this._tolvynHeaders['X-Tolvyn-User'] = options.user;
35
+ if (options.endCustomer)
36
+ this._tolvynHeaders['X-Tolvyn-End-Customer'] = options.endCustomer;
33
37
  this._tolvynFailOpen = options.failOpen ?? true;
34
38
  this._tolvynFallbackKey =
35
39
  options.googleApiKey ?? process.env['GOOGLE_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;AAa3E,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;YAAK,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,GAAM,OAAO,CAAC,IAAI,CAAC;QAC5E,IAAI,OAAO,CAAC,OAAO;YAAE,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/E,IAAI,OAAO,CAAC,OAAO;YAAE,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/E,IAAI,OAAO,CAAC,KAAK;YAAI,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,GAAK,OAAO,CAAC,KAAK,CAAC;QAE7E,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;AA7CD,oCA6CC"}
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"}
@@ -9,6 +9,8 @@ export interface TolvynAnthropicOptions extends Omit<ClientOptions, 'apiKey' | '
9
9
  service?: string;
10
10
  feature?: string;
11
11
  agent?: string;
12
+ user?: string;
13
+ endCustomer?: string;
12
14
  failOpen?: boolean;
13
15
  anthropicApiKey?: string;
14
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/anthropic.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,aAAa,EAAE,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMjE,MAAM,WAAW,sBACf,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,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,SAAU,SAAQ,aAAa;IAC1C,SAAgB,eAAe,EAAE,OAAO,CAAC;IACzC,SAAgB,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;gBAE3C,OAAO,GAAE,sBAA2B;CA4CjD"}
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/anthropic.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,aAAa,EAAE,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMjE,MAAM,WAAW,sBACf,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,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,SAAU,SAAQ,aAAa;IAC1C,SAAgB,eAAe,EAAE,OAAO,CAAC;IACzC,SAAgB,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;gBAE3C,OAAO,GAAE,sBAA2B;CA+CjD"}
@@ -23,9 +23,13 @@ export class Anthropic extends AnthropicBase {
23
23
  defaultHeaders['X-Tolvyn-Feature'] = options.feature;
24
24
  if (options.agent)
25
25
  defaultHeaders['X-Tolvyn-Agent'] = options.agent;
26
+ if (options.user)
27
+ defaultHeaders['X-Tolvyn-User'] = options.user;
28
+ if (options.endCustomer)
29
+ defaultHeaders['X-Tolvyn-End-Customer'] = options.endCustomer;
26
30
  const fallbackKey = options.anthropicApiKey ?? process.env['ANTHROPIC_API_KEY'];
27
31
  const failOpen = options.failOpen ?? true;
28
- const { tolvynApiKey: _tk, proxyUrl: _pu, team: _t, service: _sv, feature: _f, agent: _a, failOpen: _fo, anthropicApiKey: _aak, ...rest } = options;
32
+ const { tolvynApiKey: _tk, proxyUrl: _pu, team: _t, service: _sv, feature: _f, agent: _a, user: _u, endCustomer: _ec, failOpen: _fo, anthropicApiKey: _aak, ...rest } = options;
29
33
  const superOptions = {
30
34
  ...rest,
31
35
  apiKey: tolvynApiKey,
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/anthropic.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,aAAgC,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,2BAA2B,GAAG,6CAA6C,CAAC;AAClF,MAAM,oBAAoB,GAAG,2BAA2B,CAAC;AAczD,MAAM,OAAO,SAAU,SAAQ,aAAa;IAI1C,YAAY,UAAkC,EAAE;QAC9C,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,2BAA2B,CAAC;QAE9B,MAAM,cAAc,GAA2B,EAAE,CAAC;QAClD,IAAI,OAAO,CAAC,IAAI;YAAK,cAAc,CAAC,eAAe,CAAC,GAAM,OAAO,CAAC,IAAI,CAAC;QACvE,IAAI,OAAO,CAAC,OAAO;YAAE,cAAc,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;QAC1E,IAAI,OAAO,CAAC,OAAO;YAAE,cAAc,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;QAC1E,IAAI,OAAO,CAAC,KAAK;YAAI,cAAc,CAAC,gBAAgB,CAAC,GAAK,OAAO,CAAC,KAAK,CAAC;QAExE,MAAM,WAAW,GAAG,OAAO,CAAC,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QAChF,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,QAAQ,EAAE,GAAG,EAAE,eAAe,EAAE,IAAI,EAC5D,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,oBAAoB,EAAE,WAAW,CAAC,CAAC;QACzF,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,CAAC;QAEpB,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC;QAChC,IAAI,CAAC,kBAAkB,GAAG,WAAW,CAAC;IACxC,CAAC;CACF"}
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/anthropic.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,aAAgC,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,2BAA2B,GAAG,6CAA6C,CAAC;AAClF,MAAM,oBAAoB,GAAG,2BAA2B,CAAC;AAgBzD,MAAM,OAAO,SAAU,SAAQ,aAAa;IAI1C,YAAY,UAAkC,EAAE;QAC9C,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,2BAA2B,CAAC;QAE9B,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,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QAChF,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,eAAe,EAAE,IAAI,EACpC,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,oBAAoB,EAAE,WAAW,CAAC,CAAC;QACzF,CAAC;QAED,KAAK,CAAC,YAAY,CAAC,CAAC;QAEpB,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC;QAChC,IAAI,CAAC,kBAAkB,GAAG,WAAW,CAAC;IACxC,CAAC;CACF"}
@@ -9,6 +9,8 @@ export interface TolvynOpenAIOptions extends Omit<ClientOptions, 'apiKey' | 'bas
9
9
  service?: string;
10
10
  feature?: string;
11
11
  agent?: string;
12
+ user?: string;
13
+ endCustomer?: string;
12
14
  failOpen?: boolean;
13
15
  openAIApiKey?: string;
14
16
  }
@@ -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,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;CA6C9C"}
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'];
@@ -55,9 +23,13 @@ export class OpenAI extends OpenAIBase {
55
23
  defaultHeaders['X-Tolvyn-Feature'] = options.feature;
56
24
  if (options.agent)
57
25
  defaultHeaders['X-Tolvyn-Agent'] = options.agent;
26
+ if (options.user)
27
+ defaultHeaders['X-Tolvyn-User'] = options.user;
28
+ if (options.endCustomer)
29
+ defaultHeaders['X-Tolvyn-End-Customer'] = options.endCustomer;
58
30
  const fallbackKey = options.openAIApiKey ?? process.env['OPENAI_API_KEY'];
59
31
  const failOpen = options.failOpen ?? true;
60
- const { tolvynApiKey: _tk, proxyUrl: _pu, team: _t, service: _sv, feature: _f, agent: _a, failOpen: _fo, openAIApiKey: _oak, ...rest } = options;
32
+ const { tolvynApiKey: _tk, proxyUrl: _pu, team: _t, service: _sv, feature: _f, agent: _a, user: _u, endCustomer: _ec, failOpen: _fo, openAIApiKey: _oak, ...rest } = options;
61
33
  const superOptions = {
62
34
  ...rest,
63
35
  apiKey: tolvynApiKey,
@@ -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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"}
@@ -9,6 +9,8 @@ export interface TolvynGoogleOptions {
9
9
  service?: string;
10
10
  feature?: string;
11
11
  agent?: string;
12
+ user?: string;
13
+ endCustomer?: string;
12
14
  failOpen?: boolean;
13
15
  googleApiKey?: string;
14
16
  }
@@ -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;AAM/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,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,YAAa,SAAQ,kBAAkB;IAClD,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;IA4BpC,kBAAkB,CACzB,WAAW,EAAE,WAAW,EACxB,cAAc,CAAC,EAAE,cAAc;CASlC"}
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;AAM/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;AAED,qBAAa,YAAa,SAAQ,kBAAkB;IAClD,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;IA8BpC,kBAAkB,CACzB,WAAW,EAAE,WAAW,EACxB,cAAc,CAAC,EAAE,cAAc;CASlC"}
@@ -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'];
@@ -27,6 +27,10 @@ export class TolvynGoogle extends GoogleGenerativeAI {
27
27
  this._tolvynHeaders['X-Tolvyn-Feature'] = options.feature;
28
28
  if (options.agent)
29
29
  this._tolvynHeaders['X-Tolvyn-Agent'] = options.agent;
30
+ if (options.user)
31
+ this._tolvynHeaders['X-Tolvyn-User'] = options.user;
32
+ if (options.endCustomer)
33
+ this._tolvynHeaders['X-Tolvyn-End-Customer'] = options.endCustomer;
30
34
  this._tolvynFailOpen = options.failOpen ?? true;
31
35
  this._tolvynFallbackKey =
32
36
  options.googleApiKey ?? process.env['GOOGLE_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;AAa3E,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;YAAK,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,GAAM,OAAO,CAAC,IAAI,CAAC;QAC5E,IAAI,OAAO,CAAC,OAAO;YAAE,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/E,IAAI,OAAO,CAAC,OAAO;YAAE,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/E,IAAI,OAAO,CAAC,KAAK;YAAI,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,GAAK,OAAO,CAAC,KAAK,CAAC;QAE7E,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.3",
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/anthropic.ts CHANGED
@@ -15,6 +15,8 @@ export interface TolvynAnthropicOptions
15
15
  service?: string;
16
16
  feature?: string;
17
17
  agent?: string;
18
+ user?: string;
19
+ endCustomer?: string;
18
20
  failOpen?: boolean;
19
21
  anthropicApiKey?: string;
20
22
  }
@@ -37,17 +39,20 @@ export class Anthropic extends AnthropicBase {
37
39
  ANTHROPIC_DEFAULT_PROXY_URL;
38
40
 
39
41
  const defaultHeaders: Record<string, string> = {};
40
- if (options.team) defaultHeaders['X-Tolvyn-Team'] = options.team;
41
- if (options.service) defaultHeaders['X-Tolvyn-Service'] = options.service;
42
- if (options.feature) defaultHeaders['X-Tolvyn-Feature'] = options.feature;
43
- if (options.agent) defaultHeaders['X-Tolvyn-Agent'] = options.agent;
42
+ if (options.team) defaultHeaders['X-Tolvyn-Team'] = options.team;
43
+ if (options.service) defaultHeaders['X-Tolvyn-Service'] = options.service;
44
+ if (options.feature) defaultHeaders['X-Tolvyn-Feature'] = options.feature;
45
+ if (options.agent) defaultHeaders['X-Tolvyn-Agent'] = options.agent;
46
+ if (options.user) defaultHeaders['X-Tolvyn-User'] = options.user;
47
+ if (options.endCustomer) defaultHeaders['X-Tolvyn-End-Customer'] = options.endCustomer;
44
48
 
45
49
  const fallbackKey = options.anthropicApiKey ?? process.env['ANTHROPIC_API_KEY'];
46
50
  const failOpen = options.failOpen ?? true;
47
51
 
48
52
  const {
49
53
  tolvynApiKey: _tk, proxyUrl: _pu, team: _t, service: _sv,
50
- feature: _f, agent: _a, failOpen: _fo, anthropicApiKey: _aak,
54
+ feature: _f, agent: _a, user: _u, endCustomer: _ec,
55
+ failOpen: _fo, anthropicApiKey: _aak,
51
56
  ...rest
52
57
  } = options;
53
58
 
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';
@@ -15,53 +15,12 @@ export interface TolvynOpenAIOptions
15
15
  service?: string;
16
16
  feature?: string;
17
17
  agent?: string;
18
+ user?: string;
19
+ endCustomer?: string;
18
20
  failOpen?: boolean;
19
21
  openAIApiKey?: string;
20
22
  }
21
23
 
22
- function makeFailOpenFetch(
23
- fallbackKey: string,
24
- directUrl: string,
25
- provider: string
26
- ): typeof globalThis.fetch {
27
- return async function failOpenFetch(
28
- input: RequestInfo | URL,
29
- init?: RequestInit
30
- ): Promise<Response> {
31
- try {
32
- const res = await fetch(input, init);
33
- if (res.status === 503) {
34
- throw Object.assign(new Error('503 from proxy'), { status: 503 });
35
- }
36
- return res;
37
- } catch (err: unknown) {
38
- if (shouldNotFailOpen(err) || !isProxyError(err)) throw err;
39
- console.error(
40
- `TOLVYN proxy unreachable — routing direct to ${provider} (fail-open)`
41
- );
42
- const originalUrl =
43
- typeof input === 'string'
44
- ? input
45
- : input instanceof URL
46
- ? input.href
47
- : (input as Request).url;
48
- const url = new URL(originalUrl);
49
- const directBase = new URL(directUrl);
50
- url.hostname = directBase.hostname;
51
- url.protocol = directBase.protocol;
52
- url.port = directBase.port;
53
- url.pathname = url.pathname; // keep path intact
54
-
55
- const newInit: RequestInit = { ...(init ?? {}) };
56
- const headers = new Headers((init?.headers as HeadersInit) ?? {});
57
- headers.set('Authorization', `Bearer ${fallbackKey}`);
58
- newInit.headers = headers;
59
-
60
- return fetch(url.toString(), newInit);
61
- }
62
- };
63
- }
64
-
65
24
  export class OpenAI extends OpenAIBase {
66
25
  public readonly _tolvynFailOpen: boolean;
67
26
  public readonly _tolvynFallbackKey: string | undefined;
@@ -81,17 +40,20 @@ export class OpenAI extends OpenAIBase {
81
40
  OPENAI_DEFAULT_PROXY_URL;
82
41
 
83
42
  const defaultHeaders: Record<string, string> = {};
84
- if (options.team) defaultHeaders['X-Tolvyn-Team'] = options.team;
85
- if (options.service) defaultHeaders['X-Tolvyn-Service'] = options.service;
86
- if (options.feature) defaultHeaders['X-Tolvyn-Feature'] = options.feature;
87
- if (options.agent) defaultHeaders['X-Tolvyn-Agent'] = options.agent;
43
+ if (options.team) defaultHeaders['X-Tolvyn-Team'] = options.team;
44
+ if (options.service) defaultHeaders['X-Tolvyn-Service'] = options.service;
45
+ if (options.feature) defaultHeaders['X-Tolvyn-Feature'] = options.feature;
46
+ if (options.agent) defaultHeaders['X-Tolvyn-Agent'] = options.agent;
47
+ if (options.user) defaultHeaders['X-Tolvyn-User'] = options.user;
48
+ if (options.endCustomer) defaultHeaders['X-Tolvyn-End-Customer'] = options.endCustomer;
88
49
 
89
50
  const fallbackKey = options.openAIApiKey ?? process.env['OPENAI_API_KEY'];
90
51
  const failOpen = options.failOpen ?? true;
91
52
 
92
53
  const {
93
54
  tolvynApiKey: _tk, proxyUrl: _pu, team: _t, service: _sv,
94
- feature: _f, agent: _a, failOpen: _fo, openAIApiKey: _oak,
55
+ feature: _f, agent: _a, user: _u, endCustomer: _ec,
56
+ failOpen: _fo, openAIApiKey: _oak,
95
57
  ...rest
96
58
  } = options;
97
59
 
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;
@@ -18,6 +18,8 @@ export interface TolvynGoogleOptions {
18
18
  service?: string;
19
19
  feature?: string;
20
20
  agent?: string;
21
+ user?: string;
22
+ endCustomer?: string;
21
23
  failOpen?: boolean;
22
24
  googleApiKey?: string;
23
25
  }
@@ -46,10 +48,12 @@ export class TolvynGoogle extends GoogleGenerativeAI {
46
48
  GOOGLE_DEFAULT_PROXY_URL;
47
49
 
48
50
  this._tolvynHeaders = {};
49
- if (options.team) this._tolvynHeaders['X-Tolvyn-Team'] = options.team;
50
- if (options.service) this._tolvynHeaders['X-Tolvyn-Service'] = options.service;
51
- if (options.feature) this._tolvynHeaders['X-Tolvyn-Feature'] = options.feature;
52
- if (options.agent) this._tolvynHeaders['X-Tolvyn-Agent'] = options.agent;
51
+ if (options.team) this._tolvynHeaders['X-Tolvyn-Team'] = options.team;
52
+ if (options.service) this._tolvynHeaders['X-Tolvyn-Service'] = options.service;
53
+ if (options.feature) this._tolvynHeaders['X-Tolvyn-Feature'] = options.feature;
54
+ if (options.agent) this._tolvynHeaders['X-Tolvyn-Agent'] = options.agent;
55
+ if (options.user) this._tolvynHeaders['X-Tolvyn-User'] = options.user;
56
+ if (options.endCustomer) this._tolvynHeaders['X-Tolvyn-End-Customer'] = options.endCustomer;
53
57
 
54
58
  this._tolvynFailOpen = options.failOpen ?? true;
55
59
  this._tolvynFallbackKey =