@contentgrowth/llm-service 1.2.1 → 1.2.3
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 +194 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -1
- package/dist/index.d.ts +51 -1
- package/dist/index.js +193 -24
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -31,6 +31,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
31
31
|
// src/index.js
|
|
32
32
|
var index_exports = {};
|
|
33
33
|
__export(index_exports, {
|
|
34
|
+
AnthropicProvider: () => AnthropicProvider,
|
|
34
35
|
BaseConfigProvider: () => BaseConfigProvider,
|
|
35
36
|
ConfigManager: () => ConfigManager,
|
|
36
37
|
DefaultConfigProvider: () => DefaultConfigProvider,
|
|
@@ -122,7 +123,8 @@ var DefaultConfigProvider = class extends BaseConfigProvider {
|
|
|
122
123
|
return {
|
|
123
124
|
provider: tenantConfig.provider,
|
|
124
125
|
models: MODEL_CONFIGS[tenantConfig.provider],
|
|
125
|
-
|
|
126
|
+
// for backward compatibility, api_key is deprecated and shall never be used!!
|
|
127
|
+
apiKey: tenantConfig.apiKey || tenantConfig.api_key,
|
|
126
128
|
project: tenantConfig.project,
|
|
127
129
|
location: tenantConfig.location,
|
|
128
130
|
temperature: parseFloat(env.DEFAULT_TEMPERATURE || "0.7"),
|
|
@@ -193,35 +195,36 @@ var DefaultConfigProvider = class extends BaseConfigProvider {
|
|
|
193
195
|
// src/llm/config-manager.js
|
|
194
196
|
var MODEL_CONFIGS = {
|
|
195
197
|
openai: {
|
|
196
|
-
default: "gpt-
|
|
197
|
-
edge: "gpt-
|
|
198
|
-
fast: "gpt-
|
|
199
|
-
cost: "gpt-
|
|
200
|
-
free: "gpt-
|
|
198
|
+
default: "gpt-5.5-instant",
|
|
199
|
+
edge: "gpt-5.5-thinking",
|
|
200
|
+
fast: "gpt-5.5-instant",
|
|
201
|
+
cost: "gpt-5.5-instant",
|
|
202
|
+
free: "gpt-5.5-instant"
|
|
201
203
|
},
|
|
202
204
|
gemini: {
|
|
203
|
-
default: "gemini-3-flash
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
// 'gemini-2.5-flash-lite',
|
|
209
|
-
cost: "gemini-3-flash-preview",
|
|
210
|
-
// 'gemini-2.5-flash-lite',
|
|
211
|
-
free: "gemini-3-flash-preview",
|
|
212
|
-
// 'gemini-2.0-flash-lite',
|
|
205
|
+
default: "gemini-3.5-flash",
|
|
206
|
+
edge: "gemini-3.5-pro",
|
|
207
|
+
fast: "gemini-3.5-flash",
|
|
208
|
+
cost: "gemini-3.5-flash",
|
|
209
|
+
free: "gemini-3.5-flash",
|
|
213
210
|
video: "veo",
|
|
214
|
-
image: "gemini-3-pro-image-preview"
|
|
215
|
-
// Default image generation model
|
|
211
|
+
image: "gemini-3.5-pro-image-preview"
|
|
216
212
|
},
|
|
217
213
|
vertex: {
|
|
218
|
-
default: "gemini-3-flash
|
|
219
|
-
edge: "gemini-3-pro
|
|
220
|
-
fast: "gemini-3-flash
|
|
221
|
-
cost: "gemini-3-flash
|
|
222
|
-
free: "gemini-3-flash
|
|
214
|
+
default: "gemini-3.5-flash",
|
|
215
|
+
edge: "gemini-3.5-pro",
|
|
216
|
+
fast: "gemini-3.5-flash",
|
|
217
|
+
cost: "gemini-3.5-flash",
|
|
218
|
+
free: "gemini-3.5-flash",
|
|
223
219
|
video: "veo",
|
|
224
|
-
image: "gemini-3-pro-image-preview"
|
|
220
|
+
image: "gemini-3.5-pro-image-preview"
|
|
221
|
+
},
|
|
222
|
+
anthropic: {
|
|
223
|
+
default: "claude-4.6-sonnet",
|
|
224
|
+
edge: "claude-4.8-opus",
|
|
225
|
+
fast: "claude-4.5-haiku",
|
|
226
|
+
cost: "claude-4.5-haiku",
|
|
227
|
+
free: "claude-4.5-haiku"
|
|
225
228
|
}
|
|
226
229
|
};
|
|
227
230
|
var ConfigManager = class {
|
|
@@ -1181,6 +1184,170 @@ ${prompt}` : prompt;
|
|
|
1181
1184
|
}
|
|
1182
1185
|
};
|
|
1183
1186
|
|
|
1187
|
+
// src/llm/providers/anthropic-provider.js
|
|
1188
|
+
var AnthropicProvider = class extends BaseLLMProvider {
|
|
1189
|
+
constructor(config) {
|
|
1190
|
+
super(config);
|
|
1191
|
+
this.models = config.models || {};
|
|
1192
|
+
this.defaultModel = this.models.default || "claude-3-5-sonnet-20241022";
|
|
1193
|
+
}
|
|
1194
|
+
async chat(userMessage, systemPrompt = "", options = {}) {
|
|
1195
|
+
var _a;
|
|
1196
|
+
const messages = [{ role: "user", content: userMessage }];
|
|
1197
|
+
const tier = options.tier || "default";
|
|
1198
|
+
const effectiveModel = this._getModelForTier(tier);
|
|
1199
|
+
const effectiveMaxTokens = options.maxTokens || this.config.maxTokens || 4096;
|
|
1200
|
+
const effectiveTemperature = options.temperature !== void 0 ? options.temperature : (_a = this.config.temperature) != null ? _a : 0.7;
|
|
1201
|
+
const response = await this._chatCompletionWithModel(
|
|
1202
|
+
messages,
|
|
1203
|
+
systemPrompt,
|
|
1204
|
+
null,
|
|
1205
|
+
effectiveModel,
|
|
1206
|
+
effectiveMaxTokens,
|
|
1207
|
+
effectiveTemperature,
|
|
1208
|
+
options
|
|
1209
|
+
);
|
|
1210
|
+
return { text: response.content };
|
|
1211
|
+
}
|
|
1212
|
+
async chatCompletion(messages, systemPrompt, tools = null, options = {}) {
|
|
1213
|
+
var _a;
|
|
1214
|
+
const tier = options.tier || "default";
|
|
1215
|
+
const effectiveModel = this._getModelForTier(tier);
|
|
1216
|
+
const effectiveMaxTokens = options.maxTokens || this.config.maxTokens || 4096;
|
|
1217
|
+
const effectiveTemperature = options.temperature !== void 0 ? options.temperature : (_a = this.config.temperature) != null ? _a : 0.7;
|
|
1218
|
+
return this._chatCompletionWithModel(
|
|
1219
|
+
messages,
|
|
1220
|
+
systemPrompt,
|
|
1221
|
+
tools,
|
|
1222
|
+
effectiveModel,
|
|
1223
|
+
effectiveMaxTokens,
|
|
1224
|
+
effectiveTemperature,
|
|
1225
|
+
options
|
|
1226
|
+
);
|
|
1227
|
+
}
|
|
1228
|
+
async _chatCompletionWithModel(messages, systemPrompt, tools, modelName, maxTokens, temperature, options = {}) {
|
|
1229
|
+
const baseURL = this.config.baseURL || "https://api.anthropic.com";
|
|
1230
|
+
const url = `${baseURL.replace(/\/$/, "")}/v1/messages`;
|
|
1231
|
+
const formattedMessages = messages.map((m) => ({
|
|
1232
|
+
role: m.role === "assistant" ? "assistant" : "user",
|
|
1233
|
+
content: m.content
|
|
1234
|
+
}));
|
|
1235
|
+
const headers = {
|
|
1236
|
+
"Content-Type": "application/json",
|
|
1237
|
+
"x-api-key": this.config.apiKey || "",
|
|
1238
|
+
"anthropic-version": "2023-06-01"
|
|
1239
|
+
};
|
|
1240
|
+
const payload = {
|
|
1241
|
+
model: modelName,
|
|
1242
|
+
messages: formattedMessages,
|
|
1243
|
+
max_tokens: maxTokens,
|
|
1244
|
+
temperature
|
|
1245
|
+
};
|
|
1246
|
+
if (systemPrompt) {
|
|
1247
|
+
payload.system = systemPrompt;
|
|
1248
|
+
}
|
|
1249
|
+
if (options.responseFormat) {
|
|
1250
|
+
const formatType = typeof options.responseFormat === "string" ? options.responseFormat : options.responseFormat.type;
|
|
1251
|
+
if (formatType === "json" || formatType === "json_schema") {
|
|
1252
|
+
const schemaText = options.responseFormat.schema || options.responseSchema ? `
|
|
1253
|
+
|
|
1254
|
+
Your output must comply strictly with this JSON Schema: ${JSON.stringify(options.responseFormat.schema || options.responseSchema)}` : "";
|
|
1255
|
+
const jsonPrompt = `IMPORTANT: You must respond ONLY in raw JSON format. Do not write any conversational text, explanations, or markdown code blocks (e.g. do NOT wrap your answer in \`\`\`json ... \`\`\`). Your response must start with '{' and end with '}'.${schemaText}`;
|
|
1256
|
+
if (payload.system) {
|
|
1257
|
+
payload.system = `${payload.system}
|
|
1258
|
+
|
|
1259
|
+
${jsonPrompt}`;
|
|
1260
|
+
} else {
|
|
1261
|
+
payload.system = jsonPrompt;
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
let responseText;
|
|
1266
|
+
let responseData;
|
|
1267
|
+
try {
|
|
1268
|
+
const res = await fetch(url, {
|
|
1269
|
+
method: "POST",
|
|
1270
|
+
headers,
|
|
1271
|
+
body: JSON.stringify(payload)
|
|
1272
|
+
});
|
|
1273
|
+
responseText = await res.text();
|
|
1274
|
+
if (!res.ok) {
|
|
1275
|
+
console.error(`[AnthropicProvider] API request failed with status ${res.status}:`, responseText);
|
|
1276
|
+
throw new LLMServiceException(`Anthropic API Error: ${responseText}`, res.status);
|
|
1277
|
+
}
|
|
1278
|
+
responseData = JSON.parse(responseText);
|
|
1279
|
+
} catch (error) {
|
|
1280
|
+
console.error(`[AnthropicProvider] request failed (API Key: ${this._getMaskedApiKey()}):`, error);
|
|
1281
|
+
throw error;
|
|
1282
|
+
}
|
|
1283
|
+
const contentBlock = responseData.content && responseData.content[0];
|
|
1284
|
+
const contentText = contentBlock ? contentBlock.text : "";
|
|
1285
|
+
if (!contentText) {
|
|
1286
|
+
console.error("[AnthropicProvider] Model returned empty response content");
|
|
1287
|
+
throw new LLMServiceException(
|
|
1288
|
+
"Model returned empty response. This usually means the prompt or schema is confusing the model.",
|
|
1289
|
+
500
|
|
1290
|
+
);
|
|
1291
|
+
}
|
|
1292
|
+
const rawFinishReason = responseData.stop_reason;
|
|
1293
|
+
const normalizedFinishReason = this.normalizeFinishReason(rawFinishReason);
|
|
1294
|
+
const result = {
|
|
1295
|
+
content: contentText,
|
|
1296
|
+
tool_calls: null,
|
|
1297
|
+
// REST client tool calls mapping not required for playbook studio
|
|
1298
|
+
finishReason: normalizedFinishReason,
|
|
1299
|
+
_rawFinishReason: rawFinishReason,
|
|
1300
|
+
_responseFormat: options.responseFormat,
|
|
1301
|
+
usage: {
|
|
1302
|
+
prompt_tokens: responseData.usage ? responseData.usage.input_tokens : 0,
|
|
1303
|
+
completion_tokens: responseData.usage ? responseData.usage.output_tokens : 0,
|
|
1304
|
+
total_tokens: responseData.usage ? responseData.usage.input_tokens + responseData.usage.output_tokens : 0
|
|
1305
|
+
},
|
|
1306
|
+
model: modelName
|
|
1307
|
+
};
|
|
1308
|
+
if (options.responseFormat && this._shouldAutoParse(options)) {
|
|
1309
|
+
result.parsedContent = this._safeJsonParse(contentText);
|
|
1310
|
+
}
|
|
1311
|
+
return result;
|
|
1312
|
+
}
|
|
1313
|
+
_getModelForTier(tier) {
|
|
1314
|
+
if (this.models[tier]) {
|
|
1315
|
+
return this.models[tier];
|
|
1316
|
+
}
|
|
1317
|
+
return this.defaultModel;
|
|
1318
|
+
}
|
|
1319
|
+
_shouldAutoParse(options) {
|
|
1320
|
+
if (!options.responseFormat) return false;
|
|
1321
|
+
const formatType = typeof options.responseFormat === "string" ? options.responseFormat : options.responseFormat.type;
|
|
1322
|
+
return formatType === "json" || formatType === "json_schema";
|
|
1323
|
+
}
|
|
1324
|
+
_safeJsonParse(text) {
|
|
1325
|
+
try {
|
|
1326
|
+
return extractJsonFromResponse(text);
|
|
1327
|
+
} catch (error) {
|
|
1328
|
+
console.error("[AnthropicProvider] Failed to extract JSON from response:", text, error);
|
|
1329
|
+
try {
|
|
1330
|
+
return JSON.parse(text);
|
|
1331
|
+
} catch (_) {
|
|
1332
|
+
return null;
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
normalizeFinishReason(providerReason) {
|
|
1337
|
+
const lower = (providerReason || "").toLowerCase();
|
|
1338
|
+
if (lower === "end_turn") {
|
|
1339
|
+
return "completed";
|
|
1340
|
+
}
|
|
1341
|
+
if (lower === "max_tokens") {
|
|
1342
|
+
return "truncated";
|
|
1343
|
+
}
|
|
1344
|
+
if (lower === "stop_sequence") {
|
|
1345
|
+
return "completed";
|
|
1346
|
+
}
|
|
1347
|
+
return super.normalizeFinishReason(providerReason);
|
|
1348
|
+
}
|
|
1349
|
+
};
|
|
1350
|
+
|
|
1184
1351
|
// src/llm-service.js
|
|
1185
1352
|
var LLMService = class {
|
|
1186
1353
|
constructor(env, toolImplementations = {}) {
|
|
@@ -1202,6 +1369,8 @@ var LLMService = class {
|
|
|
1202
1369
|
provider = new OpenAIProvider(config);
|
|
1203
1370
|
} else if (config.provider === "gemini" || config.provider === "vertex") {
|
|
1204
1371
|
provider = new GoogleProvider(config);
|
|
1372
|
+
} else if (config.provider === "anthropic") {
|
|
1373
|
+
provider = new AnthropicProvider(config);
|
|
1205
1374
|
} else {
|
|
1206
1375
|
throw new LLMServiceException(`Unsupported LLM provider: ${config.provider}`, 500);
|
|
1207
1376
|
}
|
|
@@ -1770,6 +1939,7 @@ function createSpeechHandler(app, getConfig) {
|
|
|
1770
1939
|
}
|
|
1771
1940
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1772
1941
|
0 && (module.exports = {
|
|
1942
|
+
AnthropicProvider,
|
|
1773
1943
|
BaseConfigProvider,
|
|
1774
1944
|
ConfigManager,
|
|
1775
1945
|
DefaultConfigProvider,
|