llm-exe 2.1.2 → 2.1.4
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.d.mts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +189 -3
- package/dist/index.mjs +189 -3
- package/package.json +4 -2
- package/readme.md +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -955,7 +955,10 @@ type AllLlm = {
|
|
|
955
955
|
input: AmazonBedrockRequest;
|
|
956
956
|
};
|
|
957
957
|
"xai.chat.v1": {
|
|
958
|
-
input:
|
|
958
|
+
input: GenericLLm;
|
|
959
|
+
};
|
|
960
|
+
"ollama.chat.v1": {
|
|
961
|
+
input: GenericLLm;
|
|
959
962
|
};
|
|
960
963
|
};
|
|
961
964
|
type AllUseLlmOptions = AllLlm & {
|
|
@@ -1000,7 +1003,7 @@ interface BaseRequest<_T extends Record<string, any>> {
|
|
|
1000
1003
|
interface BaseLlm<_T extends BaseLlCall = BaseLlCall> extends BaseRequest<_T> {
|
|
1001
1004
|
}
|
|
1002
1005
|
|
|
1003
|
-
type LlmProvider = "openai.chat" | "openai.embedding" | "openai.chat-mock" | "anthropic.chat" | "amazon:anthropic.chat" | "amazon:meta.chat" | "amazon:nova.chat" | "amazon.embedding" | "xai.chat";
|
|
1006
|
+
type LlmProvider = "openai.chat" | "openai.embedding" | "openai.chat-mock" | "anthropic.chat" | "amazon:anthropic.chat" | "amazon:meta.chat" | "amazon:nova.chat" | "amazon.embedding" | "xai.chat" | "ollama.chat";
|
|
1004
1007
|
interface Config<Pk = LlmProviderKey> {
|
|
1005
1008
|
key: Pk;
|
|
1006
1009
|
provider: LlmProvider;
|
|
@@ -1149,6 +1152,10 @@ declare function filterObjectOnSchema(schema: any, doc: any, detach?: any, prope
|
|
|
1149
1152
|
|
|
1150
1153
|
declare const asyncCallWithTimeout: <T = any>(asyncPromise: Promise<T>, timeLimit?: number) => Promise<T>;
|
|
1151
1154
|
|
|
1155
|
+
declare function guessProviderFromModel(payload: {
|
|
1156
|
+
model: string;
|
|
1157
|
+
}): "openai" | "xai" | "bedrock:anthropic" | "anthropic";
|
|
1158
|
+
|
|
1152
1159
|
declare const maybeStringifyJSON: (objOrMaybeString: any) => string;
|
|
1153
1160
|
declare const maybeParseJSON: <Expected = any>(objOrMaybeJSON: any) => Expected;
|
|
1154
1161
|
declare function isObjectStringified(maybeObject: string): boolean;
|
|
@@ -1160,6 +1167,7 @@ declare const index_assert: typeof assert;
|
|
|
1160
1167
|
declare const index_asyncCallWithTimeout: typeof asyncCallWithTimeout;
|
|
1161
1168
|
declare const index_defineSchema: typeof defineSchema;
|
|
1162
1169
|
declare const index_filterObjectOnSchema: typeof filterObjectOnSchema;
|
|
1170
|
+
declare const index_guessProviderFromModel: typeof guessProviderFromModel;
|
|
1163
1171
|
declare const index_importHelpers: typeof importHelpers;
|
|
1164
1172
|
declare const index_importPartials: typeof importPartials;
|
|
1165
1173
|
declare const index_isObjectStringified: typeof isObjectStringified;
|
|
@@ -1170,10 +1178,11 @@ declare const index_registerPartials: typeof registerPartials;
|
|
|
1170
1178
|
declare const index_replaceTemplateString: typeof replaceTemplateString;
|
|
1171
1179
|
declare const index_replaceTemplateStringAsync: typeof replaceTemplateStringAsync;
|
|
1172
1180
|
declare namespace index {
|
|
1173
|
-
export { index_assert as assert, index_asyncCallWithTimeout as asyncCallWithTimeout, index_defineSchema as defineSchema, index_filterObjectOnSchema as filterObjectOnSchema, index_importHelpers as importHelpers, index_importPartials as importPartials, index_isObjectStringified as isObjectStringified, index_maybeParseJSON as maybeParseJSON, index_maybeStringifyJSON as maybeStringifyJSON, index_registerHelpers as registerHelpers, index_registerPartials as registerPartials, index_replaceTemplateString as replaceTemplateString, index_replaceTemplateStringAsync as replaceTemplateStringAsync };
|
|
1181
|
+
export { index_assert as assert, index_asyncCallWithTimeout as asyncCallWithTimeout, index_defineSchema as defineSchema, index_filterObjectOnSchema as filterObjectOnSchema, index_guessProviderFromModel as guessProviderFromModel, index_importHelpers as importHelpers, index_importPartials as importPartials, index_isObjectStringified as isObjectStringified, index_maybeParseJSON as maybeParseJSON, index_maybeStringifyJSON as maybeStringifyJSON, index_registerHelpers as registerHelpers, index_registerPartials as registerPartials, index_replaceTemplateString as replaceTemplateString, index_replaceTemplateStringAsync as replaceTemplateStringAsync };
|
|
1174
1182
|
}
|
|
1175
1183
|
|
|
1176
1184
|
declare const configs: {
|
|
1185
|
+
"ollama.chat.v1": Config<keyof AllLlm>;
|
|
1177
1186
|
"xai.chat.v1": Config<keyof AllLlm>;
|
|
1178
1187
|
"xai.grok-2": Config<keyof AllLlm>;
|
|
1179
1188
|
"amazon:anthropic.chat.v1": Config<keyof AllLlm>;
|
package/dist/index.d.ts
CHANGED
|
@@ -955,7 +955,10 @@ type AllLlm = {
|
|
|
955
955
|
input: AmazonBedrockRequest;
|
|
956
956
|
};
|
|
957
957
|
"xai.chat.v1": {
|
|
958
|
-
input:
|
|
958
|
+
input: GenericLLm;
|
|
959
|
+
};
|
|
960
|
+
"ollama.chat.v1": {
|
|
961
|
+
input: GenericLLm;
|
|
959
962
|
};
|
|
960
963
|
};
|
|
961
964
|
type AllUseLlmOptions = AllLlm & {
|
|
@@ -1000,7 +1003,7 @@ interface BaseRequest<_T extends Record<string, any>> {
|
|
|
1000
1003
|
interface BaseLlm<_T extends BaseLlCall = BaseLlCall> extends BaseRequest<_T> {
|
|
1001
1004
|
}
|
|
1002
1005
|
|
|
1003
|
-
type LlmProvider = "openai.chat" | "openai.embedding" | "openai.chat-mock" | "anthropic.chat" | "amazon:anthropic.chat" | "amazon:meta.chat" | "amazon:nova.chat" | "amazon.embedding" | "xai.chat";
|
|
1006
|
+
type LlmProvider = "openai.chat" | "openai.embedding" | "openai.chat-mock" | "anthropic.chat" | "amazon:anthropic.chat" | "amazon:meta.chat" | "amazon:nova.chat" | "amazon.embedding" | "xai.chat" | "ollama.chat";
|
|
1004
1007
|
interface Config<Pk = LlmProviderKey> {
|
|
1005
1008
|
key: Pk;
|
|
1006
1009
|
provider: LlmProvider;
|
|
@@ -1149,6 +1152,10 @@ declare function filterObjectOnSchema(schema: any, doc: any, detach?: any, prope
|
|
|
1149
1152
|
|
|
1150
1153
|
declare const asyncCallWithTimeout: <T = any>(asyncPromise: Promise<T>, timeLimit?: number) => Promise<T>;
|
|
1151
1154
|
|
|
1155
|
+
declare function guessProviderFromModel(payload: {
|
|
1156
|
+
model: string;
|
|
1157
|
+
}): "openai" | "xai" | "bedrock:anthropic" | "anthropic";
|
|
1158
|
+
|
|
1152
1159
|
declare const maybeStringifyJSON: (objOrMaybeString: any) => string;
|
|
1153
1160
|
declare const maybeParseJSON: <Expected = any>(objOrMaybeJSON: any) => Expected;
|
|
1154
1161
|
declare function isObjectStringified(maybeObject: string): boolean;
|
|
@@ -1160,6 +1167,7 @@ declare const index_assert: typeof assert;
|
|
|
1160
1167
|
declare const index_asyncCallWithTimeout: typeof asyncCallWithTimeout;
|
|
1161
1168
|
declare const index_defineSchema: typeof defineSchema;
|
|
1162
1169
|
declare const index_filterObjectOnSchema: typeof filterObjectOnSchema;
|
|
1170
|
+
declare const index_guessProviderFromModel: typeof guessProviderFromModel;
|
|
1163
1171
|
declare const index_importHelpers: typeof importHelpers;
|
|
1164
1172
|
declare const index_importPartials: typeof importPartials;
|
|
1165
1173
|
declare const index_isObjectStringified: typeof isObjectStringified;
|
|
@@ -1170,10 +1178,11 @@ declare const index_registerPartials: typeof registerPartials;
|
|
|
1170
1178
|
declare const index_replaceTemplateString: typeof replaceTemplateString;
|
|
1171
1179
|
declare const index_replaceTemplateStringAsync: typeof replaceTemplateStringAsync;
|
|
1172
1180
|
declare namespace index {
|
|
1173
|
-
export { index_assert as assert, index_asyncCallWithTimeout as asyncCallWithTimeout, index_defineSchema as defineSchema, index_filterObjectOnSchema as filterObjectOnSchema, index_importHelpers as importHelpers, index_importPartials as importPartials, index_isObjectStringified as isObjectStringified, index_maybeParseJSON as maybeParseJSON, index_maybeStringifyJSON as maybeStringifyJSON, index_registerHelpers as registerHelpers, index_registerPartials as registerPartials, index_replaceTemplateString as replaceTemplateString, index_replaceTemplateStringAsync as replaceTemplateStringAsync };
|
|
1181
|
+
export { index_assert as assert, index_asyncCallWithTimeout as asyncCallWithTimeout, index_defineSchema as defineSchema, index_filterObjectOnSchema as filterObjectOnSchema, index_guessProviderFromModel as guessProviderFromModel, index_importHelpers as importHelpers, index_importPartials as importPartials, index_isObjectStringified as isObjectStringified, index_maybeParseJSON as maybeParseJSON, index_maybeStringifyJSON as maybeStringifyJSON, index_registerHelpers as registerHelpers, index_registerPartials as registerPartials, index_replaceTemplateString as replaceTemplateString, index_replaceTemplateStringAsync as replaceTemplateStringAsync };
|
|
1174
1182
|
}
|
|
1175
1183
|
|
|
1176
1184
|
declare const configs: {
|
|
1185
|
+
"ollama.chat.v1": Config<keyof AllLlm>;
|
|
1177
1186
|
"xai.chat.v1": Config<keyof AllLlm>;
|
|
1178
1187
|
"xai.grok-2": Config<keyof AllLlm>;
|
|
1179
1188
|
"amazon:anthropic.chat.v1": Config<keyof AllLlm>;
|
package/dist/index.js
CHANGED
|
@@ -429,6 +429,7 @@ __export(utils_exports, {
|
|
|
429
429
|
asyncCallWithTimeout: () => asyncCallWithTimeout,
|
|
430
430
|
defineSchema: () => defineSchema,
|
|
431
431
|
filterObjectOnSchema: () => filterObjectOnSchema,
|
|
432
|
+
guessProviderFromModel: () => guessProviderFromModel,
|
|
432
433
|
importHelpers: () => importHelpers,
|
|
433
434
|
importPartials: () => importPartials,
|
|
434
435
|
isObjectStringified: () => isObjectStringified,
|
|
@@ -1403,6 +1404,61 @@ var asyncCallWithTimeout = /* @__PURE__ */ __name(async (asyncPromise, timeLimit
|
|
|
1403
1404
|
});
|
|
1404
1405
|
}, "asyncCallWithTimeout");
|
|
1405
1406
|
|
|
1407
|
+
// src/utils/modules/guessProviderFromModel.ts
|
|
1408
|
+
function isModelKnownOpenAi(payload) {
|
|
1409
|
+
const model = payload.model.toLowerCase();
|
|
1410
|
+
if (model.startsWith("gpt-") || model.startsWith("chatgpt-")) {
|
|
1411
|
+
return true;
|
|
1412
|
+
}
|
|
1413
|
+
if (model === "o1" || model.startsWith("o1-")) {
|
|
1414
|
+
return true;
|
|
1415
|
+
}
|
|
1416
|
+
if (model === "o3-mini") {
|
|
1417
|
+
return true;
|
|
1418
|
+
}
|
|
1419
|
+
return false;
|
|
1420
|
+
}
|
|
1421
|
+
__name(isModelKnownOpenAi, "isModelKnownOpenAi");
|
|
1422
|
+
function isModelKnownAnthropic(payload) {
|
|
1423
|
+
const model = payload.model.toLowerCase();
|
|
1424
|
+
if (model.startsWith("claude-")) {
|
|
1425
|
+
return true;
|
|
1426
|
+
}
|
|
1427
|
+
return false;
|
|
1428
|
+
}
|
|
1429
|
+
__name(isModelKnownAnthropic, "isModelKnownAnthropic");
|
|
1430
|
+
function isModelKnownXai(payload) {
|
|
1431
|
+
const model = payload.model.toLowerCase();
|
|
1432
|
+
if (model.startsWith("grok-")) {
|
|
1433
|
+
return true;
|
|
1434
|
+
}
|
|
1435
|
+
return false;
|
|
1436
|
+
}
|
|
1437
|
+
__name(isModelKnownXai, "isModelKnownXai");
|
|
1438
|
+
function isModelKnownBedrockAnthropic(payload) {
|
|
1439
|
+
const model = payload.model.toLowerCase();
|
|
1440
|
+
if (model.startsWith("anthropic.claude-")) {
|
|
1441
|
+
return true;
|
|
1442
|
+
}
|
|
1443
|
+
return false;
|
|
1444
|
+
}
|
|
1445
|
+
__name(isModelKnownBedrockAnthropic, "isModelKnownBedrockAnthropic");
|
|
1446
|
+
function guessProviderFromModel(payload) {
|
|
1447
|
+
switch (true) {
|
|
1448
|
+
case isModelKnownOpenAi(payload):
|
|
1449
|
+
return "openai";
|
|
1450
|
+
case isModelKnownXai(payload):
|
|
1451
|
+
return "xai";
|
|
1452
|
+
case isModelKnownBedrockAnthropic(payload):
|
|
1453
|
+
return "bedrock:anthropic";
|
|
1454
|
+
case isModelKnownAnthropic(payload):
|
|
1455
|
+
return "anthropic";
|
|
1456
|
+
default:
|
|
1457
|
+
throw new Error("Unsupported model");
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
__name(guessProviderFromModel, "guessProviderFromModel");
|
|
1461
|
+
|
|
1406
1462
|
// src/utils/modules/index.ts
|
|
1407
1463
|
function registerHelpers(helpers) {
|
|
1408
1464
|
hbs.registerHelpers(helpers);
|
|
@@ -2342,12 +2398,47 @@ var xai = {
|
|
|
2342
2398
|
"xai.grok-2": withDefaultModel(xaiChatV1, "grok-2-latest")
|
|
2343
2399
|
};
|
|
2344
2400
|
|
|
2401
|
+
// src/llm/config/ollama/index.ts
|
|
2402
|
+
var ollamaChatV1 = {
|
|
2403
|
+
key: "ollama.chat.v1",
|
|
2404
|
+
provider: "ollama.chat",
|
|
2405
|
+
endpoint: `${getEnvironmentVariable("OLLAMA_ENDPOINT") || `http://localhost:11434`}/api/chat`,
|
|
2406
|
+
options: {
|
|
2407
|
+
prompt: {}
|
|
2408
|
+
},
|
|
2409
|
+
method: "POST",
|
|
2410
|
+
headers: `{"Content-Type": "application/json" }`,
|
|
2411
|
+
mapBody: {
|
|
2412
|
+
prompt: {
|
|
2413
|
+
key: "messages",
|
|
2414
|
+
sanitize: /* @__PURE__ */ __name((v) => {
|
|
2415
|
+
if (typeof v === "string") {
|
|
2416
|
+
return [
|
|
2417
|
+
{
|
|
2418
|
+
role: "user",
|
|
2419
|
+
content: v
|
|
2420
|
+
}
|
|
2421
|
+
];
|
|
2422
|
+
}
|
|
2423
|
+
return v;
|
|
2424
|
+
}, "sanitize")
|
|
2425
|
+
},
|
|
2426
|
+
model: {
|
|
2427
|
+
key: "model"
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
};
|
|
2431
|
+
var ollama = {
|
|
2432
|
+
"ollama.chat.v1": ollamaChatV1
|
|
2433
|
+
};
|
|
2434
|
+
|
|
2345
2435
|
// src/llm/config.ts
|
|
2346
2436
|
var configs = {
|
|
2347
2437
|
...openai,
|
|
2348
2438
|
...anthropic,
|
|
2349
2439
|
...bedrock,
|
|
2350
|
-
...xai
|
|
2440
|
+
...xai,
|
|
2441
|
+
...ollama
|
|
2351
2442
|
};
|
|
2352
2443
|
function getLlmConfig(provider) {
|
|
2353
2444
|
const pick2 = configs[provider];
|
|
@@ -2626,6 +2717,80 @@ function OutputXAIChat(result, _config) {
|
|
|
2626
2717
|
}
|
|
2627
2718
|
__name(OutputXAIChat, "OutputXAIChat");
|
|
2628
2719
|
|
|
2720
|
+
// src/llm/output/_utils/combineJsonl.ts
|
|
2721
|
+
function combineJsonl(jsonl) {
|
|
2722
|
+
const lines = jsonl.trim().split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
|
|
2723
|
+
try {
|
|
2724
|
+
return JSON.parse(line);
|
|
2725
|
+
} catch (e) {
|
|
2726
|
+
throw new Error(`Invalid JSON: ${line}`);
|
|
2727
|
+
}
|
|
2728
|
+
});
|
|
2729
|
+
if (lines.length === 0) {
|
|
2730
|
+
throw new Error("No JSON lines provided.");
|
|
2731
|
+
}
|
|
2732
|
+
lines.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
2733
|
+
let combinedContent = lines.map((line) => line?.message?.content ?? "").join("");
|
|
2734
|
+
combinedContent = combinedContent.replace(/\\u003c/g, "<").replace(/\\u003e/g, ">");
|
|
2735
|
+
const finalLine = lines.find((line) => line.done === true);
|
|
2736
|
+
if (!finalLine) {
|
|
2737
|
+
throw new Error("No line found where done = true.");
|
|
2738
|
+
}
|
|
2739
|
+
const result = {
|
|
2740
|
+
model: finalLine.model,
|
|
2741
|
+
created_at: finalLine.created_at,
|
|
2742
|
+
message: {
|
|
2743
|
+
role: finalLine?.message?.role || "assistant",
|
|
2744
|
+
content: combinedContent
|
|
2745
|
+
},
|
|
2746
|
+
done_reason: finalLine.done_reason,
|
|
2747
|
+
done: finalLine.done,
|
|
2748
|
+
total_duration: finalLine.total_duration,
|
|
2749
|
+
load_duration: finalLine.load_duration,
|
|
2750
|
+
prompt_eval_count: finalLine.prompt_eval_count,
|
|
2751
|
+
prompt_eval_duration: finalLine.prompt_eval_duration,
|
|
2752
|
+
eval_count: finalLine.eval_count,
|
|
2753
|
+
eval_duration: finalLine.eval_duration
|
|
2754
|
+
};
|
|
2755
|
+
const content = {
|
|
2756
|
+
type: "text",
|
|
2757
|
+
text: combinedContent
|
|
2758
|
+
};
|
|
2759
|
+
return {
|
|
2760
|
+
lines,
|
|
2761
|
+
result,
|
|
2762
|
+
content
|
|
2763
|
+
};
|
|
2764
|
+
}
|
|
2765
|
+
__name(combineJsonl, "combineJsonl");
|
|
2766
|
+
|
|
2767
|
+
// src/llm/output/ollama.ts
|
|
2768
|
+
function OutputOllamaChat(result, _config) {
|
|
2769
|
+
const combined = combineJsonl(result);
|
|
2770
|
+
const id = `${combined.result.model}.${combined.result.created_at}`;
|
|
2771
|
+
const name = combined.result.model || _config?.model || "ollama.unknown";
|
|
2772
|
+
const created = (/* @__PURE__ */ new Date(`${combined.result.created_at}`)).getTime();
|
|
2773
|
+
const stopReason = `${combined?.result?.done_reason || "stop"}`;
|
|
2774
|
+
const content = [
|
|
2775
|
+
combined.content
|
|
2776
|
+
];
|
|
2777
|
+
const usage = {
|
|
2778
|
+
output_tokens: 0,
|
|
2779
|
+
input_tokens: 0,
|
|
2780
|
+
total_tokens: 0
|
|
2781
|
+
};
|
|
2782
|
+
return BaseLlmOutput2({
|
|
2783
|
+
id,
|
|
2784
|
+
name,
|
|
2785
|
+
created,
|
|
2786
|
+
usage,
|
|
2787
|
+
stopReason,
|
|
2788
|
+
content,
|
|
2789
|
+
options: []
|
|
2790
|
+
});
|
|
2791
|
+
}
|
|
2792
|
+
__name(OutputOllamaChat, "OutputOllamaChat");
|
|
2793
|
+
|
|
2629
2794
|
// src/llm/output/index.ts
|
|
2630
2795
|
function getOutputParser(config, response) {
|
|
2631
2796
|
switch (config?.key) {
|
|
@@ -2641,6 +2806,8 @@ function getOutputParser(config, response) {
|
|
|
2641
2806
|
// return OutputDefault(response, config);
|
|
2642
2807
|
case "xai.chat.v1":
|
|
2643
2808
|
return OutputXAIChat(response, config);
|
|
2809
|
+
case "ollama.chat.v1":
|
|
2810
|
+
return OutputOllamaChat(response, config);
|
|
2644
2811
|
default: {
|
|
2645
2812
|
if (config?.key?.startsWith("custom:")) {
|
|
2646
2813
|
return OutputDefault(response, config);
|
|
@@ -2651,12 +2818,26 @@ function getOutputParser(config, response) {
|
|
|
2651
2818
|
}
|
|
2652
2819
|
__name(getOutputParser, "getOutputParser");
|
|
2653
2820
|
|
|
2821
|
+
// src/utils/modules/isValidUrl.ts
|
|
2822
|
+
function isValidUrl(input) {
|
|
2823
|
+
try {
|
|
2824
|
+
new URL(input);
|
|
2825
|
+
return true;
|
|
2826
|
+
} catch {
|
|
2827
|
+
return false;
|
|
2828
|
+
}
|
|
2829
|
+
}
|
|
2830
|
+
__name(isValidUrl, "isValidUrl");
|
|
2831
|
+
|
|
2654
2832
|
// src/utils/modules/request.ts
|
|
2655
2833
|
async function apiRequest(url, options) {
|
|
2656
2834
|
const finalOptions = {
|
|
2657
2835
|
...options
|
|
2658
2836
|
};
|
|
2659
2837
|
try {
|
|
2838
|
+
if (!url || !isValidUrl(url)) {
|
|
2839
|
+
throw new Error("Invalid URL");
|
|
2840
|
+
}
|
|
2660
2841
|
const response = await fetch(url, finalOptions);
|
|
2661
2842
|
if (!response.ok) {
|
|
2662
2843
|
let message = `HTTP error. Status: ${response.status}. Error Message: ${response?.statusText || "Unknown error."}`;
|
|
@@ -2669,8 +2850,13 @@ async function apiRequest(url, options) {
|
|
|
2669
2850
|
}
|
|
2670
2851
|
throw new Error(message);
|
|
2671
2852
|
}
|
|
2672
|
-
|
|
2673
|
-
|
|
2853
|
+
if (response.headers.get("content-type")?.includes("application/json")) {
|
|
2854
|
+
const responseData = await response.json();
|
|
2855
|
+
return responseData;
|
|
2856
|
+
} else {
|
|
2857
|
+
const responseData = await response.text();
|
|
2858
|
+
return responseData;
|
|
2859
|
+
}
|
|
2674
2860
|
} catch (error) {
|
|
2675
2861
|
const message = error instanceof Error ? error.message : "Error";
|
|
2676
2862
|
throw new Error(`Request to ${url} failed: ${message}`);
|
package/dist/index.mjs
CHANGED
|
@@ -381,6 +381,7 @@ __export(utils_exports, {
|
|
|
381
381
|
asyncCallWithTimeout: () => asyncCallWithTimeout,
|
|
382
382
|
defineSchema: () => defineSchema,
|
|
383
383
|
filterObjectOnSchema: () => filterObjectOnSchema,
|
|
384
|
+
guessProviderFromModel: () => guessProviderFromModel,
|
|
384
385
|
importHelpers: () => importHelpers,
|
|
385
386
|
importPartials: () => importPartials,
|
|
386
387
|
isObjectStringified: () => isObjectStringified,
|
|
@@ -1355,6 +1356,61 @@ var asyncCallWithTimeout = /* @__PURE__ */ __name(async (asyncPromise, timeLimit
|
|
|
1355
1356
|
});
|
|
1356
1357
|
}, "asyncCallWithTimeout");
|
|
1357
1358
|
|
|
1359
|
+
// src/utils/modules/guessProviderFromModel.ts
|
|
1360
|
+
function isModelKnownOpenAi(payload) {
|
|
1361
|
+
const model = payload.model.toLowerCase();
|
|
1362
|
+
if (model.startsWith("gpt-") || model.startsWith("chatgpt-")) {
|
|
1363
|
+
return true;
|
|
1364
|
+
}
|
|
1365
|
+
if (model === "o1" || model.startsWith("o1-")) {
|
|
1366
|
+
return true;
|
|
1367
|
+
}
|
|
1368
|
+
if (model === "o3-mini") {
|
|
1369
|
+
return true;
|
|
1370
|
+
}
|
|
1371
|
+
return false;
|
|
1372
|
+
}
|
|
1373
|
+
__name(isModelKnownOpenAi, "isModelKnownOpenAi");
|
|
1374
|
+
function isModelKnownAnthropic(payload) {
|
|
1375
|
+
const model = payload.model.toLowerCase();
|
|
1376
|
+
if (model.startsWith("claude-")) {
|
|
1377
|
+
return true;
|
|
1378
|
+
}
|
|
1379
|
+
return false;
|
|
1380
|
+
}
|
|
1381
|
+
__name(isModelKnownAnthropic, "isModelKnownAnthropic");
|
|
1382
|
+
function isModelKnownXai(payload) {
|
|
1383
|
+
const model = payload.model.toLowerCase();
|
|
1384
|
+
if (model.startsWith("grok-")) {
|
|
1385
|
+
return true;
|
|
1386
|
+
}
|
|
1387
|
+
return false;
|
|
1388
|
+
}
|
|
1389
|
+
__name(isModelKnownXai, "isModelKnownXai");
|
|
1390
|
+
function isModelKnownBedrockAnthropic(payload) {
|
|
1391
|
+
const model = payload.model.toLowerCase();
|
|
1392
|
+
if (model.startsWith("anthropic.claude-")) {
|
|
1393
|
+
return true;
|
|
1394
|
+
}
|
|
1395
|
+
return false;
|
|
1396
|
+
}
|
|
1397
|
+
__name(isModelKnownBedrockAnthropic, "isModelKnownBedrockAnthropic");
|
|
1398
|
+
function guessProviderFromModel(payload) {
|
|
1399
|
+
switch (true) {
|
|
1400
|
+
case isModelKnownOpenAi(payload):
|
|
1401
|
+
return "openai";
|
|
1402
|
+
case isModelKnownXai(payload):
|
|
1403
|
+
return "xai";
|
|
1404
|
+
case isModelKnownBedrockAnthropic(payload):
|
|
1405
|
+
return "bedrock:anthropic";
|
|
1406
|
+
case isModelKnownAnthropic(payload):
|
|
1407
|
+
return "anthropic";
|
|
1408
|
+
default:
|
|
1409
|
+
throw new Error("Unsupported model");
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
__name(guessProviderFromModel, "guessProviderFromModel");
|
|
1413
|
+
|
|
1358
1414
|
// src/utils/modules/index.ts
|
|
1359
1415
|
function registerHelpers(helpers) {
|
|
1360
1416
|
hbs.registerHelpers(helpers);
|
|
@@ -2294,12 +2350,47 @@ var xai = {
|
|
|
2294
2350
|
"xai.grok-2": withDefaultModel(xaiChatV1, "grok-2-latest")
|
|
2295
2351
|
};
|
|
2296
2352
|
|
|
2353
|
+
// src/llm/config/ollama/index.ts
|
|
2354
|
+
var ollamaChatV1 = {
|
|
2355
|
+
key: "ollama.chat.v1",
|
|
2356
|
+
provider: "ollama.chat",
|
|
2357
|
+
endpoint: `${getEnvironmentVariable("OLLAMA_ENDPOINT") || `http://localhost:11434`}/api/chat`,
|
|
2358
|
+
options: {
|
|
2359
|
+
prompt: {}
|
|
2360
|
+
},
|
|
2361
|
+
method: "POST",
|
|
2362
|
+
headers: `{"Content-Type": "application/json" }`,
|
|
2363
|
+
mapBody: {
|
|
2364
|
+
prompt: {
|
|
2365
|
+
key: "messages",
|
|
2366
|
+
sanitize: /* @__PURE__ */ __name((v) => {
|
|
2367
|
+
if (typeof v === "string") {
|
|
2368
|
+
return [
|
|
2369
|
+
{
|
|
2370
|
+
role: "user",
|
|
2371
|
+
content: v
|
|
2372
|
+
}
|
|
2373
|
+
];
|
|
2374
|
+
}
|
|
2375
|
+
return v;
|
|
2376
|
+
}, "sanitize")
|
|
2377
|
+
},
|
|
2378
|
+
model: {
|
|
2379
|
+
key: "model"
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
};
|
|
2383
|
+
var ollama = {
|
|
2384
|
+
"ollama.chat.v1": ollamaChatV1
|
|
2385
|
+
};
|
|
2386
|
+
|
|
2297
2387
|
// src/llm/config.ts
|
|
2298
2388
|
var configs = {
|
|
2299
2389
|
...openai,
|
|
2300
2390
|
...anthropic,
|
|
2301
2391
|
...bedrock,
|
|
2302
|
-
...xai
|
|
2392
|
+
...xai,
|
|
2393
|
+
...ollama
|
|
2303
2394
|
};
|
|
2304
2395
|
function getLlmConfig(provider) {
|
|
2305
2396
|
const pick2 = configs[provider];
|
|
@@ -2578,6 +2669,80 @@ function OutputXAIChat(result, _config) {
|
|
|
2578
2669
|
}
|
|
2579
2670
|
__name(OutputXAIChat, "OutputXAIChat");
|
|
2580
2671
|
|
|
2672
|
+
// src/llm/output/_utils/combineJsonl.ts
|
|
2673
|
+
function combineJsonl(jsonl) {
|
|
2674
|
+
const lines = jsonl.trim().split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
|
|
2675
|
+
try {
|
|
2676
|
+
return JSON.parse(line);
|
|
2677
|
+
} catch (e) {
|
|
2678
|
+
throw new Error(`Invalid JSON: ${line}`);
|
|
2679
|
+
}
|
|
2680
|
+
});
|
|
2681
|
+
if (lines.length === 0) {
|
|
2682
|
+
throw new Error("No JSON lines provided.");
|
|
2683
|
+
}
|
|
2684
|
+
lines.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
2685
|
+
let combinedContent = lines.map((line) => line?.message?.content ?? "").join("");
|
|
2686
|
+
combinedContent = combinedContent.replace(/\\u003c/g, "<").replace(/\\u003e/g, ">");
|
|
2687
|
+
const finalLine = lines.find((line) => line.done === true);
|
|
2688
|
+
if (!finalLine) {
|
|
2689
|
+
throw new Error("No line found where done = true.");
|
|
2690
|
+
}
|
|
2691
|
+
const result = {
|
|
2692
|
+
model: finalLine.model,
|
|
2693
|
+
created_at: finalLine.created_at,
|
|
2694
|
+
message: {
|
|
2695
|
+
role: finalLine?.message?.role || "assistant",
|
|
2696
|
+
content: combinedContent
|
|
2697
|
+
},
|
|
2698
|
+
done_reason: finalLine.done_reason,
|
|
2699
|
+
done: finalLine.done,
|
|
2700
|
+
total_duration: finalLine.total_duration,
|
|
2701
|
+
load_duration: finalLine.load_duration,
|
|
2702
|
+
prompt_eval_count: finalLine.prompt_eval_count,
|
|
2703
|
+
prompt_eval_duration: finalLine.prompt_eval_duration,
|
|
2704
|
+
eval_count: finalLine.eval_count,
|
|
2705
|
+
eval_duration: finalLine.eval_duration
|
|
2706
|
+
};
|
|
2707
|
+
const content = {
|
|
2708
|
+
type: "text",
|
|
2709
|
+
text: combinedContent
|
|
2710
|
+
};
|
|
2711
|
+
return {
|
|
2712
|
+
lines,
|
|
2713
|
+
result,
|
|
2714
|
+
content
|
|
2715
|
+
};
|
|
2716
|
+
}
|
|
2717
|
+
__name(combineJsonl, "combineJsonl");
|
|
2718
|
+
|
|
2719
|
+
// src/llm/output/ollama.ts
|
|
2720
|
+
function OutputOllamaChat(result, _config) {
|
|
2721
|
+
const combined = combineJsonl(result);
|
|
2722
|
+
const id = `${combined.result.model}.${combined.result.created_at}`;
|
|
2723
|
+
const name = combined.result.model || _config?.model || "ollama.unknown";
|
|
2724
|
+
const created = (/* @__PURE__ */ new Date(`${combined.result.created_at}`)).getTime();
|
|
2725
|
+
const stopReason = `${combined?.result?.done_reason || "stop"}`;
|
|
2726
|
+
const content = [
|
|
2727
|
+
combined.content
|
|
2728
|
+
];
|
|
2729
|
+
const usage = {
|
|
2730
|
+
output_tokens: 0,
|
|
2731
|
+
input_tokens: 0,
|
|
2732
|
+
total_tokens: 0
|
|
2733
|
+
};
|
|
2734
|
+
return BaseLlmOutput2({
|
|
2735
|
+
id,
|
|
2736
|
+
name,
|
|
2737
|
+
created,
|
|
2738
|
+
usage,
|
|
2739
|
+
stopReason,
|
|
2740
|
+
content,
|
|
2741
|
+
options: []
|
|
2742
|
+
});
|
|
2743
|
+
}
|
|
2744
|
+
__name(OutputOllamaChat, "OutputOllamaChat");
|
|
2745
|
+
|
|
2581
2746
|
// src/llm/output/index.ts
|
|
2582
2747
|
function getOutputParser(config, response) {
|
|
2583
2748
|
switch (config?.key) {
|
|
@@ -2593,6 +2758,8 @@ function getOutputParser(config, response) {
|
|
|
2593
2758
|
// return OutputDefault(response, config);
|
|
2594
2759
|
case "xai.chat.v1":
|
|
2595
2760
|
return OutputXAIChat(response, config);
|
|
2761
|
+
case "ollama.chat.v1":
|
|
2762
|
+
return OutputOllamaChat(response, config);
|
|
2596
2763
|
default: {
|
|
2597
2764
|
if (config?.key?.startsWith("custom:")) {
|
|
2598
2765
|
return OutputDefault(response, config);
|
|
@@ -2603,12 +2770,26 @@ function getOutputParser(config, response) {
|
|
|
2603
2770
|
}
|
|
2604
2771
|
__name(getOutputParser, "getOutputParser");
|
|
2605
2772
|
|
|
2773
|
+
// src/utils/modules/isValidUrl.ts
|
|
2774
|
+
function isValidUrl(input) {
|
|
2775
|
+
try {
|
|
2776
|
+
new URL(input);
|
|
2777
|
+
return true;
|
|
2778
|
+
} catch {
|
|
2779
|
+
return false;
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2782
|
+
__name(isValidUrl, "isValidUrl");
|
|
2783
|
+
|
|
2606
2784
|
// src/utils/modules/request.ts
|
|
2607
2785
|
async function apiRequest(url, options) {
|
|
2608
2786
|
const finalOptions = {
|
|
2609
2787
|
...options
|
|
2610
2788
|
};
|
|
2611
2789
|
try {
|
|
2790
|
+
if (!url || !isValidUrl(url)) {
|
|
2791
|
+
throw new Error("Invalid URL");
|
|
2792
|
+
}
|
|
2612
2793
|
const response = await fetch(url, finalOptions);
|
|
2613
2794
|
if (!response.ok) {
|
|
2614
2795
|
let message = `HTTP error. Status: ${response.status}. Error Message: ${response?.statusText || "Unknown error."}`;
|
|
@@ -2621,8 +2802,13 @@ async function apiRequest(url, options) {
|
|
|
2621
2802
|
}
|
|
2622
2803
|
throw new Error(message);
|
|
2623
2804
|
}
|
|
2624
|
-
|
|
2625
|
-
|
|
2805
|
+
if (response.headers.get("content-type")?.includes("application/json")) {
|
|
2806
|
+
const responseData = await response.json();
|
|
2807
|
+
return responseData;
|
|
2808
|
+
} else {
|
|
2809
|
+
const responseData = await response.text();
|
|
2810
|
+
return responseData;
|
|
2811
|
+
}
|
|
2626
2812
|
} catch (error) {
|
|
2627
2813
|
const message = error instanceof Error ? error.message : "Error";
|
|
2628
2814
|
throw new Error(`Request to ${url} failed: ${message}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "llm-exe",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.4",
|
|
4
4
|
"description": "Simplify building LLM-powered apps with easy-to-use base components, supporting text and chat-based prompts with handlebars template engine, output parsers, and flexible function calling capabilities.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -45,7 +45,9 @@
|
|
|
45
45
|
"docs:build": "vitepress build docs",
|
|
46
46
|
"lint": "eslint",
|
|
47
47
|
"format:check": "prettier --check \"src\"",
|
|
48
|
-
"format:write": "prettier --write \"src\""
|
|
48
|
+
"format:write": "prettier --write \"src\"",
|
|
49
|
+
"publish-main": "npm publish",
|
|
50
|
+
"publish-beta": "npm publish --tag beta"
|
|
49
51
|
},
|
|
50
52
|
"author": "Greg Reindel",
|
|
51
53
|
"license": "MIT",
|
package/readme.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# llm-exe
|
|
2
2
|
|
|
3
|
-
[](https://github.com/gregreindel/llm-exe/actions/workflows/tests.yml) [](https://coveralls.io/github/gregreindel/llm-exe?branch=main) [](https://badge.fury.io/js/llm-exe)
|
|
4
4
|
|
|
5
5
|
A package that provides simplified base components to make building and maintaining LLM-powered applications easier.
|
|
6
6
|
|
|
7
7
|
- Write functions powered by LLM's with easy to use building blocks.
|
|
8
8
|
- Pure Javascript and Typescript. Allows you to pass and infer types.
|
|
9
|
-
- Support for text-based (llama-3) and chat-based prompts (gpt-4o, claude-3.5, grok-3)
|
|
10
|
-
- Call LLM's from different providers without changing your code. (OpenAi/Anthropic/xAI/AWS Bedrock)
|
|
9
|
+
- Support for text-based (llama-3) and chat-based prompts. (gpt-4o, claude-3.5, grok-3, Bedrock, Ollama, etc)
|
|
10
|
+
- Call LLM's from different providers without changing your code. (OpenAi/Anthropic/xAI/AWS Bedrock/Ollama)
|
|
11
11
|
- Supercharge your prompts by using handlebars within prompt template.
|
|
12
12
|
- Allow LLM's to call functions (or call other LLM executors).
|
|
13
13
|
- Not very opinionated. You have control on how you use it.
|