@anvaka/vue-llm 0.2.0 → 0.3.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.
- package/README.md +64 -3
- package/dist/core/LLMClient.js +92 -63
- package/dist/index.js +37 -29
- package/dist/pricing/calculate.js +58 -0
- package/dist/pricing/index.js +10 -0
- package/dist/pricing/rates.js +80 -0
- package/dist/providers/AnthropicProvider.js +35 -26
- package/dist/providers/BaseProvider.js +84 -74
- package/dist/providers/CustomProvider.js +69 -28
- package/dist/providers/DeepSeekProvider.js +115 -0
- package/dist/providers/GeminiProvider.js +143 -111
- package/dist/providers/GrokProvider.js +75 -38
- package/dist/providers/LlamaServerProvider.js +72 -31
- package/dist/providers/OllamaProvider.js +117 -41
- package/dist/providers/OpenAIProvider.js +64 -57
- package/dist/providers/OpenRouterProvider.js +40 -40
- package/dist/providers/factory.js +12 -7
- package/dist/providers/index.js +10 -8
- package/package.json +7 -2
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import { BaseProvider as
|
|
2
|
-
class
|
|
1
|
+
import { BaseProvider as C } from "./BaseProvider.js";
|
|
2
|
+
class A extends C {
|
|
3
3
|
async detectCapabilities() {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
const t = this.config.model;
|
|
5
|
+
if (!t) return;
|
|
6
|
+
const e = t.match(/gemini-(\d+)\.(\d+)/), s = e ? Number(e[1]) : null, n = e ? Number(e[2]) : null, i = (a, o) => s != null && (s > a || s === a && n >= o);
|
|
7
|
+
(t.includes("gemini-pro-vision") || i(1, 5)) && this.capabilities.add("vision"), (t.includes("gemini-pro") || i(1, 5)) && this.capabilities.add("tools"), i(2, 0) && this.capabilities.add("thinking");
|
|
8
|
+
}
|
|
9
|
+
prepareRequest(t, e) {
|
|
10
|
+
const s = this.processMessages(t, e), n = {
|
|
11
|
+
contents: this.convertToGeminiFormat(s),
|
|
9
12
|
generationConfig: {
|
|
10
|
-
temperature:
|
|
11
|
-
maxOutputTokens:
|
|
13
|
+
temperature: e.temperature ?? this.config.temperature ?? 0.7,
|
|
14
|
+
maxOutputTokens: e.maxTokens || this.config.maxTokens || 1e3,
|
|
12
15
|
topP: 0.8,
|
|
13
16
|
topK: 10
|
|
14
17
|
},
|
|
@@ -18,117 +21,130 @@ class _ extends A {
|
|
|
18
21
|
{ category: "HARM_CATEGORY_SEXUALLY_EXPLICIT", threshold: "BLOCK_NONE" },
|
|
19
22
|
{ category: "HARM_CATEGORY_DANGEROUS_CONTENT", threshold: "BLOCK_NONE" }
|
|
20
23
|
]
|
|
21
|
-
}, i =
|
|
22
|
-
return i && (
|
|
24
|
+
}, i = t.find((a) => a.role === "system");
|
|
25
|
+
return i && (n.systemInstruction = { parts: [{ text: i.content }] }), e.tools && this.capabilities.has("tools") && (n.tools = this.convertToolsToGeminiFormat(e.tools)), n;
|
|
26
|
+
}
|
|
27
|
+
// Build a {tool_call_id -> function name} index from prior assistant
|
|
28
|
+
// messages so tool-result messages can be reshaped into Gemini's
|
|
29
|
+
// functionResponse (which requires the function name to match).
|
|
30
|
+
buildToolCallNameIndex(t) {
|
|
31
|
+
const e = /* @__PURE__ */ new Map();
|
|
32
|
+
for (const s of t)
|
|
33
|
+
if (s.role === "assistant" && Array.isArray(s.tool_calls))
|
|
34
|
+
for (const n of s.tool_calls)
|
|
35
|
+
n.id && e.set(n.id, n.name);
|
|
36
|
+
return e;
|
|
23
37
|
}
|
|
24
|
-
convertToGeminiFormat(
|
|
25
|
-
const t = [];
|
|
26
|
-
for (const n of
|
|
38
|
+
convertToGeminiFormat(t) {
|
|
39
|
+
const e = this.buildToolCallNameIndex(t), s = [];
|
|
40
|
+
for (const n of t) {
|
|
27
41
|
if (n.role === "system") continue;
|
|
28
|
-
|
|
42
|
+
if (n.role === "tool") {
|
|
43
|
+
const a = n.name || e.get(n.tool_call_id) || "unknown";
|
|
44
|
+
let o = n.content;
|
|
45
|
+
if (typeof o == "string")
|
|
46
|
+
try {
|
|
47
|
+
const l = JSON.parse(o);
|
|
48
|
+
o = l !== null && typeof l == "object" && !Array.isArray(l) ? l : { result: l };
|
|
49
|
+
} catch {
|
|
50
|
+
o = { result: n.content };
|
|
51
|
+
}
|
|
52
|
+
else (o === null || typeof o != "object" || Array.isArray(o)) && (o = { result: o });
|
|
53
|
+
s.push({
|
|
54
|
+
role: "user",
|
|
55
|
+
parts: [{ functionResponse: { name: a, response: o } }]
|
|
56
|
+
});
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (n.role === "assistant" && Array.isArray(n.tool_calls) && n.tool_calls.length) {
|
|
60
|
+
const a = [];
|
|
61
|
+
n.content && a.push({ text: String(n.content) });
|
|
62
|
+
for (const o of n.tool_calls)
|
|
63
|
+
a.push({ functionCall: { name: o.name, args: typeof o.args == "string" ? T(o.args) : o.args || {} } });
|
|
64
|
+
s.push({ role: "model", parts: a });
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const i = n.role === "assistant" ? "model" : "user";
|
|
29
68
|
if (Array.isArray(n.content)) {
|
|
30
|
-
const
|
|
31
|
-
var
|
|
32
|
-
return o.type === "text" ? { text: o.text } : o.type === "image" ? { inlineData: { mimeType: ((
|
|
69
|
+
const a = n.content.map((o) => {
|
|
70
|
+
var l, u;
|
|
71
|
+
return o.type === "text" ? { text: o.text } : o.type === "image" ? { inlineData: { mimeType: ((l = o.source) == null ? void 0 : l.media_type) || "image/jpeg", data: ((u = o.source) == null ? void 0 : u.data) || o.data } } : o.type === "image_url" ? { inlineData: { mimeType: "image/jpeg", data: o.image_url.url.split(",")[1] } } : { text: String(o) };
|
|
33
72
|
});
|
|
34
|
-
|
|
73
|
+
s.push({ role: i, parts: a });
|
|
35
74
|
} else
|
|
36
|
-
|
|
75
|
+
s.push({ role: i, parts: [{ text: n.content }] });
|
|
37
76
|
}
|
|
38
|
-
return
|
|
77
|
+
return s;
|
|
39
78
|
}
|
|
40
|
-
processMessages(
|
|
41
|
-
return
|
|
79
|
+
processMessages(t, e) {
|
|
80
|
+
return e.images && this.capabilities.has("vision") ? this.addImagesToMessages(t, e.images) : t;
|
|
42
81
|
}
|
|
43
|
-
addImagesToMessages(
|
|
44
|
-
const
|
|
45
|
-
if (
|
|
46
|
-
const
|
|
47
|
-
|
|
82
|
+
addImagesToMessages(t, e) {
|
|
83
|
+
const s = t[t.length - 1];
|
|
84
|
+
if (s && s.role === "user") {
|
|
85
|
+
const n = [{ type: "text", text: s.content }];
|
|
86
|
+
e.forEach((i) => n.push({ type: "image", data: typeof i == "string" ? i : i.data, mimeType: "image/jpeg" })), s.content = n;
|
|
48
87
|
}
|
|
49
|
-
return
|
|
88
|
+
return t;
|
|
50
89
|
}
|
|
51
|
-
convertToolsToGeminiFormat(
|
|
52
|
-
return
|
|
53
|
-
}
|
|
54
|
-
processResponse(
|
|
55
|
-
var
|
|
56
|
-
const
|
|
57
|
-
if (
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
90
|
+
convertToolsToGeminiFormat(t) {
|
|
91
|
+
return t.map((e) => ({ functionDeclarations: [{ name: e.function.name, description: e.function.description, parameters: e.function.parameters }] }));
|
|
92
|
+
}
|
|
93
|
+
processResponse(t) {
|
|
94
|
+
var s;
|
|
95
|
+
const e = { content: "", usage: null, finishReason: null };
|
|
96
|
+
if (t.candidates && t.candidates.length > 0) {
|
|
97
|
+
const n = t.candidates[0], i = ((s = n.content) == null ? void 0 : s.parts) || [];
|
|
98
|
+
e.content = i.filter((o) => o.text).map((o) => o.text).join("");
|
|
99
|
+
const a = i.filter((o) => o.functionCall).map((o) => o.functionCall);
|
|
100
|
+
a.length && (e.toolCalls = a.map((o, l) => ({
|
|
101
|
+
id: p(l),
|
|
102
|
+
name: o.name,
|
|
103
|
+
args: o.args || {}
|
|
104
|
+
}))), n.finishReason && (e.finishReason = h(n.finishReason));
|
|
64
105
|
}
|
|
65
|
-
return e.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
async streamRequest(e, t, n) {
|
|
72
|
-
const s = this.prepareRequest(e, t), i = new AbortController(), o = t.requestId || this.generateRequestId();
|
|
73
|
-
this.activeRequests.set(o, i);
|
|
106
|
+
return e.usage = y(t.usageMetadata), e;
|
|
107
|
+
}
|
|
108
|
+
parseStreamingLine(t) {
|
|
109
|
+
if (!t.startsWith("data: ")) return null;
|
|
110
|
+
const e = t.slice(6).trim();
|
|
111
|
+
if (!e) return null;
|
|
74
112
|
try {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const { done: y, value: M } = await l.read();
|
|
79
|
-
if (y) break;
|
|
80
|
-
u += m.decode(M, { stream: !0 });
|
|
81
|
-
for (let g = d; g < u.length; g++) {
|
|
82
|
-
const p = u[g];
|
|
83
|
-
if (C) {
|
|
84
|
-
C = !1;
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
if (p === "\\" && h) {
|
|
88
|
-
C = !0;
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
if (p === '"') {
|
|
92
|
-
h = !h;
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
if (!h) {
|
|
96
|
-
if (p === "{")
|
|
97
|
-
f === 0 && (d = g), f++;
|
|
98
|
-
else if (p === "}" && (f--, f === 0)) {
|
|
99
|
-
const x = u.slice(d, g + 1);
|
|
100
|
-
try {
|
|
101
|
-
const b = JSON.parse(x), r = this.extractStreamingContent(b);
|
|
102
|
-
if (r && (r.content && (c += r.content), r.thinking && (R += r.thinking), n({ content: r.content || "", thinking: r.thinking || "", fullContent: c, fullThinking: R, done: r.done || !1, usage: r.usage || null, finishReason: r.finishReason || null }), r.done))
|
|
103
|
-
return c;
|
|
104
|
-
} catch {
|
|
105
|
-
}
|
|
106
|
-
d = g + 1;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
f === 0 && d < u.length && (u = u.slice(d), d = 0);
|
|
111
|
-
}
|
|
112
|
-
return c;
|
|
113
|
-
} catch (a) {
|
|
114
|
-
throw a.name === "AbortError" ? new Error("Request cancelled") : a;
|
|
115
|
-
} finally {
|
|
116
|
-
this.activeRequests.delete(o);
|
|
113
|
+
return JSON.parse(e);
|
|
114
|
+
} catch {
|
|
115
|
+
return null;
|
|
117
116
|
}
|
|
118
117
|
}
|
|
119
|
-
extractStreamingContent(
|
|
120
|
-
var
|
|
121
|
-
if (!((
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
118
|
+
extractStreamingContent(t) {
|
|
119
|
+
var m, d, f;
|
|
120
|
+
if (!((m = t == null ? void 0 : t.candidates) != null && m.length))
|
|
121
|
+
return { content: "", thinking: "", done: !1 };
|
|
122
|
+
const e = t.candidates[0];
|
|
123
|
+
let s = "", n = "", i = !1, a = null;
|
|
124
|
+
const o = ((d = e.content) == null ? void 0 : d.parts) || [];
|
|
125
|
+
s = o.filter((c) => c.text).map((c) => c.text).join("");
|
|
126
|
+
const l = o.filter((c) => c.functionCall).map((c) => c.functionCall);
|
|
127
|
+
e.finishReason && (i = !0, a = h(e.finishReason)), ((f = t.usageMetadata) == null ? void 0 : f.thoughtsTokenCount) > 0 && (n = `[Thinking: ${t.usageMetadata.thoughtsTokenCount} tokens]`);
|
|
128
|
+
const u = {
|
|
129
|
+
content: s,
|
|
130
|
+
thinking: n,
|
|
131
|
+
done: i,
|
|
132
|
+
usage: y(t.usageMetadata),
|
|
133
|
+
finishReason: a
|
|
134
|
+
};
|
|
135
|
+
return l.length && (u.toolCallDeltas = l.map((c, g) => ({
|
|
136
|
+
index: g,
|
|
137
|
+
id: p(g),
|
|
138
|
+
name: c.name || "",
|
|
139
|
+
argsTextDelta: JSON.stringify(c.args ?? {})
|
|
140
|
+
}))), u;
|
|
125
141
|
}
|
|
126
142
|
getApiPath() {
|
|
127
143
|
return `/v1beta/models/${this.config.model || "gemini-pro"}:generateContent`;
|
|
128
144
|
}
|
|
129
145
|
getStreamingEndpoint() {
|
|
130
|
-
const
|
|
131
|
-
return `${this.config.baseUrl}/v1beta/models/${
|
|
146
|
+
const t = this.config.model || "gemini-pro";
|
|
147
|
+
return `${this.config.baseUrl}/v1beta/models/${t}:streamGenerateContent?alt=sse`;
|
|
132
148
|
}
|
|
133
149
|
requiresAuth() {
|
|
134
150
|
return !!this.config.apiKey;
|
|
@@ -145,19 +161,35 @@ class _ extends A {
|
|
|
145
161
|
getModelsEndpoint() {
|
|
146
162
|
return `${this.config.baseUrl}/v1beta/models`;
|
|
147
163
|
}
|
|
148
|
-
parseModelsResponse(
|
|
149
|
-
var
|
|
150
|
-
return ((
|
|
164
|
+
parseModelsResponse(t) {
|
|
165
|
+
var e;
|
|
166
|
+
return ((e = t.models) == null ? void 0 : e.filter((s) => {
|
|
151
167
|
var i;
|
|
152
|
-
return
|
|
153
|
-
}).map((
|
|
168
|
+
return s.name.toLowerCase().includes("gemini") && ((i = s.supportedGenerationMethods) == null ? void 0 : i.includes("generateContent"));
|
|
169
|
+
}).map((s) => s.name.split("/").pop()).sort()) || [];
|
|
154
170
|
}
|
|
155
171
|
}
|
|
156
|
-
function
|
|
157
|
-
if (!
|
|
158
|
-
const
|
|
159
|
-
return
|
|
172
|
+
function h(r) {
|
|
173
|
+
if (!r) return null;
|
|
174
|
+
const t = String(r).toLowerCase();
|
|
175
|
+
return t.includes("max") && t.includes("token") ? "length" : t;
|
|
176
|
+
}
|
|
177
|
+
function p(r) {
|
|
178
|
+
return `gemini_call_${r}`;
|
|
179
|
+
}
|
|
180
|
+
function y(r) {
|
|
181
|
+
if (!r) return null;
|
|
182
|
+
const t = r.promptTokenCount ?? 0, e = r.candidatesTokenCount ?? 0, s = r.totalTokenCount ?? t + e, n = { inputTokens: t, outputTokens: e, totalTokens: s, raw: r };
|
|
183
|
+
return r.cachedContentTokenCount != null && (n.cachedInputTokens = r.cachedContentTokenCount), r.thoughtsTokenCount != null && (n.reasoningTokens = r.thoughtsTokenCount), n;
|
|
184
|
+
}
|
|
185
|
+
function T(r) {
|
|
186
|
+
try {
|
|
187
|
+
return JSON.parse(r);
|
|
188
|
+
} catch {
|
|
189
|
+
return {};
|
|
190
|
+
}
|
|
160
191
|
}
|
|
161
192
|
export {
|
|
162
|
-
|
|
193
|
+
A as GeminiProvider,
|
|
194
|
+
y as normalizeGeminiUsage
|
|
163
195
|
};
|
|
@@ -1,50 +1,79 @@
|
|
|
1
|
-
import { BaseProvider as
|
|
2
|
-
|
|
1
|
+
import { BaseProvider as g } from "./BaseProvider.js";
|
|
2
|
+
import { convertMessagesToOpenAI as m, normalizeOpenAIUsage as u } from "./OpenAIProvider.js";
|
|
3
|
+
class y extends g {
|
|
3
4
|
async detectCapabilities() {
|
|
4
5
|
if (!this.config.model) return;
|
|
5
|
-
const
|
|
6
|
-
(
|
|
6
|
+
const t = this.config.model.toLowerCase();
|
|
7
|
+
(t.includes("grok-2") || t.includes("vision")) && this.capabilities.add("vision"), this.capabilities.add("tools");
|
|
7
8
|
}
|
|
8
|
-
prepareRequest(
|
|
9
|
+
prepareRequest(t, e) {
|
|
9
10
|
const s = {
|
|
10
|
-
model:
|
|
11
|
-
messages: this.processMessages(
|
|
12
|
-
temperature:
|
|
13
|
-
max_tokens:
|
|
14
|
-
stream:
|
|
11
|
+
model: e.model || this.config.model || "grok-beta",
|
|
12
|
+
messages: this.processMessages(t, e),
|
|
13
|
+
temperature: e.temperature ?? 0.7,
|
|
14
|
+
max_tokens: e.maxTokens || 1e3,
|
|
15
|
+
stream: e.stream || !1
|
|
15
16
|
};
|
|
16
|
-
return
|
|
17
|
+
return s.stream && (s.stream_options = { include_usage: !0 }), e.tools && this.capabilities.has("tools") && (s.tools = e.tools, e.tool_choice && (s.tool_choice = e.tool_choice)), s;
|
|
17
18
|
}
|
|
18
|
-
processMessages(
|
|
19
|
-
|
|
19
|
+
processMessages(t, e) {
|
|
20
|
+
const s = m(t);
|
|
21
|
+
return e.images && this.capabilities.has("vision") ? this.addImagesToMessages(s, e.images) : s;
|
|
20
22
|
}
|
|
21
|
-
addImagesToMessages(
|
|
22
|
-
const s =
|
|
23
|
+
addImagesToMessages(t, e) {
|
|
24
|
+
const s = t[t.length - 1];
|
|
23
25
|
if (s && s.role === "user") {
|
|
24
26
|
const n = [{ type: "text", text: s.content }];
|
|
25
|
-
|
|
27
|
+
e.forEach((r) => n.push({ type: "image_url", image_url: { url: typeof r == "string" ? r : r.url } })), s.content = n;
|
|
26
28
|
}
|
|
27
|
-
return
|
|
29
|
+
return t;
|
|
28
30
|
}
|
|
29
|
-
processResponse(
|
|
30
|
-
var
|
|
31
|
-
|
|
31
|
+
processResponse(t) {
|
|
32
|
+
var n, r, i, o;
|
|
33
|
+
const e = (r = (n = t.choices) == null ? void 0 : n[0]) == null ? void 0 : r.message, s = {
|
|
34
|
+
content: (e == null ? void 0 : e.content) || "",
|
|
35
|
+
usage: u(t.usage),
|
|
36
|
+
finishReason: c((o = (i = t.choices) == null ? void 0 : i[0]) == null ? void 0 : o.finish_reason)
|
|
37
|
+
};
|
|
38
|
+
return Array.isArray(e == null ? void 0 : e.tool_calls) && (s.toolCalls = e.tool_calls.map((l) => {
|
|
39
|
+
var d, f;
|
|
40
|
+
return {
|
|
41
|
+
id: l.id,
|
|
42
|
+
name: (d = l.function) == null ? void 0 : d.name,
|
|
43
|
+
args: h((f = l.function) == null ? void 0 : f.arguments)
|
|
44
|
+
};
|
|
45
|
+
})), s;
|
|
32
46
|
}
|
|
33
|
-
parseStreamingLine(
|
|
34
|
-
if (!
|
|
35
|
-
const
|
|
36
|
-
if (
|
|
47
|
+
parseStreamingLine(t) {
|
|
48
|
+
if (!t.startsWith("data: ")) return null;
|
|
49
|
+
const e = t.slice(6).trim();
|
|
50
|
+
if (e === "[DONE]") return { done: !0 };
|
|
37
51
|
try {
|
|
38
|
-
return JSON.parse(
|
|
52
|
+
return JSON.parse(e);
|
|
39
53
|
} catch {
|
|
40
54
|
return null;
|
|
41
55
|
}
|
|
42
56
|
}
|
|
43
|
-
extractStreamingContent(
|
|
44
|
-
var
|
|
45
|
-
if (
|
|
46
|
-
const
|
|
47
|
-
|
|
57
|
+
extractStreamingContent(t) {
|
|
58
|
+
var n, r, i;
|
|
59
|
+
if (t.done) return { done: !0 };
|
|
60
|
+
const e = (n = t.choices) == null ? void 0 : n[0], s = e == null ? void 0 : e.delta;
|
|
61
|
+
if (s && Array.isArray(s.tool_calls) && s.tool_calls.length) {
|
|
62
|
+
const o = s.tool_calls[0];
|
|
63
|
+
return {
|
|
64
|
+
content: s.content || "",
|
|
65
|
+
done: !1,
|
|
66
|
+
usage: u(t.usage),
|
|
67
|
+
finishReason: c(e == null ? void 0 : e.finish_reason),
|
|
68
|
+
toolCallDelta: {
|
|
69
|
+
index: o.index ?? 0,
|
|
70
|
+
id: o.id || void 0,
|
|
71
|
+
name: ((r = o.function) == null ? void 0 : r.name) || void 0,
|
|
72
|
+
argsTextDelta: ((i = o.function) == null ? void 0 : i.arguments) || ""
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return { content: (s == null ? void 0 : s.content) || "", done: !1, usage: u(t.usage), finishReason: c(e == null ? void 0 : e.finish_reason) };
|
|
48
77
|
}
|
|
49
78
|
getApiPath() {
|
|
50
79
|
return "/v1/chat/completions";
|
|
@@ -55,16 +84,24 @@ class u extends c {
|
|
|
55
84
|
getModelsEndpoint() {
|
|
56
85
|
return `${this.config.baseUrl}/v1/models`;
|
|
57
86
|
}
|
|
58
|
-
parseModelsResponse(
|
|
59
|
-
var
|
|
60
|
-
return ((n = (s = (
|
|
87
|
+
parseModelsResponse(t) {
|
|
88
|
+
var e, s, n;
|
|
89
|
+
return ((n = (s = (e = t.data) == null ? void 0 : e.filter((r) => String(r.id).toLowerCase().includes("grok"))) == null ? void 0 : s.map((r) => r.id)) == null ? void 0 : n.sort()) || [];
|
|
61
90
|
}
|
|
62
91
|
}
|
|
63
|
-
function a
|
|
64
|
-
if (!
|
|
65
|
-
const
|
|
66
|
-
return
|
|
92
|
+
function c(a) {
|
|
93
|
+
if (!a) return null;
|
|
94
|
+
const t = String(a).toLowerCase();
|
|
95
|
+
return t === "length" || t === "max_tokens" ? "length" : t;
|
|
96
|
+
}
|
|
97
|
+
function h(a) {
|
|
98
|
+
if (!a) return {};
|
|
99
|
+
try {
|
|
100
|
+
return JSON.parse(a);
|
|
101
|
+
} catch {
|
|
102
|
+
return { __parseError: !0, raw: a };
|
|
103
|
+
}
|
|
67
104
|
}
|
|
68
105
|
export {
|
|
69
|
-
|
|
106
|
+
y as GrokProvider
|
|
70
107
|
};
|
|
@@ -1,33 +1,66 @@
|
|
|
1
|
-
import { BaseProvider as
|
|
2
|
-
|
|
1
|
+
import { BaseProvider as m } from "./BaseProvider.js";
|
|
2
|
+
import { convertMessagesToOpenAI as g, normalizeOpenAIUsage as u } from "./OpenAIProvider.js";
|
|
3
|
+
class A extends m {
|
|
3
4
|
async detectCapabilities() {
|
|
5
|
+
this.capabilities.add("tools");
|
|
4
6
|
}
|
|
5
|
-
prepareRequest(
|
|
6
|
-
|
|
7
|
-
model:
|
|
8
|
-
messages:
|
|
9
|
-
temperature:
|
|
10
|
-
max_tokens:
|
|
11
|
-
stream:
|
|
7
|
+
prepareRequest(n, e) {
|
|
8
|
+
const t = {
|
|
9
|
+
model: e.model || this.config.model || "llama2",
|
|
10
|
+
messages: g(n),
|
|
11
|
+
temperature: e.temperature ?? 0.7,
|
|
12
|
+
max_tokens: e.maxTokens || 1e3,
|
|
13
|
+
stream: e.stream || !1
|
|
12
14
|
};
|
|
15
|
+
return t.stream && (t.stream_options = { include_usage: !0 }), e.tools && this.capabilities.has("tools") && (t.tools = e.tools, e.tool_choice && (t.tool_choice = e.tool_choice)), t;
|
|
13
16
|
}
|
|
14
|
-
processResponse(
|
|
15
|
-
var
|
|
16
|
-
|
|
17
|
+
processResponse(n) {
|
|
18
|
+
var r, o, i, a;
|
|
19
|
+
const e = (o = (r = n.choices) == null ? void 0 : r[0]) == null ? void 0 : o.message, t = {
|
|
20
|
+
content: (e == null ? void 0 : e.content) || "",
|
|
21
|
+
usage: u(n.usage),
|
|
22
|
+
finishReason: c((a = (i = n.choices) == null ? void 0 : i[0]) == null ? void 0 : a.finish_reason)
|
|
23
|
+
};
|
|
24
|
+
return Array.isArray(e == null ? void 0 : e.tool_calls) && (t.toolCalls = e.tool_calls.map((l) => {
|
|
25
|
+
var d, f;
|
|
26
|
+
return {
|
|
27
|
+
id: l.id,
|
|
28
|
+
name: (d = l.function) == null ? void 0 : d.name,
|
|
29
|
+
args: h((f = l.function) == null ? void 0 : f.arguments)
|
|
30
|
+
};
|
|
31
|
+
})), t;
|
|
17
32
|
}
|
|
18
|
-
parseStreamingLine(
|
|
19
|
-
if (!
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
33
|
+
parseStreamingLine(n) {
|
|
34
|
+
if (!n.startsWith("data: ")) return null;
|
|
35
|
+
const e = n.slice(6).trim();
|
|
36
|
+
if (e === "[DONE]") return { done: !0 };
|
|
22
37
|
try {
|
|
23
|
-
return JSON.parse(
|
|
38
|
+
return JSON.parse(e);
|
|
24
39
|
} catch {
|
|
25
40
|
return null;
|
|
26
41
|
}
|
|
27
42
|
}
|
|
28
|
-
extractStreamingContent(
|
|
29
|
-
var
|
|
30
|
-
|
|
43
|
+
extractStreamingContent(n) {
|
|
44
|
+
var r, o, i;
|
|
45
|
+
if (n.done) return { done: !0 };
|
|
46
|
+
const e = (r = n.choices) == null ? void 0 : r[0], t = e == null ? void 0 : e.delta;
|
|
47
|
+
if (t && Array.isArray(t.tool_calls) && t.tool_calls.length) {
|
|
48
|
+
const a = t.tool_calls[0];
|
|
49
|
+
return {
|
|
50
|
+
content: t.content || "",
|
|
51
|
+
thinking: "",
|
|
52
|
+
done: !1,
|
|
53
|
+
usage: u(n.usage),
|
|
54
|
+
finishReason: c(e == null ? void 0 : e.finish_reason),
|
|
55
|
+
toolCallDelta: {
|
|
56
|
+
index: a.index ?? 0,
|
|
57
|
+
id: a.id || void 0,
|
|
58
|
+
name: ((o = a.function) == null ? void 0 : o.name) || void 0,
|
|
59
|
+
argsTextDelta: ((i = a.function) == null ? void 0 : i.arguments) || ""
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return { content: (t == null ? void 0 : t.content) || "", thinking: "", done: !1, usage: u(n.usage), finishReason: c(e == null ? void 0 : e.finish_reason) };
|
|
31
64
|
}
|
|
32
65
|
getApiPath() {
|
|
33
66
|
return "/v1/chat/completions";
|
|
@@ -38,19 +71,27 @@ class c extends l {
|
|
|
38
71
|
getModelsEndpoint() {
|
|
39
72
|
return `${this.config.baseUrl}/v1/models`;
|
|
40
73
|
}
|
|
41
|
-
parseModelsResponse(
|
|
42
|
-
var
|
|
43
|
-
return ((
|
|
44
|
-
const
|
|
45
|
-
return
|
|
46
|
-
}).map((
|
|
74
|
+
parseModelsResponse(n) {
|
|
75
|
+
var e;
|
|
76
|
+
return ((e = n.data) == null ? void 0 : e.filter((t) => {
|
|
77
|
+
const r = t.id.toLowerCase();
|
|
78
|
+
return r.includes("mistral") || r.includes("llama") || r.includes("codellama") || r.includes(".gguf") || r.includes(".bin");
|
|
79
|
+
}).map((t) => t.id).sort()) || [];
|
|
47
80
|
}
|
|
48
81
|
}
|
|
49
|
-
function
|
|
50
|
-
if (!
|
|
51
|
-
const
|
|
52
|
-
return
|
|
82
|
+
function c(s) {
|
|
83
|
+
if (!s) return null;
|
|
84
|
+
const n = String(s).toLowerCase();
|
|
85
|
+
return n === "max_tokens" ? "length" : n;
|
|
86
|
+
}
|
|
87
|
+
function h(s) {
|
|
88
|
+
if (!s) return {};
|
|
89
|
+
try {
|
|
90
|
+
return JSON.parse(s);
|
|
91
|
+
} catch {
|
|
92
|
+
return { __parseError: !0, raw: s };
|
|
93
|
+
}
|
|
53
94
|
}
|
|
54
95
|
export {
|
|
55
|
-
|
|
96
|
+
A as LlamaServerProvider
|
|
56
97
|
};
|