@imenam/unified-llm-client 2.3.0 → 2.3.1

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":"OpenRouterPromptAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/openrouter/OpenRouterPromptAdapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACnH,OAAO,EAAE,WAAW,EAAY,cAAc,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIzF,eAAO,MAAM,mBAAmB,iCAAiC,CAAC;AAiFlE,qBAAa,uBAAwB,YAAW,aAAa;IAG/C,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEL,IAAI,EAAE,oBAAoB;IAIhD,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,GAAG;IAiCzC,cAAc,CAClB,QAAQ,EAAE,GAAG,EACb,KAAK,GAAE,cAAc,EAAO,EAC5B,UAAU,GAAE,MAAM,GAAG,MAAM,GAAG,MAAe,EAC7C,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,EAChC,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC;IAkClB,kBAAkB,CAAC,EACvB,QAAQ,EACR,KAAK,EACL,UAAU,EACV,KAAK,EACL,OAAO,EACP,eAAe,EACf,MAAM,GACP,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IA0H5C,OAAO,CAAC,SAAS;YAkCH,IAAI;YAmBJ,OAAO;CAItB"}
1
+ {"version":3,"file":"OpenRouterPromptAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/openrouter/OpenRouterPromptAdapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACnH,OAAO,EAAE,WAAW,EAAY,cAAc,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIzF,eAAO,MAAM,mBAAmB,iCAAiC,CAAC;AAkGlE,qBAAa,uBAAwB,YAAW,aAAa;IAG/C,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEL,IAAI,EAAE,oBAAoB;IAIhD,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,GAAG;IAiCzC,cAAc,CAClB,QAAQ,EAAE,GAAG,EACb,KAAK,GAAE,cAAc,EAAO,EAC5B,UAAU,GAAE,MAAM,GAAG,MAAM,GAAG,MAAe,EAC7C,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,EAChC,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC;IAkClB,kBAAkB,CAAC,EACvB,QAAQ,EACR,KAAK,EACL,UAAU,EACV,KAAK,EACL,OAAO,EACP,eAAe,EACf,MAAM,GACP,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IA0H5C,OAAO,CAAC,SAAS;YAkCH,IAAI;YAmBJ,OAAO;CAItB"}
@@ -68,6 +68,24 @@ const IMAGE_MIME_TYPES = {
68
68
  ".gif": "image/gif",
69
69
  ".webp": "image/webp",
70
70
  };
71
+ /**
72
+ * Type MIME d'une image d'après ses premiers octets. L'extension d'un fichier
73
+ * ne suffit pas : un JPEG enregistré en `.png` serait annoncé `image/png`, ce
74
+ * que Claude refuse (« the image appears to be a image/jpeg image »).
75
+ */
76
+ function sniffImageMimeType(buffer) {
77
+ if (buffer.length >= 3 && buffer[0] === 0xff && buffer[1] === 0xd8 && buffer[2] === 0xff)
78
+ return "image/jpeg";
79
+ if (buffer.length >= 8 && buffer.subarray(0, 8).equals(Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]))) {
80
+ return "image/png";
81
+ }
82
+ if (buffer.length >= 6 && /^GIF8[79]a$/.test(buffer.subarray(0, 6).toString("ascii")))
83
+ return "image/gif";
84
+ if (buffer.length >= 12 && buffer.subarray(0, 4).toString("ascii") === "RIFF" && buffer.subarray(8, 12).toString("ascii") === "WEBP") {
85
+ return "image/webp";
86
+ }
87
+ return undefined;
88
+ }
71
89
  /** Extensions audio acceptées en `input_audio`, associées à la valeur de `format`. */
72
90
  const AUDIO_FORMATS = {
73
91
  ".mp3": "mp3",
@@ -347,6 +365,7 @@ class OpenRouterPromptAdapter {
347
365
  exports.OpenRouterPromptAdapter = OpenRouterPromptAdapter;
348
366
  /** Convertit un fichier local (ou une URL) en élément de contenu OpenRouter. */
349
367
  function toContentPart(file) {
368
+ var _a;
350
369
  if (/^https?:\/\//.test(file)) {
351
370
  return /\.pdf($|\?)/i.test(file)
352
371
  ? { type: "file", file: { filename: path.basename(new URL(file).pathname), file_data: file } }
@@ -355,7 +374,8 @@ function toContentPart(file) {
355
374
  const filePath = path.resolve(file);
356
375
  const ext = path.extname(filePath).toLowerCase();
357
376
  // Les erreurs de lecture sont propagées : un fichier manquant ne doit pas partir en silence.
358
- const base64Data = fs.readFileSync(filePath).toString("base64");
377
+ const fileBuffer = fs.readFileSync(filePath);
378
+ const base64Data = fileBuffer.toString("base64");
359
379
  if (ext === ".pdf") {
360
380
  return {
361
381
  type: "file",
@@ -366,7 +386,8 @@ function toContentPart(file) {
366
386
  if (audioFormat) {
367
387
  return { type: "input_audio", input_audio: { data: base64Data, format: audioFormat } };
368
388
  }
369
- const mimeType = IMAGE_MIME_TYPES[ext];
389
+ // Le contenu fait foi ; l'extension ne sert qu'en dernier recours.
390
+ const mimeType = (_a = sniffImageMimeType(fileBuffer)) !== null && _a !== void 0 ? _a : IMAGE_MIME_TYPES[ext];
370
391
  if (!mimeType) {
371
392
  throw new Error(`Attached file type ${ext || "(none)"} is not supported by the OpenRouter adapter: ${file}`);
372
393
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imenam/unified-llm-client",
3
- "version": "2.3.0",
3
+ "version": "2.3.1",
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",