@contentgrowth/llm-service 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.
package/dist/index.cjs CHANGED
@@ -602,11 +602,13 @@ var GeminiProvider = class extends BaseLLMProvider {
602
602
  return { text: response.content };
603
603
  }
604
604
  async chatCompletion(messages, systemPrompt, tools = null, options = {}) {
605
+ const tier = options.tier || "default";
606
+ const modelName = this.models[tier] || this.defaultModel;
605
607
  return this._chatCompletionWithModel(
606
608
  messages,
607
609
  systemPrompt,
608
610
  tools,
609
- this.defaultModel,
611
+ modelName,
610
612
  this.config.maxTokens,
611
613
  this.config.temperature,
612
614
  options
@@ -1068,6 +1070,65 @@ ${prompt}` : prompt;
1068
1070
  throw error;
1069
1071
  }
1070
1072
  }
1073
+ /**
1074
+ * Extract structured data from a file (PDF, Image, etc.) using Gemini Multimodal capabilities.
1075
+ * @param {Buffer|string} fileData - Base64 string or Buffer of the file
1076
+ * @param {string} mimeType - Mime type (e.g., 'application/pdf', 'image/png')
1077
+ * @param {string} prompt - Extraction prompt
1078
+ * @param {Object} schema - JSON schema for the output
1079
+ * @param {Object} options - Additional options
1080
+ */
1081
+ async extractWithLLM(fileData, mimeType, prompt, schema = null, options = {}) {
1082
+ var _a, _b, _c, _d;
1083
+ const tier = options.tier || "default";
1084
+ const modelName = this.models[tier] || this.defaultModel;
1085
+ const maxTokens = options.maxTokens || this.config.maxTokens;
1086
+ const temperature = options.temperature !== void 0 ? options.temperature : this.config.temperature;
1087
+ const generationConfig = this._buildGenerationConfig(
1088
+ { ...options, responseFormat: schema ? { type: "json_schema", schema } : "json" },
1089
+ maxTokens,
1090
+ temperature
1091
+ );
1092
+ const parts = [
1093
+ { text: prompt }
1094
+ ];
1095
+ let base64Data = fileData;
1096
+ if (typeof fileData !== "string") {
1097
+ try {
1098
+ base64Data = Buffer.from(fileData).toString("base64");
1099
+ } catch (e) {
1100
+ }
1101
+ }
1102
+ parts.push({
1103
+ inlineData: {
1104
+ data: base64Data,
1105
+ mimeType
1106
+ }
1107
+ });
1108
+ const requestOptions = {
1109
+ model: modelName,
1110
+ contents: [{
1111
+ role: "user",
1112
+ parts
1113
+ }],
1114
+ config: generationConfig
1115
+ };
1116
+ try {
1117
+ const response = await this.client.models.generateContent(requestOptions);
1118
+ const candidate = (_a = response.candidates) == null ? void 0 : _a[0];
1119
+ if (!candidate) {
1120
+ throw new LLMServiceException("No candidates returned from model during extraction", 500);
1121
+ }
1122
+ const textContent = ((_d = (_c = (_b = candidate.content) == null ? void 0 : _b.parts) == null ? void 0 : _c[0]) == null ? void 0 : _d.text) || "";
1123
+ if (this._shouldAutoParse(options)) {
1124
+ return this._safeJsonParse(textContent);
1125
+ }
1126
+ return textContent;
1127
+ } catch (error) {
1128
+ console.error(`[GeminiProvider] extractWithLLM failed (API Key: ${this._getMaskedApiKey()}):`, error);
1129
+ throw error;
1130
+ }
1131
+ }
1071
1132
  };
1072
1133
 
1073
1134
  // src/llm-service.js
@@ -1295,6 +1356,22 @@ var LLMService = class {
1295
1356
  const provider = await this._getProvider(tenantId);
1296
1357
  return provider.getDeepResearchStatus(operationId);
1297
1358
  }
1359
+ /**
1360
+ * Extract structured data from a file (Multimodal)
1361
+ * @param {Buffer|string} fileData - File content (base64 or buffer)
1362
+ * @param {string} mimeType - File mime type (e.g. 'application/pdf')
1363
+ * @param {string} prompt - Extraction instructions
1364
+ * @param {string} tenantId - Tenant ID
1365
+ * @param {Object} schema - Optional JSON schema
1366
+ * @param {Object} options - Options
1367
+ */
1368
+ async extractWithLLM(fileData, mimeType, prompt, tenantId, schema = null, options = {}) {
1369
+ const provider = await this._getProvider(tenantId);
1370
+ if (!provider.extractWithLLM) {
1371
+ throw new LLMServiceException(`Provider ${provider.config.provider} does not support extractWithLLM (Multimodal extraction)`, 400);
1372
+ }
1373
+ return provider.extractWithLLM(fileData, mimeType, prompt, schema, options);
1374
+ }
1298
1375
  };
1299
1376
  var LLMServiceException = class extends Error {
1300
1377
  constructor(message, statusCode = 500, details = null) {
@@ -1543,9 +1620,17 @@ var TranscriptionService = class {
1543
1620
  const apiEndpoint = location === "global" ? "https://speech.googleapis.com" : `https://${location}-speech.googleapis.com`;
1544
1621
  const url = `${apiEndpoint}/v2/${recognizer}:recognize`;
1545
1622
  const languageCodes = language ? [language] : ["en-US"];
1623
+ let decodingConfig = { autoDecodingConfig: {} };
1624
+ if (audioFile.type && audioFile.type.includes("webm")) {
1625
+ decodingConfig = {
1626
+ explicitDecodingConfig: {
1627
+ encoding: "WEBM_OPUS"
1628
+ }
1629
+ };
1630
+ }
1546
1631
  const body = {
1547
1632
  config: {
1548
- autoDecodingConfig: {},
1633
+ ...decodingConfig,
1549
1634
  languageCodes,
1550
1635
  // Sanitize model: Strict allowlist for Google v2 models
1551
1636
  model: model || "chirp_3"