@7n/tauri-components 0.11.2 → 0.13.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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.13.0] - 2026-07-20
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- AgentDialog.vue: мітка агент·модель над кожною відповіддю в чаті — фіксується на request(), не змінюється для наступних respond() у тій самій розмові (перемикання агента/тіру діє лише на нову сесію)
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- useAcpAgent(): перемикання agent у picker більше не лишає modelTier зі значенням попереднього агента (напр. cursor's AVG="Grok 4.5" після переключення на pi, де тірів взагалі нема) — тепер watch(agentKind) перерезолвлює modelTier під новий агент
|
|
12
|
+
|
|
13
|
+
## [0.12.0] - 2026-07-20
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Storybook (Vue3 + Vite) для компонентів `npm/src/components/` — конфіг у
|
|
18
|
+
`npm/.storybook/`, по одному `*.stories.js` на компонент (`BaseDialog`,
|
|
19
|
+
`DialogActions`, `StatePill`, `RequestView`, `AgentDialog`, `AuditDialog`), і
|
|
20
|
+
named vitest-проєкт `"storybook"` (`@storybook/addon-vitest`, browser mode,
|
|
21
|
+
Playwright Chromium) поряд з canonical `"unit"`-проєктом у `npm/vitest.config.mjs`
|
|
22
|
+
— вмикає окремий вимір покриття `Vue (Storybook)` через `@7n/test coverage`.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- docs(changelog): додано change-файл для поточних змін у npm workspace
|
|
27
|
+
- chore(lint): дозаповнено cspell-словник, авто-fix markdownlint у docs/
|
|
28
|
+
|
|
3
29
|
## [0.11.2] - 2026-07-19
|
|
4
30
|
|
|
5
31
|
### Changed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@7n/tauri-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Shared LLM agent engine + Vue/Quasar UI for Tauri apps (chat, journal, trust-tier approval).",
|
|
6
6
|
"license": "MIT",
|
|
@@ -63,6 +63,9 @@
|
|
|
63
63
|
"@storybook/addon-vitest": "^10.5.2",
|
|
64
64
|
"@storybook/vue3-vite": "^10.5.2",
|
|
65
65
|
"@vitejs/plugin-vue": "^6.0.8",
|
|
66
|
+
"@vitest/browser": "^4.1.10",
|
|
67
|
+
"@vitest/browser-playwright": "^4.1.10",
|
|
68
|
+
"playwright": "^1.61.1",
|
|
66
69
|
"storybook": "^10.5.2"
|
|
67
70
|
}
|
|
68
71
|
}
|
|
@@ -29,7 +29,10 @@
|
|
|
29
29
|
<div v-if="turns.length" ref="logEl" class="chat-log">
|
|
30
30
|
<template v-for="(turn, i) in turns" :key="i">
|
|
31
31
|
<div v-if="turn.role === 'user'" class="chat-user">{{ turn.text }}</div>
|
|
32
|
-
<
|
|
32
|
+
<template v-else>
|
|
33
|
+
<div class="chat-model-label">{{ turn.agentLabel }}</div>
|
|
34
|
+
<RequestView :result="turn.result" />
|
|
35
|
+
</template>
|
|
33
36
|
</template>
|
|
34
37
|
<div v-if="running" class="chat-thinking"><q-spinner-dots size="18px" /> думаю…</div>
|
|
35
38
|
</div>
|
|
@@ -85,6 +88,21 @@ const turns = ref([])
|
|
|
85
88
|
const requestId = ref(null)
|
|
86
89
|
const logEl = ref(null)
|
|
87
90
|
const showConfig = ref(false)
|
|
91
|
+
// Latched at the start of a conversation (request()) and reused for every
|
|
92
|
+
// respond() in it: resuming a session keeps talking to whichever agent/tier
|
|
93
|
+
// spawned it — changing the dropdowns mid-conversation only takes effect on
|
|
94
|
+
// the NEXT fresh request(), so re-reading agentKind/modelTier live at every
|
|
95
|
+
// send() would mislabel turns with a model that isn't actually answering.
|
|
96
|
+
const activeAgentLabel = ref('')
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Human-readable "agent · tier" for whichever preset is currently selected.
|
|
100
|
+
* @returns {string} label
|
|
101
|
+
*/
|
|
102
|
+
function currentAgentLabel() {
|
|
103
|
+
const tier = availableTiers.value.find(t => t.id === modelTier.value)
|
|
104
|
+
return `${agentKind.value} · ${tier?.label ?? modelTier.value}`
|
|
105
|
+
}
|
|
88
106
|
|
|
89
107
|
// Labels shift once a conversation is under way (fresh request → follow-up).
|
|
90
108
|
const inputLabel = computed(() => (turns.value.length ? 'Повідомлення' : 'Prompt'))
|
|
@@ -115,7 +133,7 @@ async function scrollToEnd() {
|
|
|
115
133
|
*/
|
|
116
134
|
function apply(outcome) {
|
|
117
135
|
if (outcome.requestId) requestId.value = outcome.requestId
|
|
118
|
-
turns.value.push({ role: 'agent', result: outcome })
|
|
136
|
+
turns.value.push({ role: 'agent', result: outcome, agentLabel: activeAgentLabel.value })
|
|
119
137
|
if (outcome.actions?.some(action => action.envelope?.ok)) emit('ran')
|
|
120
138
|
scrollToEnd()
|
|
121
139
|
}
|
|
@@ -131,6 +149,10 @@ async function send() {
|
|
|
131
149
|
scrollToEnd()
|
|
132
150
|
running.value = true
|
|
133
151
|
try {
|
|
152
|
+
// Only a fresh request() actually spawns with the currently-selected
|
|
153
|
+
// agent/tier — a respond() keeps talking to whatever the conversation
|
|
154
|
+
// already started with, so the label must not move mid-conversation.
|
|
155
|
+
if (!requestId.value) activeAgentLabel.value = currentAgentLabel()
|
|
134
156
|
apply(await (requestId.value ? respond(requestId.value, text) : request(text)))
|
|
135
157
|
} catch (error) {
|
|
136
158
|
$q.notify({ type: 'negative', message: String(error?.message ?? error) })
|
|
@@ -162,6 +184,15 @@ async function send() {
|
|
|
162
184
|
line-height: 1.45;
|
|
163
185
|
}
|
|
164
186
|
|
|
187
|
+
.chat-model-label {
|
|
188
|
+
align-self: flex-start;
|
|
189
|
+
font-size: 11px;
|
|
190
|
+
opacity: 0.6;
|
|
191
|
+
text-transform: uppercase;
|
|
192
|
+
letter-spacing: 0.02em;
|
|
193
|
+
margin-bottom: -4px;
|
|
194
|
+
}
|
|
195
|
+
|
|
165
196
|
.chat-thinking {
|
|
166
197
|
display: flex;
|
|
167
198
|
align-items: center;
|
package/src/vue/use-acp-agent.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { computed, ref } from 'vue'
|
|
1
|
+
import { computed, ref, watch } from 'vue'
|
|
2
2
|
import { acpConfig, startAcpMcpBridge } from '../core/acp-agent.js'
|
|
3
3
|
import { createAcpAgentKit } from '../core/acp-kit.js'
|
|
4
4
|
import { createTauriJournalStore } from './journal-store-tauri.js'
|
|
@@ -47,6 +47,16 @@ export function useAcpAgent({
|
|
|
47
47
|
const journal = createTauriJournalStore()
|
|
48
48
|
const kit = createAcpAgentKit({ catalog, journal, transport, actorTiers })
|
|
49
49
|
|
|
50
|
+
// Tiers are per-agent presets (see `agents[kind].tiers` above) — a tier id
|
|
51
|
+
// picked for the PREVIOUS agent (e.g. cursor's "AVG" = Grok 4.5) doesn't
|
|
52
|
+
// necessarily exist for the newly selected one (pi has no tiers at all), so
|
|
53
|
+
// switching agentKind must re-resolve modelTier instead of leaving it
|
|
54
|
+
// pointing at a tier the UI can no longer show a matching label for.
|
|
55
|
+
watch(agentKind, kind => {
|
|
56
|
+
const tiers = agents[kind]?.tiers ?? {}
|
|
57
|
+
modelTier.value = defaultTier in tiers ? defaultTier : (Object.keys(tiers)[0] ?? '')
|
|
58
|
+
})
|
|
59
|
+
|
|
50
60
|
/**
|
|
51
61
|
* Read the per-machine default agent (`ACP_DEFAULT_AGENT`) and start the
|
|
52
62
|
* domain MCP bridge. Call once before the first `request()` — mirrors
|