@imenam/unified-llm-client 2.0.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,21 @@
1
1
  export type Provider = "openai" | "gemini" | "qwen" | "anthropic";
2
- export type ApiKeyResolver<T = unknown> = (context: T) => Promise<string | false> | string | false;
2
+ /**
3
+ * Resolves the API key for an LLM call.
4
+ *
5
+ * Return semantics:
6
+ * - `string` → use this key for the current call.
7
+ * - `undefined` (or no return value) → fallback automatique sur la variable
8
+ * d'environnement du provider (comportement natif de `PROVIDERS_CONFIG`).
9
+ * - `false` → access denied (the client throws an "access denied" error).
10
+ *
11
+ * The default context shape `{ provider: Provider } & Record<string, unknown>`
12
+ * reflects the provider auto-injection performed by `UnifiedLLMClient.chat()`.
13
+ * Consumers can narrow the generic `T` to their own context type while still
14
+ * benefiting from auto-completion on `context.provider`.
15
+ */
16
+ export type ApiKeyResolver<T = {
17
+ provider: Provider;
18
+ } & Record<string, unknown>> = (context: T) => Promise<string | false | undefined> | string | false | undefined;
3
19
  export type ChatMessageRole = "user" | "assistant" | "system" | "tool" | "function";
4
20
  export interface ChatMessage {
5
21
  tool_call_id?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/common/types.ts"],"names":[],"mappings":"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"}
@@ -16,7 +16,13 @@ export type ChatOptions = {
16
16
  stream?: boolean;
17
17
  config?: ChatOptionalConfig;
18
18
  signal?: AbortSignal;
19
- apiKeyContext?: unknown;
19
+ /**
20
+ * Contexte additionnel transmis à l'`apiKeyResolver`. Optionnel : si omis, le resolver
21
+ * reçoit uniquement `{ provider }` (auto-injecté par le client). Toute valeur passée
22
+ * ici est fusionnée avec le `provider` auto-injecté ; en cas de collision sur la clé
23
+ * `provider`, l'auto-injection est prioritaire (source de vérité = `this.model.provider`).
24
+ */
25
+ apiKeyContext?: Record<string, unknown>;
20
26
  };
21
27
  export declare class UnifiedLLMClient {
22
28
  private promptAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"UnifiedLLMClient.d.ts","sourceRoot":"","sources":["../../src/core/UnifiedLLMClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UnifiedLLMClient.d.ts","sourceRoot":"","sources":["../../src/core/UnifiedLLMClient.ts"],"names":[],"mappings":"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"}
@@ -51,7 +51,7 @@ class UnifiedLLMClient {
51
51
  }
52
52
  chat(_a) {
53
53
  return __awaiter(this, arguments, void 0, function* ({ message, tools, toolChoice = "auto", onChunk, onFinalResponse, onLog, stream = false, config, signal, apiKeyContext }) {
54
- var _b;
54
+ var _b, _c;
55
55
  let effectiveConfig = config !== undefined || signal !== undefined
56
56
  ? Object.assign(Object.assign({}, config), (signal !== undefined ? { signal } : {})) : undefined;
57
57
  if (apiKeyContext !== undefined) {
@@ -61,13 +61,15 @@ class UnifiedLLMClient {
61
61
  let promptAdapter = this.promptAdapter;
62
62
  let outputAdapter = this.outputAdapter;
63
63
  if (!this.isProxyMode && effectiveResolver) {
64
- if (apiKeyContext === undefined) {
65
- throw new Error("[ApiKeyResolver] A resolver is defined but no apiKeyContext was provided.");
66
- }
67
- const resolvedKey = yield effectiveResolver(apiKeyContext);
68
- if (resolvedKey === false)
64
+ // Auto-injection systématique du provider, fusion avec le contexte consommateur s'il existe.
65
+ // L'auto-injection prend la priorité : `this.model.provider` est la source de vérité.
66
+ const fullContext = Object.assign(Object.assign({}, ((_c = apiKeyContext) !== null && _c !== void 0 ? _c : {})), { provider: this.model.provider });
67
+ const resolvedKey = yield effectiveResolver(fullContext);
68
+ if (resolvedKey === false) {
69
69
  throw new Error("[ApiKeyResolver] The resolver returned false — access denied.");
70
- const resolved = LLMAdapter_1.PROVIDERS_CONFIG[this.model.provider](resolvedKey);
70
+ }
71
+ // resolvedKey === undefined → on laisse PROVIDERS_CONFIG faire son fallback natif sur process.env
72
+ const resolved = LLMAdapter_1.PROVIDERS_CONFIG[this.model.provider](resolvedKey !== null && resolvedKey !== void 0 ? resolvedKey : undefined);
71
73
  promptAdapter = resolved.promptAdapter;
72
74
  outputAdapter = resolved.outputAdapter;
73
75
  }
@@ -21,9 +21,16 @@ const __1 = require("..");
21
21
  /**
22
22
  * Exemple de resolver : renvoie la clé pour un tenant connu, sinon `false` (refus).
23
23
  * En production, vous chargeriez la clé depuis une base, un vault, etc.
24
+ *
25
+ * Le client auto-injecte `provider` dans le contexte (typé `Provider`), et fusionne
26
+ * les clés fournies via `apiKeyContext`. Ces dernières sont accessibles via le type
27
+ * par défaut `Record<string, unknown>` et peuvent être castées vers le contexte
28
+ * applicatif au sein du resolver.
24
29
  */
25
30
  const demoResolver = (ctx) => __awaiter(void 0, void 0, void 0, function* () {
26
- const { tenantId } = ctx;
31
+ const tenantId = ctx.tenantId;
32
+ if (!tenantId)
33
+ return false;
27
34
  const byTenant = {
28
35
  // Un seul slot de démo : même clé env que la config Gemini par défaut.
29
36
  demo: process.env.GOOGLE_API_KEY,
@@ -57,6 +64,22 @@ function main() {
57
64
  apiKeyContext: { tenantId: "demo" },
58
65
  });
59
66
  console.log(res2.content);
67
+ console.log();
68
+ // Resolver qui consigne le contexte reçu (illustre l'auto-injection de `provider`)
69
+ // et qui retourne `undefined` pour activer le fallback natif sur `process.env`.
70
+ console.log("--- Resolver retournant undefined → fallback env var ---\n");
71
+ const fallbackResolver = (ctx) => __awaiter(this, void 0, void 0, function* () {
72
+ console.log(" [resolver] contexte reçu :", ctx);
73
+ return undefined;
74
+ });
75
+ const fallbackClient = new __1.UnifiedLLMClient(__1.MODELS.GEMINI_FLASH_2_5, {
76
+ apiKeyResolver: fallbackResolver,
77
+ });
78
+ // Aucun apiKeyContext fourni : le resolver reçoit uniquement `{ provider }`.
79
+ const res3 = yield fallbackClient.chat({
80
+ message: "Réponds uniquement par : OK fallback.",
81
+ });
82
+ console.log(res3.content);
60
83
  });
61
84
  }
62
85
  main().catch((err) => {
@@ -29,11 +29,16 @@ function main() {
29
29
  const server = new __1.ProxyServer({
30
30
  port: PROXY_PORT,
31
31
  apiKey: PROXY_API_KEY,
32
+ // Le `ProxyServer` auto-injecte `provider` dans le contexte (typé `Provider`).
33
+ // Si `tenantId` est manquant, on retourne `undefined` pour activer le fallback
34
+ // natif sur `process.env` ; si `tenantId` est inconnu, on refuse explicitement.
32
35
  apiKeyResolver: (ctx) => __awaiter(this, void 0, void 0, function* () {
33
- const { tenantId } = ctx;
34
- if (tenantId === "demo") {
36
+ console.log(" [server resolver] received context:", ctx);
37
+ const tenantId = ctx.tenantId;
38
+ if (!tenantId)
39
+ return undefined;
40
+ if (tenantId === "demo")
35
41
  return process.env.GOOGLE_API_KEY;
36
- }
37
42
  return false;
38
43
  }),
39
44
  });
@@ -51,10 +56,17 @@ function main() {
51
56
  });
52
57
  console.log(res.content);
53
58
  console.log();
54
- console.log("--- Missing apiKeyContext (HTTP 400 from proxy) ---\n");
59
+ console.log("--- No apiKeyContext → resolver returns undefined → fallback env ---\n");
60
+ const res2 = yield client.chat({
61
+ message: "Reply only with: OK fallback.",
62
+ });
63
+ console.log(res2.content);
64
+ console.log();
65
+ console.log("--- Unknown tenantId → resolver returns false → HTTP 403 ---\n");
55
66
  try {
56
67
  yield client.chat({
57
- message: "This should fail on the server.",
68
+ message: "This should be rejected.",
69
+ apiKeyContext: { tenantId: "ghost" },
58
70
  });
59
71
  console.error("Expected the request to be rejected.");
60
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ProxyServer.d.ts","sourceRoot":"","sources":["../../src/proxy/ProxyServer.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,kBAAkB,EAAoB,MAAM,SAAS,CAAC;AAI/D,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEjC,OAAO,EAAE,kBAAkB;IAKvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IASrB,OAAO,CAAC,aAAa;YAoCP,WAAW;YAyFX,mBAAmB;IAuCjC,OAAO,CAAC,QAAQ;CAGjB"}
1
+ {"version":3,"file":"ProxyServer.d.ts","sourceRoot":"","sources":["../../src/proxy/ProxyServer.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,kBAAkB,EAAoB,MAAM,SAAS,CAAC;AAI/D,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEjC,OAAO,EAAE,kBAAkB;IAKvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IASrB,OAAO,CAAC,aAAa;YAoCP,WAAW;YA4FX,mBAAmB;IAuCjC,OAAO,CAAC,QAAQ;CAGjB"}
@@ -116,29 +116,30 @@ class ProxyServer {
116
116
  }
117
117
  processChat(body, res) {
118
118
  return __awaiter(this, void 0, void 0, function* () {
119
+ var _a;
119
120
  let request;
120
121
  try {
121
122
  request = JSON.parse(body);
122
123
  }
123
- catch (_a) {
124
+ catch (_b) {
124
125
  res.writeHead(400, { "Content-Type": "application/json" });
125
126
  res.end(JSON.stringify({ error: "Invalid JSON body" }));
126
127
  return;
127
128
  }
128
129
  let resolvedApiKey;
129
130
  if (this.options.apiKeyResolver) {
130
- if (request.apiKeyContext === undefined) {
131
- res.writeHead(400, { "Content-Type": "application/json" });
132
- res.end(JSON.stringify({ error: "apiKeyResolver is defined but no apiKeyContext was provided" }));
133
- return;
134
- }
135
- const result = yield this.options.apiKeyResolver(request.apiKeyContext);
131
+ // Auto-injection systématique du provider, fusion avec le contexte consommateur s'il existe.
132
+ // L'auto-injection prend la priorité : `request.model.provider` est la source de vérité.
133
+ // Comportement aligné sur le mode direct (UnifiedLLMClient.chat()).
134
+ const fullContext = Object.assign(Object.assign({}, ((_a = request.apiKeyContext) !== null && _a !== void 0 ? _a : {})), { provider: request.model.provider });
135
+ const result = yield this.options.apiKeyResolver(fullContext);
136
136
  if (result === false) {
137
137
  res.writeHead(403, { "Content-Type": "application/json" });
138
138
  res.end(JSON.stringify({ error: "apiKeyResolver returned false" }));
139
139
  return;
140
140
  }
141
- resolvedApiKey = result;
141
+ // result === undefined → on laisse PROVIDERS_CONFIG faire son fallback natif sur process.env
142
+ resolvedApiKey = result !== null && result !== void 0 ? result : undefined;
142
143
  }
143
144
  const tempFiles = [];
144
145
  try {
@@ -198,7 +199,7 @@ class ProxyServer {
198
199
  try {
199
200
  fs.unlinkSync(tmpFile);
200
201
  }
201
- catch (_b) {
202
+ catch (_c) {
202
203
  /* ignore cleanup errors */
203
204
  }
204
205
  }
@@ -3,6 +3,17 @@ import { StreamedChatChunk } from "../core/LLMAdapter";
3
3
  export interface ProxyServerOptions {
4
4
  port: number;
5
5
  apiKey?: string;
6
+ /**
7
+ * Resolver côté serveur proxy. Le `ProxyServer` auto-injecte systématiquement
8
+ * la clé `provider` (issue de `request.model.provider`) dans le contexte
9
+ * transmis au resolver, et fusionne les valeurs reçues via `apiKeyContext` du
10
+ * payload HTTP. Comportement aligné sur le mode direct (`UnifiedLLMClient`).
11
+ *
12
+ * Sémantique des retours :
13
+ * - `string` → cette clé est utilisée pour l'appel courant.
14
+ * - `undefined` → fallback natif sur la variable d'environnement du provider.
15
+ * - `false` → HTTP 403 (access denied).
16
+ */
6
17
  apiKeyResolver?: ApiKeyResolver;
7
18
  }
8
19
  export interface ProxyChatRequest {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/proxy/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,EAAE,CAAC;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE;QACP,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAChC,CAAC;IACF,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/proxy/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,EAAE,CAAC;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE;QACP,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KAChC,CAAC;IACF,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imenam/unified-llm-client",
3
- "version": "2.0.3",
3
+ "version": "2.1.0",
4
4
  "description": "A unified interface for multiple LLM providers (OpenAI, Gemini, Anthropic, Qwen) with tool-calling, streaming, and audio support",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",