@7n/tauri-components 0.7.0 → 0.9.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.
Files changed (36) hide show
  1. package/package.json +5 -1
  2. package/src/components/docs/AgentDialog.md +35 -0
  3. package/src/components/docs/AuditDialog.md +28 -0
  4. package/src/components/docs/BaseDialog.md +22 -0
  5. package/src/components/docs/DialogActions.md +24 -0
  6. package/src/components/docs/RequestView.md +25 -0
  7. package/src/components/docs/StatePill.md +20 -0
  8. package/src/components/docs/index.md +28 -0
  9. package/src/components/docs/status.md +29 -0
  10. package/src/core/acp-agent.js +192 -0
  11. package/src/core/acp-kit.js +260 -0
  12. package/src/core/docs/acp-agent.md +43 -0
  13. package/src/core/docs/acp-kit.md +50 -0
  14. package/src/core/docs/agent-handler.md +31 -0
  15. package/src/core/docs/agent-kit.md +25 -0
  16. package/src/core/docs/dispatch.md +30 -0
  17. package/src/core/docs/llm.md +29 -0
  18. package/src/core/docs/manifest.md +30 -0
  19. package/src/core/docs/omlx-models.md +30 -0
  20. package/src/core/docs/resolve-omlx-base-url.md +40 -0
  21. package/src/core/docs/scope.md +32 -0
  22. package/src/core/docs/tools.md +28 -0
  23. package/src/docs/index.md +54 -0
  24. package/src/index.js +12 -0
  25. package/src/testing/docs/index.md +24 -0
  26. package/src/testing/docs/quasar.md +28 -0
  27. package/src/vue/docs/index.md +28 -0
  28. package/src/vue/docs/journal-store-tauri.md +27 -0
  29. package/src/vue/docs/transports.md +25 -0
  30. package/src/vue/docs/use-acp-agent.md +29 -0
  31. package/src/vue/docs/use-agent.md +29 -0
  32. package/src/vue/docs/use-omlx.md +30 -0
  33. package/src/vue/docs/use-updater.md +31 -0
  34. package/src/vue/index.js +2 -0
  35. package/src/vue/use-acp-agent.js +109 -0
  36. package/src/vue/use-updater.js +116 -0
@@ -0,0 +1,260 @@
1
+ import * as acpAgent from './acp-agent.js'
2
+ import { createDispatch } from './dispatch.js'
3
+ import { classify, DEFAULT_ACTOR_TIERS } from './scope.js'
4
+
5
+ // createAcpAgentKit binds an app's catalog + journal to the ACP execution
6
+ // engine — the ACP-flavored sibling of createAgentKit (agent-kit.js), added
7
+ // alongside it so existing consumers keep working on the old omlx/runAgent
8
+ // path while migrating at their own pace (see SPEC / plan for the sequencing).
9
+ //
10
+ // The two engines differ in where tool dispatch happens: runAgent() drove its
11
+ // own tool-calling loop and dispatched synchronously inside handleRequest.
12
+ // Here the ACP agent process drives its OWN loop and calls domain tools
13
+ // through the Rust-side MCP bridge — so dispatch is triggered by a STANDING
14
+ // listener on `acp://mcp-tool-call`, not by anything in request()/respond().
15
+ // Every such call is tier-classified as an `{kind:'agent'}` actor, since by
16
+ // construction only an autonomous agent process can reach the bridge.
17
+ //
18
+ // Scope: one active session/request at a time, matching how AgentDialog is
19
+ // actually used today (a single live conversation). A tool call or permission
20
+ // request always attaches its `needs_approval` state to whichever journal
21
+ // request is currently active — concurrent sessions would need per-session
22
+ // routing, which isn't attempted here.
23
+
24
+ const AGENT_ACTOR = { kind: 'agent', id: 'acp' }
25
+ const QUESTION_RE = /\?\s*$/
26
+
27
+ /**
28
+ * @param {string} text candidate text
29
+ * @returns {boolean} true when text ends with a question mark
30
+ */
31
+ function isQuestion(text) {
32
+ return typeof text === 'string' && QUESTION_RE.test(text.trim())
33
+ }
34
+
35
+ /**
36
+ * Derive the structured result fields from a runAcpTurn() result.
37
+ * @param {{content: string, stopped?: string}} turn runAcpTurn result
38
+ * @returns {{status: string, summary: string|null, question: string|null}} fields
39
+ */
40
+ function finalizeTurn(turn) {
41
+ const question = isQuestion(turn.content) ? turn.content : null
42
+ let status = 'done'
43
+ if (turn.stopped === 'max_steps' || turn.stopped === 'refusal') status = 'partial'
44
+ else if (turn.stopped === 'cancelled') status = 'partial'
45
+ else if (question) status = 'needs_clarification'
46
+ return { status, summary: question ? null : (turn.content || null), question }
47
+ }
48
+
49
+ /**
50
+ * @param {object} config kit configuration
51
+ * @param {object[]} config.catalog tool definitions (required)
52
+ * @param {object} config.journal journal store { create, load, update, list }
53
+ * @param {(tool: object, input: object) => unknown} [config.transport] backend runner for domain tools; omit for a chat-only kit (no domain MCP tools)
54
+ * @param {Record<string, number>} [config.actorTiers] max executable tier rank per actor kind
55
+ * @param {object} [config.deps] injectable `acp-agent.js` functions (tests only — defaults to the real module)
56
+ * @returns {{request: Function, respond: Function, approve: Function}} bound kit
57
+ */
58
+ export function createAcpAgentKit({ catalog, journal, transport, actorTiers = DEFAULT_ACTOR_TIERS, deps = acpAgent } = {}) {
59
+ if (!Array.isArray(catalog)) throw new Error('createAcpAgentKit: catalog (array) is required')
60
+
61
+ const dispatch = transport ? createDispatch(catalog, transport) : null
62
+ let activeSessionKey = null
63
+ let activeRequestId = null
64
+ let listening = false
65
+
66
+ /**
67
+ * Resolve one pending MCP tools/call per the tier decision. Called once per
68
+ * `acp://mcp-tool-call` event.
69
+ * @param {{requestId: string, tool: string, input: object}} payload event payload
70
+ * @returns {Promise<void>} resolves once the bridge has an answer
71
+ */
72
+ async function handleToolCall({ requestId, tool, input }) {
73
+ if (!dispatch) {
74
+ await deps.respondAcpToolCall(requestId, { ok: false, error: { code: 'forbidden', message: 'No transport configured.' } })
75
+ return
76
+ }
77
+ const decision = classify(catalog, actorTiers, AGENT_ACTOR, tool)
78
+ if (decision === 'deny') {
79
+ await deps.respondAcpToolCall(requestId, { ok: false, error: { code: 'forbidden', message: `Tool "${tool}" is not allowed.` } })
80
+ return
81
+ }
82
+ if (decision === 'approval') {
83
+ if (activeRequestId) {
84
+ await journal.update(activeRequestId, { status: 'needs_approval', pendingApproval: { kind: 'mcp', requestId, tool, input } })
85
+ }
86
+ return // acp_mcp_tool_result comes later, from approve()
87
+ }
88
+ await deps.respondAcpToolCall(requestId, await dispatch(tool, input))
89
+ }
90
+
91
+ /**
92
+ * Mirror a native ACP `session/request_permission` into the same
93
+ * `pendingApproval` shape as an MCP tool-call pause, so `AuditDialog` only
94
+ * has to understand one contract.
95
+ * @param {{requestId: string, toolCall: object, options: {optionId: string, name: string, kind: string}[]}} payload event payload
96
+ * @returns {Promise<void>} resolves once the journal is updated
97
+ */
98
+ async function handlePermissionRequest(payload) {
99
+ if (!activeRequestId) return
100
+ await journal.update(activeRequestId, { status: 'needs_approval', pendingApproval: { kind: 'acp', ...payload } })
101
+ }
102
+
103
+ /**
104
+ * Start listening for domain tool calls and native permission requests —
105
+ * lazy, once per kit, since it applies to every session this kit drives.
106
+ * @returns {Promise<void>} resolves once both listeners are attached
107
+ */
108
+ async function ensureListening() {
109
+ if (listening) return
110
+ listening = true
111
+ await deps.onAcpToolCall(handleToolCall)
112
+ await deps.onAcpPermissionRequest(handlePermissionRequest)
113
+ }
114
+
115
+ /**
116
+ * Run one turn, journal the result, and reset `pendingApproval`. Callers
117
+ * must set `activeRequestId` themselves *before* starting the turn — a
118
+ * tool-call/permission-request can arrive (and needs to see the right id)
119
+ * while the turn's own promise is still pending, so setting it here as a
120
+ * side effect of awaiting would be too late.
121
+ * @param {string} requestId journal record id
122
+ * @param {object[]} baseActions actions already recorded for this request
123
+ * @param {Promise<object>} turnPromise the in-flight `runAcpTurn` call
124
+ * @returns {Promise<object>} structured result envelope
125
+ */
126
+ async function runAndJournal(requestId, baseActions, turnPromise) {
127
+ let turn
128
+ try {
129
+ turn = await turnPromise
130
+ }
131
+ catch (error) {
132
+ await journal.update(requestId, { status: 'failed', error: String(error?.message ?? error) })
133
+ return { requestId, status: 'failed', summary: null, actions: baseActions, question: null, pendingApproval: null }
134
+ }
135
+ const fields = finalizeTurn(turn)
136
+ const actions = [...baseActions, ...turn.trace]
137
+ await journal.update(requestId, { ...fields, messages: turn.messages, actions, pendingApproval: null })
138
+ return { requestId, ...fields, actions, pendingApproval: null }
139
+ }
140
+
141
+ return {
142
+ /**
143
+ * Start a new ACP-backed request: spawns the agent session and runs the
144
+ * first prompt turn.
145
+ * @param {{intent: string, agent: object}} opts `agent` is passed straight to `createAcpSession` (agentKind/command/args/env/cwd/…)
146
+ * @returns {Promise<object>} structured result envelope
147
+ */
148
+ async request({ intent, agent }) {
149
+ await ensureListening()
150
+ const id = await journal.create({ intent, actor: AGENT_ACTOR })
151
+ await journal.update(id, { status: 'running' })
152
+ const session = await deps.createAcpSession(agent)
153
+ activeSessionKey = session.sessionKey
154
+ activeRequestId = id
155
+ await journal.update(id, { acp: { agentKind: session.agentKind, sessionKey: session.sessionKey } })
156
+ return runAndJournal(id, [], deps.runAcpTurn({ sessionKey: activeSessionKey, text: intent }))
157
+ },
158
+
159
+ /**
160
+ * Continue the active session with a follow-up message.
161
+ * @param {{requestId: string, message: string}} opts resume parameters
162
+ * @returns {Promise<object>} updated result envelope
163
+ */
164
+ async respond({ requestId, message }) {
165
+ if (!activeSessionKey) {
166
+ return { requestId, status: 'failed', summary: null, actions: [], question: 'No active ACP session.', pendingApproval: null }
167
+ }
168
+ let record
169
+ try {
170
+ record = await journal.load(requestId)
171
+ }
172
+ catch {
173
+ return { requestId, status: 'failed', summary: null, actions: [], question: 'Request not found.', pendingApproval: null }
174
+ }
175
+ await journal.update(requestId, { status: 'running' })
176
+ activeRequestId = requestId
177
+ return runAndJournal(requestId, record.actions ?? [], deps.runAcpTurn({ sessionKey: activeSessionKey, text: message }))
178
+ },
179
+
180
+ /**
181
+ * Resolve a pending approval — either an MCP domain-tool call or a native
182
+ * ACP permission request, whichever is attached to this journal record.
183
+ * @param {{requestId: string, approve: boolean}} opts approval parameters
184
+ * @returns {Promise<object>} updated result envelope
185
+ */
186
+ async approve({ requestId, approve: decision }) {
187
+ let record
188
+ try {
189
+ record = await journal.load(requestId)
190
+ }
191
+ catch {
192
+ return { requestId, status: 'failed', summary: null, actions: [], question: 'Request not found.', pendingApproval: null }
193
+ }
194
+
195
+ const pending = record.pendingApproval
196
+ if (record.status !== 'needs_approval' || !pending) {
197
+ return { requestId, status: record.status, summary: record.summary, actions: record.actions ?? [], question: null, pendingApproval: null }
198
+ }
199
+
200
+ if (pending.kind === 'acp') return approveAcpPermission(deps, journal, requestId, record, pending, decision)
201
+ return approveMcpToolCall(deps, dispatch, journal, requestId, record, pending, decision)
202
+ },
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Resolve a pending MCP domain-tool call (reject with a forbidden envelope,
208
+ * or dispatch and forward the real envelope) and unblock the agent.
209
+ *
210
+ * Deliberately does **not** declare a terminal `done`/`rejected` status: once
211
+ * we reply to the agent's `tools/call`, its turn keeps running in the
212
+ * background — the in-flight `request()`/`respond()` call's `runAndJournal`
213
+ * is the only thing that will observe how the turn actually concludes (it
214
+ * may make more tool calls, or answer differently than a flat "done" would
215
+ * suggest), so it's the sole writer of the final journal state. This also
216
+ * means the old "retry a failed dispatch" UX doesn't carry over: once the
217
+ * agent has been told a tool call failed, it has already moved on.
218
+ * @param {object} deps injected acp-agent.js functions
219
+ * @param {Function} dispatch bound `createDispatch` result
220
+ * @param {object} journal journal store
221
+ * @param {string} requestId journal record id
222
+ * @param {object} record loaded journal record
223
+ * @param {{requestId: string, tool: string, input: object}} pending the paused MCP call
224
+ * @param {boolean} decision approve (true) or reject (false)
225
+ * @returns {Promise<object>} immediate (non-terminal) result envelope
226
+ */
227
+ async function approveMcpToolCall(deps, dispatch, journal, requestId, record, pending, decision) {
228
+ const envelope = decision
229
+ ? await dispatch(pending.tool, pending.input)
230
+ : { ok: false, error: { code: 'forbidden', message: 'Rejected by human.' } }
231
+ await deps.respondAcpToolCall(pending.requestId, envelope)
232
+
233
+ const actions = [...(record.actions ?? []), { tool: pending.tool, input: pending.input, envelope }]
234
+ await journal.update(requestId, { status: 'running', actions, pendingApproval: null })
235
+ return { requestId, status: 'running', summary: null, actions, question: null, pendingApproval: null }
236
+ }
237
+
238
+ /**
239
+ * Resolve a native ACP `session/request_permission` by selecting the
240
+ * matching allow/reject option (`kind` from `PermissionOptionView`, see
241
+ * `tauri-plugin-agent/src/acp/mod.rs`) and unblock the agent. Falls back to
242
+ * the first option if none of the requested kind is offered. Same
243
+ * non-terminal-status rule as `approveMcpToolCall` — the agent's turn is
244
+ * still running.
245
+ * @param {object} deps injected acp-agent.js functions
246
+ * @param {object} journal journal store
247
+ * @param {string} requestId journal record id
248
+ * @param {object} record loaded journal record
249
+ * @param {{requestId: string, options: {optionId: string, kind: string}[]}} pending the paused permission request
250
+ * @param {boolean} decision approve (true) or reject (false)
251
+ * @returns {Promise<object>} immediate (non-terminal) result envelope
252
+ */
253
+ async function approveAcpPermission(deps, journal, requestId, record, pending, decision) {
254
+ const wantPrefix = decision ? 'allow' : 'reject'
255
+ const option = pending.options?.find(o => o.kind?.startsWith(wantPrefix)) ?? pending.options?.[0]
256
+ await deps.respondAcpPermission(pending.requestId, option?.optionId)
257
+
258
+ await journal.update(requestId, { status: 'running', pendingApproval: null })
259
+ return { requestId, status: 'running', summary: null, actions: record.actions ?? [], question: null, pendingApproval: null }
260
+ }
@@ -0,0 +1,43 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/core/acp-agent.js
4
+ crc: e30fb954
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
+ # acp-agent.js
12
+
13
+ ## Огляд
14
+
15
+ Модуль керує життєвим циклом сесій агента ACP. Він дозволяє ініціалізувати сесії за допомогою `createAcpSession`, виконувати ходи промпта через `runAcpTurn` та скасовувати сесії за допомогою `cancelAcpSession`. Модуль встановлює мережевий зв'язок через http://127.0.0.1:54321/ та ініціалізує MCP-міст за допомогою `startAcpMcpBridge`. Він реєструє інструменти та обробляє запити на виклики інструментів через `onAcpToolCall` та відповіді на них через `respondAcpToolCall`. Модуль також обробляє запити на дозволи через `onAcpPermissionRequest` та надає відповіді за допомогою `respondAcpPermission`. Модуль надає конфігурацію типу агента за допомогою `acpConfig`. Усі помилки перехоплюються (fail-safe), і винятки не викидаються назовні.
16
+
17
+ ## Поведінка
18
+
19
+ createAcpSession запускає підпроцес агента ACP та ініціалізує його сесію, повертаючи ключ сесії.
20
+ runAcpTurn виконує один хід промпта для існуючої сесії ACP, потоково передаючи оновлення сесії.
21
+ cancelAcpSession відсилає команду на скасування поточного промпт-ходу для сесії ACP.
22
+ onAcpToolCall підписується на події виклику інструменту, ініційовані агентом через MCP-міст.
23
+ respondAcpToolCall вирішує очікуваний виклик інструменту, надаючи результат агенту.
24
+ onAcpPermissionRequest підписується на запити дозволу від агента, наприклад, на доступ до файлової системи.
25
+ respondAcpPermission вирішує очікуваний запит дозволу, обираючи один із запропонованих варіантів.
26
+ startAcpMcpBridge реєструє каталог інструментів цього застосунку в доменному MCP-міст та запускає його, повертаючи URL, наприклад, http://127.0.0.1:54321/.
27
+ acpConfig зчитує за замовчуванням тип агента для машини.
28
+
29
+ ## Публічний API
30
+
31
+ createAcpSession — Запускає підпроцес агента ACP та виконує ініціалізацію з'єднання, повертаючи ідентифікатор сесії.
32
+ runAcpTurn — Виконує один раунд взаємодії з агентом у вже ініційованій сесії, передаючи оновлення сесії.
33
+ cancelAcpSession — Змушує агента припинити поточний раунд взаємодії.
34
+ onAcpToolCall — Підписується на виклик інструменту, який агент ініціював через MCP-міст, очікуючи на результат.
35
+ respondAcpToolCall — Надає відповідь на очікуваний виклик інструменту, який був ініційований агентом.
36
+ onAcpPermissionRequest — Підписується на запит дозволу від агента (наприклад, на виконання команд або редагування файлів).
37
+ respondAcpPermission — Приймає рішення щодо запиту дозволу, ініційованого агентом.
38
+ startAcpMcpBridge — Реєструє каталог інструментів цього застосунку в доменному MCP-міст і запускає його.
39
+ acpConfig — Зчитує за замовчуванням тип агента для цієї машини з змінної середовища. Доступні дані можна переглянути за адресою http://127.0.0.1:54321/.
40
+
41
+ ## Гарантії поведінки
42
+
43
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
@@ -0,0 +1,50 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/core/acp-kit.js
4
+ crc: caab4cf6
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ judgeModel: openai-codex/gpt-5.4-mini
8
+ ---
9
+
10
+ # acp-kit.js
11
+
12
+ ## Огляд
13
+
14
+ Модуль ініціалізує агента та керує життєвим циклом його запитів. Функція `createAcpAgentKit` створює агента на основі заданих компонентів. Модуль дозволяє розпочинати нові запити, продовжувати активні сесії або вирішувати відкладені питання, такі як виклики інструментів чи запити на дозвіл.
15
+
16
+ ## Поведінка
17
+
18
+ 1. Викликати createAcpAgentKit, надаючи каталог інструментів, сховище журналу та, за бажанням, транспортний механізм, набір рівнів акторів та залежності.
19
+ 2. При виклику createAcpAgentKit, якщо надано транспортний механізм, створюється механізм диспетчеризації.
20
+ 3. Викликати request, щоб розпочати новий запит:
21
+ а. Забезпечити активне прослуховування подій.
22
+ б. Створити новий запис у журналі з інформацією про намір та актора.
23
+ в. Оновити запис у журналі на статус "running".
24
+ г. Створити сесію агента.
25
+ д. Встановити ключ сесії та ідентифікатор запиту як активні.
26
+ е. Оновити запис у журналі з метаданими сесії.
27
+ ж. Виконати перший хід агента, використовуючи наданий текст наміру, і зафіксувати результат у журналі.
28
+ 4. Викликати respond, щоб продовжити активну сесію:
29
+ а. Перевірити наявність активної сесії.
30
+ б. Завантажити поточний запис із журналу.
31
+ в. Оновити запис у журналі на статус "running".
32
+ г. Встановити ідентифікатор запиту як активний.
33
+ г. Виконати наступний хід агента, використовуючи надане повідомлення, і зафіксувати результат у журналі.
34
+ 5. Викликати approve, щоб вирішити відкладене схвалення:
35
+ а. Завантажити відповідний запис із журналу.
36
+ б. Перевірити, чи запис перебуває у стані "needs_approval" та має відкладене схвалення.
37
+ в. Якщо відкладене схвалення є MCP-виклик інструменту, викликати approveMcpToolCall:
38
+ а. Виконати диспетчеризацію інструменту або створити відповідь про заборону.
39
+ б. Надіслати відповідь агенту про результат виклику інструменту.
40
+ в. Оновити запис у журналі, додавши інформацію про виклик інструменту та скинувши відкладене схвалення.
41
+ в. Повернути результат, що вказує на статус "running".
42
+ г. Якщо відкладене схвалення є запит на дозвіл ACP, викликати approveAcpPermission:
43
+ а. Знайти відповідний варіант дозвілу або обрати перший варіант.
44
+ б. Надіслати відповідь агенту з обраним ідентифікатором варіанта.
45
+ в. Оновити запис у журналі, скинувши відкладене схвалення.
46
+ в. Повернути результат, що вказує на статус "running".
47
+
48
+ ## Гарантії поведінки
49
+
50
+ - (специфічних машинно-виведених гарантій немає)
@@ -0,0 +1,31 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/core/agent-handler.js
4
+ crc: 8ef1230c
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ issues: judge:inaccurate:0.97
8
+ judgeModel: openai-codex/gpt-5.4-mini
9
+ ---
10
+
11
+ # agent-handler.js
12
+
13
+ ## Огляд
14
+
15
+ Модуль керує життєвим циклом агентського запиту. Він ініціює запит через `handleRequest`, підтримує діалог з користувачем через `handleRespond` та реалізує логіку схвалення через `handleApprove`.
16
+
17
+ ## Поведінка
18
+
19
+ handleRequest ініціює новий агентський запит, створює запис у журналі та запускає цикл агента.
20
+ handleRespond продовжує розмову, використовуючи попередній стан запису та нове повідомлення користувача.
21
+ handleApprove виконує або відхиляє заплановану деструктивну дію, якщо запис перебуває у стані очікування схвалення.
22
+
23
+ ## Публічний API
24
+
25
+ handleRequest — Ініціює новий запит до агента.
26
+ handleRespond — Продовжує діалог, надаючи відповідь або уточнення.
27
+ handleApprove — Підтверджує (або відхиляє) заплановану руйнівну дію, виконуючи її з дозволу користувача.
28
+
29
+ ## Гарантії поведінки
30
+
31
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
@@ -0,0 +1,25 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/core/agent-kit.js
4
+ crc: 27461b4b
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ judgeModel: openai-codex/gpt-5.4-mini
8
+ ---
9
+
10
+ # agent-kit.js
11
+
12
+ ## Огляд
13
+
14
+ Цей модуль відповідає за ініціалізацію та конфігурування набору інструментів для агента. Функція `createAgentKit` створює об'єкт, що містить необхідні методи та механізми для роботи агента, забезпечуючи його доступ до інструментів та системних налаштувань.
15
+
16
+ ## Поведінка
17
+
18
+ 1. Викликати `createAgentKit` для створення набору інструментів агента.
19
+ 2. Надати `createAgentKit` каталог інструментів.
20
+ 3. За бажанням надати системний підказку, транспортний механізм, сховище журналу, рівні акторів та інструмент для заземлення.
21
+ 4. Отримати об'єкт набору інструментів, що містить функції для диспетчеризації, класифікації, отримання маніфесту інструментів, створення запитів, відповідей та схвалення.
22
+
23
+ ## Гарантії поведінки
24
+
25
+ - (специфічних машинно-виведених гарантій немає)
@@ -0,0 +1,30 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/core/dispatch.js
4
+ crc: 57a74200
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
+ # dispatch.js
12
+
13
+ ## Огляд
14
+
15
+ Модуль забезпечує валідацію вхідних даних та диспетчеризацію виконання інструментів. Функція `validateInput` перевіряє вхідні дані на відповідність визначеній схемі. Після успішної валідації функція `createDispatch` створює механізм виконання інструменту. Модуль гарантує перехоплення всіх помилок (fail-safe) та не генерує винятків назовні. Модуль не виконує операцій, що змінюють стан (не пише у ФС/БД).
16
+
17
+ ## Поведінка
18
+
19
+ validateInput перевіряє вхідні дані на відповідність схемі інструменту та кастомному валідатору.
20
+ createDispatch створює функцію, яка виконує інструмент після валідації вхідних даних, повертаючи обгортку з результатом або помилкою.
21
+
22
+ ## Публічний API
23
+
24
+ validateInput — порівнює об'єкт вхідних даних зі схемою інструменту та користувацьким валідатором.
25
+ createDispatch — створює функцію для відправки, прив'язану до каталогу та системи транспортування.
26
+
27
+ ## Гарантії поведінки
28
+
29
+ - Read-only: не виконує операцій запису (ФС/БД).
30
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
@@ -0,0 +1,29 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/core/llm.js
4
+ crc: 2f379651
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
+ # llm.js
12
+
13
+ ## Огляд
14
+
15
+ Модуль дозволяє ініціювати сеанс чату з мовною моделлю через мережевий ендпоінт http://127.0.0.1:10240/v1. Функціонал реалізується через публічні функції `runAgent` та `createOpenAiChat`. Код виконує виклик API та керує циклом виклику інструментів у контексті агента, доки модель не надасть фінальну відповідь або не буде перевищено ліміт кроків. Робота залежить від конфігурації, описаної у `response.json`.
16
+
17
+ ## Поведінка
18
+
19
+ runAgent виконує цикл виклику інструментів, поки модель не надасть відповідь без виклику інструменту, або доки не буде досягнуто максимальної кількості кроків.
20
+ createOpenAiChat створює функцію, яка викликає мережевий ендпоінт OpenAI-сумісного API (наприклад, http://127.0.0.1:10240/v1) для отримання відповіді моделі.
21
+
22
+ ## Публічний API
23
+
24
+ runAgent — Запускає цикл виклику інструментів до моменту, коли модель надає відповідь без виклику інструменту. Може використовувати новий запит або продовжувати сесію на основі існуючої історії повідомлень.
25
+ createOpenAiChat — Створює функцію для взаємодії з кінцевою точкою, сумісною з OpenAI (omlx).
26
+
27
+ ## Гарантії поведінки
28
+
29
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -0,0 +1,30 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/core/manifest.js
4
+ crc: 0db5edce
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ judgeModel: openai-codex/gpt-5.4-mini
8
+ ---
9
+
10
+ # manifest.js
11
+
12
+ ## Огляд
13
+
14
+ Модуль реалізує функції для роботи зі специфікаціями інструментів. Він перетворює специфікації інструментів у формат JSON Schema. Модуль генерує повний маніфест інструментів у форматі OpenAI та створює спрощені списки інструментів, що містять їхні імена та описи.
15
+
16
+ ## Поведінка
17
+
18
+ toJsonSchema перетворює специфікацію вхідних даних інструменту на об'єкт JSON Schema.
19
+ toolManifest створює масив визначень інструментів у форматі OpenAI, фільтруючи їх за наданим предикатом.
20
+ listTools створює компактний список інструментів, що містить лише їхні імена та короткі описи.
21
+
22
+ ## Публічний API
23
+
24
+ toJsonSchema — перетворює опис вхідних даних інструменту на об'єкт JSON Schema.
25
+ toolManifest — надає визначення інструментів для виклику функцій OpenAI, з можливістю фільтрації.
26
+ listTools — виводить стислий перелік доступних інструментів (назва та короткий опис).
27
+
28
+ ## Гарантії поведінки
29
+
30
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -0,0 +1,30 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/core/omlx-models.js
4
+ crc: 81a5dc3a
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ issues: judge:inaccurate:0.97
8
+ judgeModel: openai-codex/gpt-5.4-mini
9
+ ---
10
+
11
+ # omlx-models.js
12
+
13
+ ## Огляд
14
+
15
+ Модуль надає публічні механізми для взаємодії з локально завантаженими моделями. Він дозволяє отримати повний список доступних моделей та вибрати конкретну модель із цього списку. Функціонал працює в режимі, що перехоплює помилки (fail-safe), і не здійснює запису у файлову систему чи бази даних. Робота модуля залежить від конфігурацій, зокрема `response.json`.
16
+
17
+ ## Поведінка
18
+
19
+ listOmlxModels отримує список ідентифікаторів моделей, завантажених локальним сервером, або повертає порожній масив у разі будь-якої помилки.
20
+ resolveModel обирає модель з наданого списку, надаючи пріоритет обраній моделі, або повертає першу доступну модель, якщо пріоритетна відсутня.
21
+
22
+ ## Публічний API
23
+
24
+ listOmlxModels — отримує список доступних моделей.
25
+ resolveModel — вибирає модель: обрану, якщо вона завантажена, інакше першу доступну, або порожній рядок.
26
+
27
+ ## Гарантії поведінки
28
+
29
+ - Read-only: не виконує операцій запису (ФС/БД).
30
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
@@ -0,0 +1,40 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/core/resolve-omlx-base-url.js
4
+ crc: 36c282c7
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ issues: judge:inaccurate:0.99
8
+ judgeModel: openai-codex/gpt-5.4-mini
9
+ ---
10
+
11
+ # resolve-omlx-base-url.js
12
+
13
+ ## Огляд
14
+
15
+ Модуль визначає та надає базові URL для взаємодії з серверами omlx. Він експортує константи: DIRECT_OMLX_BASE_URL="http://127.0.0.1:8000/v1" для прямого доступу та PROXY_OMLX_BASE_URL="http://127.0.0.1:8088/v1" для проксі-доступу. Модуль звертається до мережі для визначення робочого URL, перевіряючи доступність проксі-сервера. Вибір URL кешується у межах прогону. При помилках мережевого доступу модуль перехоплює їх (fail-safe) і повертає порожнє значення замість кидання винятків. Модуль є лише для читання (не виконує операцій з ФС/БД).
16
+
17
+ ## Поведінка
18
+
19
+ DIRECT_OMLX_BASE_URL: Надає базовий URL для прямого доступу до сервера omlx, який є http://127.0.0.1:8000/v1.
20
+ PROXY_OMLX_BASE_URL: Надає базовий URL для доступу через проксі-сервер omlx, який є http://127.0.0.1:8088/v1.
21
+ isDirectOmlxUrl: Перевіряє, чи вказаний URL є стандартним локальним сервером omlx (http://127.0.0.1:8000 або localhost:8000).
22
+ resolveOmlxBaseUrl: Визначає ефективний базовий URL omlx, перевіряючи доступність проксі-сервера через зондування `/health`; у разі успіху повертає URL проксі, інакше — прямий URL.
23
+ resolveOmlxBaseUrlCached: Визначає ефективний базовий URL omlx, використовуючи кешування для уникнення повторних зондувань протягом заданого часу життя (TTL).
24
+ __resetOmlxBaseUrlCache: Очищає кеш результатів зондування базового URL omlx.
25
+
26
+ ## Публічний API
27
+
28
+ DIRECT_OMLX_BASE_URL — Базовий URL для прямого доступу до локального OMLX сервера, що вказує на http://127.0.0.1:8000/v1.
29
+ PROXY_OMLX_BASE_URL — Базовий URL для проксі-доступу до OMLX сервера, що вказує на http://127.0.0.1:8088/v1.
30
+ isDirectOmlxUrl — Визначає, чи є URL основним локальним сервером OMLX, який не повинен бути перенаправлений через проксі.
31
+ resolveOmlxBaseUrl — Перевіряє доступність проксі-сервера шляхом виконання GET-запиту до http://127.0.0.1:8088/v1; якщо відповідь успішна, використовується проксі, інакше — прямий URL.
32
+ resolveOmlxBaseUrlCached — Виконує перевірку доступності проксі-сервера з кешуванням, щоб уникнути повторних перевірок при кожному виклику LLM.
33
+ __resetOmlxBaseUrlCache — Очищає всі збережені результати перевірки доступності базового URL OMLX.
34
+
35
+ ## Гарантії поведінки
36
+
37
+ - Read-only: не виконує операцій запису (ФС/БД).
38
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
39
+ - За певних помилок повертає порожнє значення (напр. `null`) замість винятку.
40
+ - Кешує результати в межах одного прогону.
@@ -0,0 +1,32 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/core/scope.js
4
+ crc: e3226974
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ judgeModel: openai-codex/gpt-5.4-mini
8
+ ---
9
+
10
+ # scope.js
11
+
12
+ ## Огляд
13
+
14
+ Модуль визначає та керує дозволами акторів на використання інструментів. Він встановлює рівні акторів за допомогою `DEFAULT_ACTOR_TIERS`, визначає доступні інструменти для кожного актора через `scopedToolNames` та надає маніфест дозволів за допомогою `scopedManifest`.
15
+
16
+ ## Поведінка
17
+
18
+ DEFAULT_ACTOR_TIERS визначає максимальний рівень виконання для різних типів акторів.
19
+ classify визначає, чи дозволено актору викликати інструмент, чи потрібне схвалення, чи заборонено.
20
+ scopedManifest повертає перелік інструментів, які актор може виконати або для яких потрібне схвалення.
21
+ scopedToolNames повертає список назв інструментів, які актор бачить.
22
+
23
+ ## Публічний API
24
+
25
+ DEFAULT_ACTOR_TIERS — Визначає рівні доступу для акторів.
26
+ classify — Визначає, до якого актора належить виклик інструменту.
27
+ scopedManifest — Перелік інструментів, доступних актору для виконання або запиту дозволу.
28
+ scopedToolNames — Список назв інструментів, видимих актору.
29
+
30
+ ## Гарантії поведінки
31
+
32
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -0,0 +1,28 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/core/tools.js
4
+ crc: 9fa4e875
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ judgeModel: openai-codex/gpt-5.4-mini
8
+ ---
9
+
10
+ # tools.js
11
+
12
+ ## Огляд
13
+
14
+ Модуль сканує заданий каталог для пошуку визначень інструментів. Він встановлює наявність інструменту за його ім'ям і повертає його визначення або `null`, якщо інструмент не знайдено.
15
+
16
+ ## Поведінка
17
+
18
+ 1. Визначає, чи існує інструмент у наданому каталозі, порівнюючи його ім'я з вказаним.
19
+ 2. Повертає визначення інструмента, якщо він знайдений.
20
+ 3. Повертає `null`, якщо інструмент не знайдено в каталозі.
21
+
22
+ ## Публічний API
23
+
24
+ getTool — знаходить інструмент за його назвою у каталозі.
25
+
26
+ ## Гарантії поведінки
27
+
28
+ - Read-only: не виконує операцій запису (ФС/БД).