@anvaka/vue-llm 0.1.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 +166 -0
- package/dist/_virtual/_plugin-vue_export-helper.js +9 -0
- package/dist/core/LLMClient.js +248 -0
- package/dist/core/configStore.js +52 -0
- package/dist/core/keyStore.js +58 -0
- package/dist/core/storageAdapter.js +67 -0
- package/dist/index.js +38 -0
- package/dist/providers/AnthropicProvider.js +88 -0
- package/dist/providers/BaseProvider.js +155 -0
- package/dist/providers/CustomProvider.js +53 -0
- package/dist/providers/GeminiProvider.js +163 -0
- package/dist/providers/GrokProvider.js +70 -0
- package/dist/providers/LlamaServerProvider.js +56 -0
- package/dist/providers/OllamaProvider.js +77 -0
- package/dist/providers/OpenAIProvider.js +98 -0
- package/dist/providers/OpenRouterProvider.js +81 -0
- package/dist/providers/factory.js +69 -0
- package/dist/providers/index.js +12 -0
- package/dist/vue/components/LLMConfigModal.vue.js +498 -0
- package/dist/vue/components/ProviderSelector.vue.js +53 -0
- package/dist/vue/components/StoredKeysManager.vue.js +223 -0
- package/dist/vue/index.js +17 -0
- package/dist/vue/plugin.js +26 -0
- package/dist/vue/useLLM.js +137 -0
- package/dist/vue-llm.css +1 -0
- package/package.json +41 -0
- package/src/styles/components.css +15 -0
- package/src/styles/variables.css +70 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
var u = (n) => {
|
|
2
|
+
throw TypeError(n);
|
|
3
|
+
};
|
|
4
|
+
var f = (n, r, t) => r.has(n) || u("Cannot " + t);
|
|
5
|
+
var h = (n, r, t) => r.has(n) ? u("Cannot add the same private member more than once") : r instanceof WeakSet ? r.add(n) : r.set(n, t);
|
|
6
|
+
var g = (n, r, t) => (f(n, r, "access private method"), t);
|
|
7
|
+
import { BaseProvider as m } from "./BaseProvider.js";
|
|
8
|
+
var c, d;
|
|
9
|
+
class k extends m {
|
|
10
|
+
constructor() {
|
|
11
|
+
super(...arguments);
|
|
12
|
+
h(this, c);
|
|
13
|
+
}
|
|
14
|
+
async detectCapabilities() {
|
|
15
|
+
if (!this.config.model) return;
|
|
16
|
+
const t = this.config.model.toLowerCase();
|
|
17
|
+
(t.startsWith("o1") || t.startsWith("o2") || t.startsWith("o3") || t.startsWith("o-") || t.includes("gpt-5") || t === "gpt5") && this.capabilities.add("thinking"), t.includes("gpt-4") && t.includes("vision") && this.capabilities.add("vision"), (t.includes("gpt-4") || t.includes("gpt-3.5") || t.includes("gpt-5")) && this.capabilities.add("tools");
|
|
18
|
+
}
|
|
19
|
+
prepareRequest(t, e) {
|
|
20
|
+
const i = e.model || this.config.model || "gpt-3.5-turbo", s = {
|
|
21
|
+
model: i,
|
|
22
|
+
messages: this.processMessages(t, e),
|
|
23
|
+
temperature: e.temperature || 0.7,
|
|
24
|
+
stream: e.stream || !1
|
|
25
|
+
};
|
|
26
|
+
return g(this, c, d).call(this, i) ? (s.max_completion_tokens = e.maxTokens || 1e3, s.temperature = 1) : s.max_tokens = e.maxTokens || 1e3, e.enableThinking && this.capabilities.has("thinking") && (s.reasoning_effort = e.reasoningEffort || "medium"), e.tools && this.capabilities.has("tools") && (s.tools = e.tools), s;
|
|
27
|
+
}
|
|
28
|
+
processMessages(t, e) {
|
|
29
|
+
return e.images && this.capabilities.has("vision") ? this.addImagesToMessages(t, e.images) : t;
|
|
30
|
+
}
|
|
31
|
+
addImagesToMessages(t, e) {
|
|
32
|
+
const i = t[t.length - 1];
|
|
33
|
+
if (i && i.role === "user") {
|
|
34
|
+
const s = [{ type: "text", text: i.content }];
|
|
35
|
+
e.forEach((a) => {
|
|
36
|
+
s.push({
|
|
37
|
+
type: "image_url",
|
|
38
|
+
image_url: { url: typeof a == "string" ? a : a.url }
|
|
39
|
+
});
|
|
40
|
+
}), i.content = s;
|
|
41
|
+
}
|
|
42
|
+
return t;
|
|
43
|
+
}
|
|
44
|
+
processResponse(t) {
|
|
45
|
+
var i, s, a, o, l;
|
|
46
|
+
const e = {
|
|
47
|
+
content: ((a = (s = (i = t.choices) == null ? void 0 : i[0]) == null ? void 0 : s.message) == null ? void 0 : a.content) || "",
|
|
48
|
+
usage: t.usage || null,
|
|
49
|
+
finishReason: ((l = (o = t.choices) == null ? void 0 : o[0]) == null ? void 0 : l.finish_reason) || null
|
|
50
|
+
};
|
|
51
|
+
return t.reasoning && (e.thinking = t.reasoning), e;
|
|
52
|
+
}
|
|
53
|
+
parseStreamingLine(t) {
|
|
54
|
+
if (!t.startsWith("data: ")) return null;
|
|
55
|
+
const e = t.slice(6).trim();
|
|
56
|
+
if (e === "[DONE]") return { done: !0 };
|
|
57
|
+
try {
|
|
58
|
+
return JSON.parse(e);
|
|
59
|
+
} catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
extractStreamingContent(t) {
|
|
64
|
+
var i, s, a, o;
|
|
65
|
+
if (t.done) return { done: !0 };
|
|
66
|
+
const e = (s = (i = t.choices) == null ? void 0 : i[0]) == null ? void 0 : s.delta;
|
|
67
|
+
return {
|
|
68
|
+
content: (e == null ? void 0 : e.content) || "",
|
|
69
|
+
thinking: (e == null ? void 0 : e.reasoning) || "",
|
|
70
|
+
done: !1,
|
|
71
|
+
usage: t.usage || null,
|
|
72
|
+
finishReason: ((o = (a = t.choices) == null ? void 0 : a[0]) == null ? void 0 : o.finish_reason) || null
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
getApiPath() {
|
|
76
|
+
return "/v1/chat/completions";
|
|
77
|
+
}
|
|
78
|
+
requiresAuth() {
|
|
79
|
+
return !!this.config.apiKey;
|
|
80
|
+
}
|
|
81
|
+
getModelsEndpoint() {
|
|
82
|
+
return `${this.config.baseUrl}/v1/models`;
|
|
83
|
+
}
|
|
84
|
+
parseModelsResponse(t) {
|
|
85
|
+
var e;
|
|
86
|
+
return ((e = t.data) == null ? void 0 : e.filter((i) => {
|
|
87
|
+
const s = i.id.toLowerCase();
|
|
88
|
+
return s.includes("gpt") || s.includes("chat");
|
|
89
|
+
}).map((i) => i.id).sort()) || [];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
c = new WeakSet(), d = function(t) {
|
|
93
|
+
const e = (t || "").toLowerCase();
|
|
94
|
+
return e.startsWith("o1") || e.startsWith("o2") || e.startsWith("o3") || e.startsWith("o-") || e.includes("gpt-5") || e === "gpt5" || e.includes("reasoning") || this.capabilities.has("thinking");
|
|
95
|
+
};
|
|
96
|
+
export {
|
|
97
|
+
k as OpenAIProvider
|
|
98
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { BaseProvider as d } from "./BaseProvider.js";
|
|
2
|
+
class f extends d {
|
|
3
|
+
async detectCapabilities() {
|
|
4
|
+
this.config.model && (this.capabilities.add("tools"), (this.config.model.includes("o1") || this.config.model.includes("thinking") || this.config.model.includes("reasoning")) && this.capabilities.add("thinking"), (this.config.model.includes("vision") || this.config.model.includes("gpt-4") || this.config.model.includes("claude") || this.config.model.includes("gemini")) && this.capabilities.add("vision"));
|
|
5
|
+
}
|
|
6
|
+
prepareRequest(t, e) {
|
|
7
|
+
const i = {
|
|
8
|
+
model: e.model || this.config.model,
|
|
9
|
+
messages: this.processMessages(t, e),
|
|
10
|
+
temperature: e.temperature || 0.7,
|
|
11
|
+
max_tokens: e.maxTokens || 1e3,
|
|
12
|
+
stream: e.stream || !1
|
|
13
|
+
};
|
|
14
|
+
return e.enableThinking && this.capabilities.has("thinking") && (i.reasoning = e.reasoning !== !1, e.reasoningEffort && (i.reasoning_effort = e.reasoningEffort)), e.tools && this.capabilities.has("tools") && (i.tools = e.tools, e.tool_choice && (i.tool_choice = e.tool_choice)), i;
|
|
15
|
+
}
|
|
16
|
+
processMessages(t, e) {
|
|
17
|
+
return e.images && this.capabilities.has("vision") ? this.addImagesToMessages(t, e.images) : t;
|
|
18
|
+
}
|
|
19
|
+
addImagesToMessages(t, e) {
|
|
20
|
+
const i = t[t.length - 1];
|
|
21
|
+
return i && i.role === "user" && (i.content = [{ type: "text", text: i.content }, ...e.map((s) => ({ type: "image_url", image_url: { url: s } }))]), t;
|
|
22
|
+
}
|
|
23
|
+
buildHeaders() {
|
|
24
|
+
const t = { "Content-Type": "application/json" };
|
|
25
|
+
return this.requiresAuth() && (t[this.getAuthHeaderName()] = this.getAuthHeaderValue()), this.config.siteUrl && (t["HTTP-Referer"] = this.config.siteUrl), this.config.siteName && (t["X-Title"] = this.config.siteName), t;
|
|
26
|
+
}
|
|
27
|
+
processResponse(t) {
|
|
28
|
+
var i, s, n, r, a, c, l, h;
|
|
29
|
+
const e = { content: ((n = (s = (i = t.choices) == null ? void 0 : i[0]) == null ? void 0 : s.message) == null ? void 0 : n.content) || "", usage: t.usage || null, finishReason: u((a = (r = t.choices) == null ? void 0 : r[0]) == null ? void 0 : a.finish_reason) };
|
|
30
|
+
return (h = (l = (c = t.choices) == null ? void 0 : c[0]) == null ? void 0 : l.message) != null && h.reasoning && (e.thinking = t.choices[0].message.reasoning), e;
|
|
31
|
+
}
|
|
32
|
+
parseStreamingLine(t) {
|
|
33
|
+
if (!t.startsWith("data: ")) return null;
|
|
34
|
+
const e = t.slice(6).trim();
|
|
35
|
+
if (e === "[DONE]") return { done: !0 };
|
|
36
|
+
try {
|
|
37
|
+
return JSON.parse(e);
|
|
38
|
+
} catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
extractStreamingContent(t) {
|
|
43
|
+
var i, s, n, r;
|
|
44
|
+
if (t.done) return { done: !0 };
|
|
45
|
+
const e = (s = (i = t.choices) == null ? void 0 : i[0]) == null ? void 0 : s.delta;
|
|
46
|
+
return { content: (e == null ? void 0 : e.content) || "", thinking: (e == null ? void 0 : e.reasoning) || "", done: !1, usage: t.usage || null, finishReason: u((r = (n = t.choices) == null ? void 0 : n[0]) == null ? void 0 : r.finish_reason) };
|
|
47
|
+
}
|
|
48
|
+
getApiPath() {
|
|
49
|
+
return "/v1/chat/completions";
|
|
50
|
+
}
|
|
51
|
+
requiresAuth() {
|
|
52
|
+
return !!this.config.apiKey;
|
|
53
|
+
}
|
|
54
|
+
getModelsEndpoint() {
|
|
55
|
+
return `${this.config.baseUrl}/v1/models`;
|
|
56
|
+
}
|
|
57
|
+
parseModelsResponse(t) {
|
|
58
|
+
return Array.isArray(t.data) ? t.data.filter((e) => {
|
|
59
|
+
var s;
|
|
60
|
+
const i = (s = e.architecture) == null ? void 0 : s.modality;
|
|
61
|
+
return i && (i.includes("text->text") || i.includes("text+image->text"));
|
|
62
|
+
}).map((e) => e.id).sort() : [];
|
|
63
|
+
}
|
|
64
|
+
async discoverModelsWithMetadata(t = 15e3) {
|
|
65
|
+
try {
|
|
66
|
+
const e = this.buildHeaders(), i = new AbortController(), s = setTimeout(() => i.abort(), t), n = await fetch(this.getModelsEndpoint(), { method: "GET", headers: e, signal: i.signal });
|
|
67
|
+
if (clearTimeout(s), !n.ok) throw new Error(`Failed to fetch models: ${n.status} ${n.statusText}`);
|
|
68
|
+
return (await n.json()).data || [];
|
|
69
|
+
} catch (e) {
|
|
70
|
+
throw e.name === "AbortError" ? new Error("Model discovery timeout - please check your connection") : e;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function u(o) {
|
|
75
|
+
if (!o) return null;
|
|
76
|
+
const t = String(o).toLowerCase();
|
|
77
|
+
return t === "length" || t === "max_tokens" ? "length" : t;
|
|
78
|
+
}
|
|
79
|
+
export {
|
|
80
|
+
f as OpenRouterProvider
|
|
81
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { OpenAIProvider as i } from "./OpenAIProvider.js";
|
|
2
|
+
import { AnthropicProvider as n } from "./AnthropicProvider.js";
|
|
3
|
+
import { GrokProvider as s } from "./GrokProvider.js";
|
|
4
|
+
import { GeminiProvider as m } from "./GeminiProvider.js";
|
|
5
|
+
import { OllamaProvider as p } from "./OllamaProvider.js";
|
|
6
|
+
import { LlamaServerProvider as u } from "./LlamaServerProvider.js";
|
|
7
|
+
import { OpenRouterProvider as l } from "./OpenRouterProvider.js";
|
|
8
|
+
import { CustomProvider as A } from "./CustomProvider.js";
|
|
9
|
+
const e = {
|
|
10
|
+
OPENAI: "openai",
|
|
11
|
+
ANTHROPIC: "anthropic",
|
|
12
|
+
GROK: "grok",
|
|
13
|
+
GEMINI: "gemini",
|
|
14
|
+
OLLAMA: "ollama",
|
|
15
|
+
LLAMA_SERVER: "llama-server",
|
|
16
|
+
OPENROUTER: "openrouter",
|
|
17
|
+
CUSTOM: "custom"
|
|
18
|
+
}, L = {
|
|
19
|
+
[e.OPENAI]: { name: "OpenAI", baseUrl: "https://api.openai.com", requiresApiKey: !0 },
|
|
20
|
+
[e.ANTHROPIC]: { name: "Anthropic", baseUrl: "https://api.anthropic.com", requiresApiKey: !0 },
|
|
21
|
+
[e.GROK]: { name: "Grok", baseUrl: "https://api.x.ai", requiresApiKey: !0 },
|
|
22
|
+
[e.GEMINI]: { name: "Google Gemini", baseUrl: "https://generativelanguage.googleapis.com", requiresApiKey: !0 },
|
|
23
|
+
[e.OLLAMA]: { name: "Ollama (Native)", baseUrl: "http://localhost:11434", requiresApiKey: !1 },
|
|
24
|
+
[e.LLAMA_SERVER]: { name: "Local Llama Server", baseUrl: "http://localhost:8080", requiresApiKey: !1 },
|
|
25
|
+
[e.OPENROUTER]: { name: "OpenRouter", baseUrl: "https://openrouter.ai/api", requiresApiKey: !0 },
|
|
26
|
+
[e.CUSTOM]: { name: "Custom OpenAI Compatible", baseUrl: "", requiresApiKey: !1 }
|
|
27
|
+
};
|
|
28
|
+
function O(t, r) {
|
|
29
|
+
switch (t) {
|
|
30
|
+
case e.OPENAI:
|
|
31
|
+
return new i(r);
|
|
32
|
+
case e.ANTHROPIC:
|
|
33
|
+
return new n(r);
|
|
34
|
+
case e.GROK:
|
|
35
|
+
return new s(r);
|
|
36
|
+
case e.GEMINI:
|
|
37
|
+
return new m(r);
|
|
38
|
+
case e.OLLAMA:
|
|
39
|
+
return new p(r);
|
|
40
|
+
case e.LLAMA_SERVER:
|
|
41
|
+
return new u(r);
|
|
42
|
+
case e.OPENROUTER:
|
|
43
|
+
return new l(r);
|
|
44
|
+
case e.CUSTOM:
|
|
45
|
+
return new A(r);
|
|
46
|
+
default:
|
|
47
|
+
throw new Error(`Unknown provider type: ${t}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const a = /* @__PURE__ */ new Map();
|
|
51
|
+
function U(t, r) {
|
|
52
|
+
if (typeof t != "string" || !r)
|
|
53
|
+
throw new Error("registerProvider requires a type string and a class reference");
|
|
54
|
+
a.set(t, r);
|
|
55
|
+
}
|
|
56
|
+
function N(t, r) {
|
|
57
|
+
if (a.has(t)) {
|
|
58
|
+
const o = a.get(t);
|
|
59
|
+
return new o(r);
|
|
60
|
+
}
|
|
61
|
+
return O(t, r);
|
|
62
|
+
}
|
|
63
|
+
export {
|
|
64
|
+
L as DEFAULT_CONFIGS,
|
|
65
|
+
e as PROVIDERS,
|
|
66
|
+
O as createProvider,
|
|
67
|
+
N as createProviderFlexible,
|
|
68
|
+
U as registerProvider
|
|
69
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseProvider as o } from "./BaseProvider.js";
|
|
2
|
+
import { OpenAIProvider as t } from "./OpenAIProvider.js";
|
|
3
|
+
import { DEFAULT_CONFIGS as d, PROVIDERS as v, createProvider as p, createProviderFlexible as x, registerProvider as a } from "./factory.js";
|
|
4
|
+
export {
|
|
5
|
+
o as BaseProvider,
|
|
6
|
+
d as DEFAULT_CONFIGS,
|
|
7
|
+
t as OpenAIProvider,
|
|
8
|
+
v as PROVIDERS,
|
|
9
|
+
p as createProvider,
|
|
10
|
+
x as createProviderFlexible,
|
|
11
|
+
a as registerProvider
|
|
12
|
+
};
|