@7n/tauri-components 0.10.1 → 0.11.1
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/CHANGELOG.md +12 -0
- package/package.json +1 -4
- package/src/components/AgentDialog.vue +21 -46
- package/src/components/AuditDialog.vue +9 -17
- package/src/components/BaseDialog.vue +2 -6
- package/src/components/DialogActions.vue +2 -3
- package/src/components/RequestView.vue +2 -3
- package/src/components/StatePill.vue +1 -1
- package/src/components/docs/AgentDialog.md +4 -4
- package/src/components/docs/AuditDialog.md +4 -4
- package/src/components/docs/BaseDialog.md +4 -4
- package/src/components/docs/DialogActions.md +4 -4
- package/src/components/docs/RequestView.md +4 -4
- package/src/components/docs/StatePill.md +4 -4
- package/src/components/docs/index.md +4 -4
- package/src/components/docs/status.md +4 -4
- package/src/components/index.js +2 -2
- package/src/components/status.js +1 -1
- package/src/core/acp-agent-presets.js +2 -2
- package/src/core/acp-agent.js +21 -15
- package/src/core/acp-kit.js +79 -30
- package/src/core/dispatch.js +3 -3
- package/src/core/docs/acp-agent-presets.md +4 -4
- package/src/core/docs/acp-agent.md +4 -4
- package/src/core/docs/acp-kit.md +4 -4
- package/src/core/docs/dispatch.md +4 -4
- package/src/core/docs/manifest.md +4 -4
- package/src/core/manifest.js +10 -8
- package/src/docs/index.md +4 -4
- package/src/index.js +3 -8
- package/src/testing/docs/quasar.md +4 -4
- package/src/testing/quasar.js +2 -2
- package/src/vue/docs/index.md +4 -4
- package/src/vue/docs/journal-store-tauri.md +4 -4
- package/src/vue/docs/use-acp-agent.md +4 -4
- package/src/vue/docs/use-updater.md +4 -4
- package/src/vue/index.js +4 -6
- package/src/vue/journal-store-tauri.js +2 -2
- package/src/vue/use-acp-agent.js +22 -14
- package/src/vue/use-updater.js +4 -6
- package/types/core/dispatch.d.ts +5 -2
- package/types/core/manifest.d.ts +14 -9
- package/types/core/scope.d.ts +24 -11
- package/types/core/tools.d.ts +1 -1
- package/types/index.d.ts +4 -9
- package/src/core/agent-handler.js +0 -171
- package/src/core/agent-kit.js +0 -43
- package/src/core/docs/agent-handler.md +0 -31
- package/src/core/docs/agent-kit.md +0 -25
- package/src/core/docs/llm.md +0 -29
- package/src/core/docs/omlx-models.md +0 -30
- package/src/core/docs/resolve-omlx-base-url.md +0 -40
- package/src/core/llm.js +0 -90
- package/src/core/omlx-models.js +0 -34
- package/src/core/resolve-omlx-base-url.js +0 -84
- package/src/vue/docs/use-agent.md +0 -29
- package/src/vue/docs/use-omlx.md +0 -30
- package/src/vue/use-agent.js +0 -60
- package/src/vue/use-omlx.js +0 -102
- package/types/core/agent-handler.d.ts +0 -43
- package/types/core/agent-kit.d.ts +0 -30
- package/types/core/llm.d.ts +0 -52
- package/types/core/omlx-models.d.ts +0 -17
- package/types/core/resolve-omlx-base-url.d.ts +0 -42
package/src/core/omlx-models.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// List the models a local omlx (OpenAI-compatible) server has loaded, via
|
|
2
|
-
// GET {baseUrl}/models. Generic OpenAI shape: { data: [{ id }] }. Returns [] on
|
|
3
|
-
// any failure so a model picker degrades gracefully to manual entry.
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @param {{ baseUrl?: string, apiKey?: string, fetchFn?: typeof fetch, signal?: AbortSignal }} [params] config
|
|
7
|
-
* @returns {Promise<string[]>} loaded model ids (empty on error)
|
|
8
|
-
*/
|
|
9
|
-
export async function listOmlxModels({ baseUrl, apiKey, fetchFn = fetch, signal } = {}) {
|
|
10
|
-
if (!baseUrl) return []
|
|
11
|
-
try {
|
|
12
|
-
const response = await fetchFn(`${baseUrl}/models`, {
|
|
13
|
-
headers: apiKey ? { authorization: `Bearer ${apiKey}` } : {},
|
|
14
|
-
signal,
|
|
15
|
-
})
|
|
16
|
-
if (!response.ok) return []
|
|
17
|
-
const data = await response.json()
|
|
18
|
-
return Array.isArray(data?.data) ? data.data.map(m => m?.id).filter(Boolean) : []
|
|
19
|
-
}
|
|
20
|
-
catch {
|
|
21
|
-
return []
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Pick a model: the preferred one if loaded, else the first available, else ''.
|
|
27
|
-
* @param {string[]} models loaded model ids
|
|
28
|
-
* @param {string} [preferred] preferred id
|
|
29
|
-
* @returns {string} chosen model id
|
|
30
|
-
*/
|
|
31
|
-
export function resolveModel(models, preferred) {
|
|
32
|
-
if (preferred && models.includes(preferred)) return preferred
|
|
33
|
-
return models[0] ?? ''
|
|
34
|
-
}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
// Resolve the effective omlx base URL: when the myllm reverse proxy
|
|
2
|
-
// (a Tauri app that forwards /v1/* to the real omlx server and logs every
|
|
3
|
-
// request/response for its history view) is alive on its well-known local
|
|
4
|
-
// port, route traffic through it; otherwise talk to omlx directly. The probe
|
|
5
|
-
// hits {proxy origin}/health — the proxy forwards it to omlx itself, so a
|
|
6
|
-
// 2xx proves BOTH the proxy and the upstream are up (omlx down behind a live
|
|
7
|
-
// proxy yields 502 → direct). Framework-free so headless consumers (MCP
|
|
8
|
-
// wrappers, node scripts) can reuse it; pass a Tauri fetch as fetchFn from
|
|
9
|
-
// webview contexts to avoid CORS on localhost.
|
|
10
|
-
|
|
11
|
-
export const DIRECT_OMLX_BASE_URL = 'http://127.0.0.1:8000/v1'
|
|
12
|
-
export const PROXY_OMLX_BASE_URL = 'http://127.0.0.1:8088/v1'
|
|
13
|
-
|
|
14
|
-
const DEFAULT_TIMEOUT_MS = 400
|
|
15
|
-
const DEFAULT_TTL_MS = 12_000
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Is this URL the default local omlx server — the only target eligible for
|
|
19
|
-
* the proxy override? A user who deliberately pointed an app at another
|
|
20
|
-
* host/port must never be silently rerouted (the proxy's upstream is
|
|
21
|
-
* hardwired to the local :8000).
|
|
22
|
-
* @param {string} url candidate base URL
|
|
23
|
-
* @returns {boolean} true for 127.0.0.1:8000 / localhost:8000, false otherwise (incl. parse errors)
|
|
24
|
-
*/
|
|
25
|
-
export function isDirectOmlxUrl(url) {
|
|
26
|
-
try {
|
|
27
|
-
const { host } = new URL(url)
|
|
28
|
-
return host === '127.0.0.1:8000' || host === 'localhost:8000'
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
return false
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* One-shot probe: GET {proxy origin}/health with a short timeout. 2xx means
|
|
37
|
-
* the proxy (and omlx behind it) is alive → use the proxy; anything else
|
|
38
|
-
* (timeout, refused, 502) → use the direct URL.
|
|
39
|
-
* @param {{ directUrl?: string, proxyUrl?: string, fetchFn?: typeof fetch, timeoutMs?: number }} [params] config
|
|
40
|
-
* @returns {Promise<string>} the base URL to use
|
|
41
|
-
*/
|
|
42
|
-
export async function resolveOmlxBaseUrl({
|
|
43
|
-
directUrl = DIRECT_OMLX_BASE_URL,
|
|
44
|
-
proxyUrl = PROXY_OMLX_BASE_URL,
|
|
45
|
-
fetchFn = fetch,
|
|
46
|
-
timeoutMs = DEFAULT_TIMEOUT_MS,
|
|
47
|
-
} = {}) {
|
|
48
|
-
try {
|
|
49
|
-
const healthUrl = new URL('/health', proxyUrl).toString()
|
|
50
|
-
const signal = typeof AbortSignal?.timeout === 'function' ? AbortSignal.timeout(timeoutMs) : undefined
|
|
51
|
-
const response = await fetchFn(healthUrl, { signal })
|
|
52
|
-
return response.ok ? proxyUrl : directUrl
|
|
53
|
-
}
|
|
54
|
-
catch {
|
|
55
|
-
return directUrl
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// proxyUrl → { promise, expiresAt }. Caching the promise (not the value)
|
|
60
|
-
// dedupes concurrent probes: several composables firing loadEnv() at once
|
|
61
|
-
// trigger a single /health request.
|
|
62
|
-
const cache = new Map()
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Cached {@link resolveOmlxBaseUrl}: at most one probe per proxyUrl per TTL
|
|
66
|
-
* window, so callers may resolve before every LLM call without paying the
|
|
67
|
-
* probe latency each time, while still noticing the proxy starting/stopping
|
|
68
|
-
* within one TTL.
|
|
69
|
-
* @param {{ directUrl?: string, proxyUrl?: string, fetchFn?: typeof fetch, timeoutMs?: number, ttlMs?: number, now?: () => number }} [params] config
|
|
70
|
-
* @returns {Promise<string>} the base URL to use
|
|
71
|
-
*/
|
|
72
|
-
export function resolveOmlxBaseUrlCached({ ttlMs = DEFAULT_TTL_MS, now = Date.now, ...probeOptions } = {}) {
|
|
73
|
-
const proxyUrl = probeOptions.proxyUrl ?? PROXY_OMLX_BASE_URL
|
|
74
|
-
const cached = cache.get(proxyUrl)
|
|
75
|
-
if (cached && now() < cached.expiresAt) return cached.promise
|
|
76
|
-
const promise = resolveOmlxBaseUrl(probeOptions)
|
|
77
|
-
cache.set(proxyUrl, { promise, expiresAt: now() + ttlMs })
|
|
78
|
-
return promise
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** Test hook: drop all cached probe results. */
|
|
82
|
-
export function __resetOmlxBaseUrlCache() {
|
|
83
|
-
cache.clear()
|
|
84
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
docgen:
|
|
3
|
-
source: npm/src/vue/use-agent.js
|
|
4
|
-
crc: 84427f61
|
|
5
|
-
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
6
|
-
score: 100
|
|
7
|
-
judgeModel: openai-codex/gpt-5.4-mini
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# use-agent.js
|
|
11
|
-
|
|
12
|
-
## Огляд
|
|
13
|
-
|
|
14
|
-
Модуль ініціалізує шлюз агента, надаючи йому інструменти, системний промпт та конфігурацію. Він дозволяє ініціювати запити до агента через `useAgent`, отримувати відповіді, затверджувати дії та переглядати доступні моделі. Звернення до мережі здійснюється через цей модуль.
|
|
15
|
-
|
|
16
|
-
## Поведінка
|
|
17
|
-
|
|
18
|
-
1. Викликати `useAgent` для ініціалізації шлюзу агента.
|
|
19
|
-
2. Надати `useAgent` каталог інструментів, системний промпт, опціональне заземлення, рівні акторів, ідентичність актора, конфігурацію omlx та транспорт для інструментів.
|
|
20
|
-
3. Отримати з `useAgent` посилання на базовий URL, модель, ключ API та функції для роботи з omlx.
|
|
21
|
-
4. Отримати з `useAgent` посилання на журнал.
|
|
22
|
-
5. Викликати `request` з отриманого шлюзу, передаючи намір та ідентичність актора, щоб ініціювати запит агента.
|
|
23
|
-
6. Викликати `respond` з отриманого шлюзу, передаючи ідентифікатор запиту та повідомлення, щоб надати відповідь агенту.
|
|
24
|
-
7. Викликати `approve` з отриманого шлюзу, передаючи ідентифікатор запиту та результат схвалення, щоб затвердити дію агента.
|
|
25
|
-
8. Викликати `listModels` з отриманого шлюзу, щоб отримати список доступних моделей omlx.
|
|
26
|
-
|
|
27
|
-
## Гарантії поведінки
|
|
28
|
-
|
|
29
|
-
- (специфічних машинно-виведених гарантій немає)
|
package/src/vue/docs/use-omlx.md
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
docgen:
|
|
3
|
-
source: npm/src/vue/use-omlx.js
|
|
4
|
-
crc: d1e34b0a
|
|
5
|
-
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
6
|
-
score: 100
|
|
7
|
-
issues: judge:inaccurate:0.98
|
|
8
|
-
judgeModel: openai-codex/gpt-5.4-mini
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# use-omlx.js
|
|
12
|
-
|
|
13
|
-
## Огляд
|
|
14
|
-
|
|
15
|
-
Модуль відповідає за ініціалізацію та кешування конфігурації для взаємодії з OMLX. Він завантажує налаштування з `settings.json` та середовища виконання, використовуючи <http://127.0.0.1:8000/v1> як резервний URL. Публічна функція useOmlx звертається до мережі, виконує кешування у межах прогону. При виникненні помилок вона перехоплює їх (fail-safe), не кидаючи винятків назовні, а повертаючи порожнє значення замість винятку.
|
|
16
|
-
|
|
17
|
-
## Поведінка
|
|
18
|
-
|
|
19
|
-
1. Ініціалізує конфігурацію OMLX, використовуючи значення з локального сховища. Якщо значення відсутнє, використовує наданий за замовчуванням URL, який може бути `http://127.0.0.1:8000/v1`.
|
|
20
|
-
2. Завантажує глобальні налаштування OMLX з середовища виконання через Rust.
|
|
21
|
-
3. Якщо завантаження успішне, застосовує API ключ до внутрішнього стану.
|
|
22
|
-
4. Якщо локальне сховище відсутнє, застосовує URL та модель з глобальних налаштувань.
|
|
23
|
-
5. Якщо URL відповідає локальному замовленню, виконується перенаправлення через проксі myllm, що є тимчасовим перевизначенням.
|
|
24
|
-
6. Зберігає поточні значення URL та моделі у локальне сховище.
|
|
25
|
-
|
|
26
|
-
## Гарантії поведінки
|
|
27
|
-
|
|
28
|
-
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
29
|
-
- За певних помилок повертає порожнє значення (напр. `null`) замість винятку.
|
|
30
|
-
- Кешує результати в межах одного прогону.
|
package/src/vue/use-agent.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { fetch as tauriFetch } from '@tauri-apps/plugin-http'
|
|
2
|
-
import { createAgentKit } from '../core/agent-kit.js'
|
|
3
|
-
import { createOpenAiChat } from '../core/llm.js'
|
|
4
|
-
import { listOmlxModels } from '../core/omlx-models.js'
|
|
5
|
-
import { createTauriJournalStore } from './journal-store-tauri.js'
|
|
6
|
-
import { tauriTransport } from './transports.js'
|
|
7
|
-
import { useOmlx } from './use-omlx.js'
|
|
8
|
-
|
|
9
|
-
// In-app agent gateway: binds an app's catalog/prompt to the webview transports —
|
|
10
|
-
// omlx via tauri-http, tools via Tauri invoke, journal via the tauri-plugin-agent
|
|
11
|
-
// commands. Returns a flat surface the dialogs consume: request(intent),
|
|
12
|
-
// respond(id, msg), approve(id, ok) plus the omlx config refs and the journal.
|
|
13
|
-
//
|
|
14
|
-
// Apps pass their catalog + systemPrompt (+ optional grounding/omlx defaults);
|
|
15
|
-
// everything Tauri-specific is wired here so feature dialogs stay domain-free.
|
|
16
|
-
|
|
17
|
-
const DEFAULT_ACTOR = { kind: 'human', id: 'local' }
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @param {object} config gateway config
|
|
21
|
-
* @param {object[]} config.catalog app tool catalog (required)
|
|
22
|
-
* @param {string|((ctx: object) => string)} [config.systemPrompt] domain prompt or builder
|
|
23
|
-
* @param {{ tool: string, key?: string, fallback?: unknown }} [config.grounding] optional prompt grounding
|
|
24
|
-
* @param {Record<string, number>} [config.actorTiers] tier overrides
|
|
25
|
-
* @param {{ kind: string, id: string }} [config.actor] caller identity (default human:local)
|
|
26
|
-
* @param {{ storagePrefix?: string, defaultBaseUrl?: string, defaultModel?: string }} [config.omlx] omlx config options
|
|
27
|
-
* @param {(tool: object, input: object) => unknown} [config.transport] tool transport (default Tauri invoke); override to route some tools elsewhere (e.g. JS/OPFS-backed handlers)
|
|
28
|
-
* @returns {object} in-app agent gateway
|
|
29
|
-
*/
|
|
30
|
-
export function useAgent({ catalog, systemPrompt, grounding, actorTiers, actor = DEFAULT_ACTOR, omlx, transport = tauriTransport } = {}) {
|
|
31
|
-
const { baseUrl, model, apiKey, save, loadEnv } = useOmlx(omlx)
|
|
32
|
-
const journal = createTauriJournalStore()
|
|
33
|
-
const kit = createAgentKit({ catalog, systemPrompt, transport, journal, actorTiers, grounding })
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Build an omlx chat fn from the current config (tauri-http transport).
|
|
37
|
-
* @returns {(req: object) => Promise<object>} chat function
|
|
38
|
-
*/
|
|
39
|
-
function chat() {
|
|
40
|
-
return createOpenAiChat({
|
|
41
|
-
baseUrl: baseUrl.value,
|
|
42
|
-
model: model.value,
|
|
43
|
-
apiKey: apiKey.value || undefined,
|
|
44
|
-
fetchFn: tauriFetch,
|
|
45
|
-
})
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return {
|
|
49
|
-
baseUrl,
|
|
50
|
-
model,
|
|
51
|
-
apiKey,
|
|
52
|
-
saveOmlx: save,
|
|
53
|
-
loadOmlxEnv: loadEnv,
|
|
54
|
-
listModels: () => listOmlxModels({ baseUrl: baseUrl.value, apiKey: apiKey.value || undefined, fetchFn: tauriFetch }),
|
|
55
|
-
journal,
|
|
56
|
-
request: intent => kit.request({ intent, actor, chat: chat() }),
|
|
57
|
-
respond: (requestId, message) => kit.respond({ requestId, message, actor, chat: chat() }),
|
|
58
|
-
approve: (requestId, approve) => kit.approve({ requestId, approve }),
|
|
59
|
-
}
|
|
60
|
-
}
|
package/src/vue/use-omlx.js
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import { ref } from 'vue'
|
|
2
|
-
import { invoke } from '@tauri-apps/api/core'
|
|
3
|
-
import { fetch as tauriFetch } from '@tauri-apps/plugin-http'
|
|
4
|
-
import { isDirectOmlxUrl, resolveOmlxBaseUrlCached } from '../core/resolve-omlx-base-url.js'
|
|
5
|
-
|
|
6
|
-
// Persisted config for the local omlx server (OpenAI-compatible MLX) that drives
|
|
7
|
-
// the in-app agent. The API key / base URL come from Rust (omlx_config), which
|
|
8
|
-
// reads them from ~/.omlx/settings.json — the same file the omlx server uses, so
|
|
9
|
-
// the config is portable between machines without env/launchd setup. baseUrl is
|
|
10
|
-
// edited in the dialog and cached in localStorage; omlx_config is the default
|
|
11
|
-
// when localStorage is empty. Priority for base: localStorage > omlx_config >
|
|
12
|
-
// hardcoded default. The key always comes from omlx_config.
|
|
13
|
-
//
|
|
14
|
-
// On top of that, when the resolved base is the default local :8000, loadEnv()
|
|
15
|
-
// probes the myllm reverse proxy (:8088/health, cached with a short TTL) and
|
|
16
|
-
// routes through it while it is alive — a runtime-only override that is never
|
|
17
|
-
// persisted, so the dialog keeps showing/editing the direct URL and a custom
|
|
18
|
-
// (non-:8000) base is never silently rerouted.
|
|
19
|
-
//
|
|
20
|
-
// storagePrefix namespaces the localStorage keys per app (so `task` and `mlmail`
|
|
21
|
-
// keep independent base/model). defaults seed first launch.
|
|
22
|
-
|
|
23
|
-
const DEFAULT_BASE_URL = 'http://127.0.0.1:8000/v1'
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Read a localStorage value, or null when localStorage is unavailable
|
|
27
|
-
* (component tests without a DOM store, SSR).
|
|
28
|
-
* @param {string} key storage key
|
|
29
|
-
* @returns {string|null} stored value, or null
|
|
30
|
-
*/
|
|
31
|
-
function readStored(key) {
|
|
32
|
-
try {
|
|
33
|
-
return globalThis.localStorage?.getItem(key) ?? null
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
return null
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Write a localStorage value; no-op when localStorage is unavailable.
|
|
42
|
-
* @param {string} key storage key
|
|
43
|
-
* @param {string} value value to store
|
|
44
|
-
*/
|
|
45
|
-
function writeStored(key, value) {
|
|
46
|
-
try {
|
|
47
|
-
globalThis.localStorage?.setItem(key, value)
|
|
48
|
-
}
|
|
49
|
-
catch {
|
|
50
|
-
// no localStorage (tests / SSR) — in-memory ref state is still updated
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* @param {{ storagePrefix?: string, defaultBaseUrl?: string, defaultModel?: string }} [options] config
|
|
56
|
-
* @returns {{ baseUrl: import('vue').Ref<string>, model: import('vue').Ref<string>, apiKey: import('vue').Ref<string>, save: () => void, loadEnv: () => Promise<void> }} persisted omlx config, an env loader and a saver
|
|
57
|
-
*/
|
|
58
|
-
export function useOmlx({ storagePrefix = 'agent', defaultBaseUrl = DEFAULT_BASE_URL, defaultModel = '' } = {}) {
|
|
59
|
-
const baseUrlKey = `${storagePrefix}:omlxBaseUrl`
|
|
60
|
-
const modelKey = `${storagePrefix}:omlxModel`
|
|
61
|
-
|
|
62
|
-
const baseUrl = ref(readStored(baseUrlKey) || defaultBaseUrl)
|
|
63
|
-
const model = ref(readStored(modelKey) || defaultModel)
|
|
64
|
-
// Filled from the global env in loadEnv(); never persisted to localStorage.
|
|
65
|
-
const apiKey = ref('')
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Pull OMLX_* from the user's global env (via Rust) and apply them: the API
|
|
69
|
-
* key is taken verbatim; baseUrl/model only fill in when localStorage is empty,
|
|
70
|
-
* so a value set in the dialog still wins. No-op outside Tauri (tests / web).
|
|
71
|
-
* @returns {Promise<void>}
|
|
72
|
-
*/
|
|
73
|
-
async function loadEnv() {
|
|
74
|
-
let env
|
|
75
|
-
try {
|
|
76
|
-
env = await invoke('plugin:agent|omlx_config')
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
return // not running under Tauri — keep localStorage / defaults
|
|
80
|
-
}
|
|
81
|
-
if (env) {
|
|
82
|
-
if (env.apiKey) apiKey.value = env.apiKey
|
|
83
|
-
if (env.baseUrl && !readStored(baseUrlKey)) baseUrl.value = env.baseUrl
|
|
84
|
-
if (env.model && !readStored(modelKey)) model.value = env.model
|
|
85
|
-
}
|
|
86
|
-
// myllm proxy override — only for the default local target, runtime-only.
|
|
87
|
-
if (isDirectOmlxUrl(baseUrl.value)) {
|
|
88
|
-
baseUrl.value = await resolveOmlxBaseUrlCached({ directUrl: baseUrl.value, fetchFn: tauriFetch })
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Persist baseUrl/model to localStorage. The API key is intentionally NOT
|
|
94
|
-
* persisted — it comes from the global OMLX_API_KEY env on each launch.
|
|
95
|
-
*/
|
|
96
|
-
function save() {
|
|
97
|
-
writeStored(baseUrlKey, baseUrl.value)
|
|
98
|
-
writeStored(modelKey, model.value)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return { baseUrl, model, apiKey, save, loadEnv }
|
|
102
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Start a new agent request.
|
|
3
|
-
* @param {{ intent: string, actor: object, chat: Function, dispatch: Function, journal: object, tools: object[], gate: Function, buildSystem?: Function, grounding?: object }} opts request parameters
|
|
4
|
-
* @returns {Promise<object>} structured result envelope
|
|
5
|
-
*/
|
|
6
|
-
export function handleRequest({ intent, actor, chat, dispatch, journal, tools, gate, buildSystem, grounding }: {
|
|
7
|
-
intent: string;
|
|
8
|
-
actor: object;
|
|
9
|
-
chat: Function;
|
|
10
|
-
dispatch: Function;
|
|
11
|
-
journal: object;
|
|
12
|
-
tools: object[];
|
|
13
|
-
gate: Function;
|
|
14
|
-
buildSystem?: Function;
|
|
15
|
-
grounding?: object;
|
|
16
|
-
}): Promise<object>;
|
|
17
|
-
/**
|
|
18
|
-
* Resume a conversation with a follow-up / clarification answer.
|
|
19
|
-
* @param {{ requestId: string, message: string, actor: object, chat: Function, dispatch: Function, journal: object, tools: object[], gate: Function }} opts resume parameters
|
|
20
|
-
* @returns {Promise<object>} updated result envelope
|
|
21
|
-
*/
|
|
22
|
-
export function handleRespond({ requestId, message, chat, dispatch, journal, tools, gate }: {
|
|
23
|
-
requestId: string;
|
|
24
|
-
message: string;
|
|
25
|
-
actor: object;
|
|
26
|
-
chat: Function;
|
|
27
|
-
dispatch: Function;
|
|
28
|
-
journal: object;
|
|
29
|
-
tools: object[];
|
|
30
|
-
gate: Function;
|
|
31
|
-
}): Promise<object>;
|
|
32
|
-
/**
|
|
33
|
-
* Approve (or reject) a pending destructive action. Executes with the approver's
|
|
34
|
-
* (human) authority via the injected dispatch — no gate.
|
|
35
|
-
* @param {{ requestId: string, approve: boolean, dispatch: Function, journal: object }} opts approval parameters
|
|
36
|
-
* @returns {Promise<object>} updated result envelope
|
|
37
|
-
*/
|
|
38
|
-
export function handleApprove({ requestId, approve, dispatch, journal }: {
|
|
39
|
-
requestId: string;
|
|
40
|
-
approve: boolean;
|
|
41
|
-
dispatch: Function;
|
|
42
|
-
journal: object;
|
|
43
|
-
}): Promise<object>;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param {object} config kit configuration
|
|
3
|
-
* @param {object[]} config.catalog tool definitions (required)
|
|
4
|
-
* @param {string|((ctx: object) => string)} [config.systemPrompt] domain system prompt (or builder from grounding ctx)
|
|
5
|
-
* @param {(tool: object, input: object) => unknown} [config.transport] backend runner; omit to build the kit without dispatch (manifest/scope only)
|
|
6
|
-
* @param {object} [config.journal] journal store { create, load, update, list }
|
|
7
|
-
* @param {Record<string, number>} [config.actorTiers] max executable tier rank per actor kind
|
|
8
|
-
* @param {{ tool: string, key?: string, fallback?: unknown }} [config.grounding] optional read tool to ground the prompt
|
|
9
|
-
* @returns {{ dispatch: Function|null, classify: Function, scopedManifest: Function, toolManifest: Function, request: Function, respond: Function, approve: Function }} bound kit
|
|
10
|
-
*/
|
|
11
|
-
export function createAgentKit({ catalog, systemPrompt, transport, journal, actorTiers, grounding }?: {
|
|
12
|
-
catalog: object[];
|
|
13
|
-
systemPrompt?: string | ((ctx: object) => string) | undefined;
|
|
14
|
-
transport?: ((tool: object, input: object) => unknown) | undefined;
|
|
15
|
-
journal?: object | undefined;
|
|
16
|
-
actorTiers?: Record<string, number> | undefined;
|
|
17
|
-
grounding?: {
|
|
18
|
-
tool: string;
|
|
19
|
-
key?: string;
|
|
20
|
-
fallback?: unknown;
|
|
21
|
-
} | undefined;
|
|
22
|
-
}): {
|
|
23
|
-
dispatch: Function | null;
|
|
24
|
-
classify: Function;
|
|
25
|
-
scopedManifest: Function;
|
|
26
|
-
toolManifest: Function;
|
|
27
|
-
request: Function;
|
|
28
|
-
respond: Function;
|
|
29
|
-
approve: Function;
|
|
30
|
-
};
|
package/types/core/llm.d.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Run the tool-calling loop until the model answers without a tool call.
|
|
3
|
-
* Accepts either a fresh prompt or an existing messages[] for sessional resume.
|
|
4
|
-
* @param {object} params loop parameters
|
|
5
|
-
* @param {string} [params.prompt] user request (fresh start)
|
|
6
|
-
* @param {object[]} [params.messages] existing conversation to resume (takes priority over prompt)
|
|
7
|
-
* @param {(name: string, input: object) => Promise<object>} params.dispatch tool dispatcher returning an envelope
|
|
8
|
-
* @param {(req: {messages: object[], tools: object[]}) => Promise<object>} params.chat model call returning an assistant message
|
|
9
|
-
* @param {number} [params.maxSteps] safety cap on loop iterations
|
|
10
|
-
* @param {string} [params.system] system prompt (only used when building fresh from prompt)
|
|
11
|
-
* @param {object[]} [params.tools] LLM tool manifest (pass a scoped manifest to restrict)
|
|
12
|
-
* @param {(name: string) => 'allow'|'approval'|'deny'} [params.gate] per-call decision (default: allow)
|
|
13
|
-
* @returns {Promise<{content: string, steps: number, trace: object[], messages: object[], stopped?: string, pendingApproval?: object}>} loop result
|
|
14
|
-
*/
|
|
15
|
-
export function runAgent({ prompt, messages: initialMessages, dispatch, chat, maxSteps, system, tools, gate }: {
|
|
16
|
-
prompt?: string | undefined;
|
|
17
|
-
messages?: object[] | undefined;
|
|
18
|
-
dispatch: (name: string, input: object) => Promise<object>;
|
|
19
|
-
chat: (req: {
|
|
20
|
-
messages: object[];
|
|
21
|
-
tools: object[];
|
|
22
|
-
}) => Promise<object>;
|
|
23
|
-
maxSteps?: number | undefined;
|
|
24
|
-
system?: string | undefined;
|
|
25
|
-
tools?: object[] | undefined;
|
|
26
|
-
gate?: ((name: string) => "allow" | "approval" | "deny") | undefined;
|
|
27
|
-
}): Promise<{
|
|
28
|
-
content: string;
|
|
29
|
-
steps: number;
|
|
30
|
-
trace: object[];
|
|
31
|
-
messages: object[];
|
|
32
|
-
stopped?: string;
|
|
33
|
-
pendingApproval?: object;
|
|
34
|
-
}>;
|
|
35
|
-
/**
|
|
36
|
-
* Build a `chat` function that calls an OpenAI-compatible endpoint (omlx).
|
|
37
|
-
* @param {object} params config
|
|
38
|
-
* @param {string} params.baseUrl base URL incl. /v1 (e.g. http://127.0.0.1:10240/v1)
|
|
39
|
-
* @param {string} params.model served model id
|
|
40
|
-
* @param {string} [params.apiKey] optional bearer token
|
|
41
|
-
* @param {typeof fetch} [params.fetchFn] fetch implementation (injectable for tests / tauri-http)
|
|
42
|
-
* @returns {(req: {messages: object[], tools: object[]}) => Promise<object>} chat function
|
|
43
|
-
*/
|
|
44
|
-
export function createOpenAiChat({ baseUrl, model, apiKey, fetchFn }: {
|
|
45
|
-
baseUrl: string;
|
|
46
|
-
model: string;
|
|
47
|
-
apiKey?: string | undefined;
|
|
48
|
-
fetchFn?: typeof fetch | undefined;
|
|
49
|
-
}): (req: {
|
|
50
|
-
messages: object[];
|
|
51
|
-
tools: object[];
|
|
52
|
-
}) => Promise<object>;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @param {{ baseUrl?: string, apiKey?: string, fetchFn?: typeof fetch, signal?: AbortSignal }} [params] config
|
|
3
|
-
* @returns {Promise<string[]>} loaded model ids (empty on error)
|
|
4
|
-
*/
|
|
5
|
-
export function listOmlxModels({ baseUrl, apiKey, fetchFn, signal }?: {
|
|
6
|
-
baseUrl?: string;
|
|
7
|
-
apiKey?: string;
|
|
8
|
-
fetchFn?: typeof fetch;
|
|
9
|
-
signal?: AbortSignal;
|
|
10
|
-
}): Promise<string[]>;
|
|
11
|
-
/**
|
|
12
|
-
* Pick a model: the preferred one if loaded, else the first available, else ''.
|
|
13
|
-
* @param {string[]} models loaded model ids
|
|
14
|
-
* @param {string} [preferred] preferred id
|
|
15
|
-
* @returns {string} chosen model id
|
|
16
|
-
*/
|
|
17
|
-
export function resolveModel(models: string[], preferred?: string): string;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Is this URL the default local omlx server — the only target eligible for
|
|
3
|
-
* the proxy override? A user who deliberately pointed an app at another
|
|
4
|
-
* host/port must never be silently rerouted (the proxy's upstream is
|
|
5
|
-
* hardwired to the local :8000).
|
|
6
|
-
* @param {string} url candidate base URL
|
|
7
|
-
* @returns {boolean} true for 127.0.0.1:8000 / localhost:8000, false otherwise (incl. parse errors)
|
|
8
|
-
*/
|
|
9
|
-
export function isDirectOmlxUrl(url: string): boolean;
|
|
10
|
-
/**
|
|
11
|
-
* One-shot probe: GET {proxy origin}/health with a short timeout. 2xx means
|
|
12
|
-
* the proxy (and omlx behind it) is alive → use the proxy; anything else
|
|
13
|
-
* (timeout, refused, 502) → use the direct URL.
|
|
14
|
-
* @param {{ directUrl?: string, proxyUrl?: string, fetchFn?: typeof fetch, timeoutMs?: number }} [params] config
|
|
15
|
-
* @returns {Promise<string>} the base URL to use
|
|
16
|
-
*/
|
|
17
|
-
export function resolveOmlxBaseUrl({ directUrl, proxyUrl, fetchFn, timeoutMs, }?: {
|
|
18
|
-
directUrl?: string;
|
|
19
|
-
proxyUrl?: string;
|
|
20
|
-
fetchFn?: typeof fetch;
|
|
21
|
-
timeoutMs?: number;
|
|
22
|
-
}): Promise<string>;
|
|
23
|
-
/**
|
|
24
|
-
* Cached {@link resolveOmlxBaseUrl}: at most one probe per proxyUrl per TTL
|
|
25
|
-
* window, so callers may resolve before every LLM call without paying the
|
|
26
|
-
* probe latency each time, while still noticing the proxy starting/stopping
|
|
27
|
-
* within one TTL.
|
|
28
|
-
* @param {{ directUrl?: string, proxyUrl?: string, fetchFn?: typeof fetch, timeoutMs?: number, ttlMs?: number, now?: () => number }} [params] config
|
|
29
|
-
* @returns {Promise<string>} the base URL to use
|
|
30
|
-
*/
|
|
31
|
-
export function resolveOmlxBaseUrlCached({ ttlMs, now, ...probeOptions }?: {
|
|
32
|
-
directUrl?: string;
|
|
33
|
-
proxyUrl?: string;
|
|
34
|
-
fetchFn?: typeof fetch;
|
|
35
|
-
timeoutMs?: number;
|
|
36
|
-
ttlMs?: number;
|
|
37
|
-
now?: () => number;
|
|
38
|
-
}): Promise<string>;
|
|
39
|
-
/** Test hook: drop all cached probe results. */
|
|
40
|
-
export function __resetOmlxBaseUrlCache(): void;
|
|
41
|
-
export const DIRECT_OMLX_BASE_URL: "http://127.0.0.1:8000/v1";
|
|
42
|
-
export const PROXY_OMLX_BASE_URL: "http://127.0.0.1:8088/v1";
|