@7n/tauri-components 0.2.0 → 0.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@7n/tauri-components",
3
- "version": "0.2.0",
3
+ "version": "0.4.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",
@@ -16,10 +16,7 @@
16
16
 
17
17
  <div v-for="rec in records" :key="rec.id" class="audit-row">
18
18
  <div @click="toggle(rec.id)" class="audit-head">
19
- <span class="state-pill" :style="{ '--c': statusColor(rec.status) }">
20
- <span class="state-pill__dot" />
21
- {{ rec.status }}
22
- </span>
19
+ <StatePill :status="rec.status" />
23
20
  <span class="audit-actor">{{ rec.actor?.kind }}{{ rec.actor?.id ? `:${rec.actor.id}` : '' }}</span>
24
21
  <span class="audit-intent">{{ rec.intent }}</span>
25
22
  <q-space />
@@ -54,17 +51,7 @@ import { ref } from 'vue'
54
51
  import { useQuasar } from 'quasar'
55
52
  import BaseDialog from './BaseDialog.vue'
56
53
  import RequestView from './RequestView.vue'
57
-
58
- const STATUS_COLOR = {
59
- pending: '#8e8e93',
60
- running: '#0a84ff',
61
- done: '#30d158',
62
- partial: '#ff9f0a',
63
- needs_clarification: '#64d2ff',
64
- needs_approval: '#ff9f0a',
65
- failed: '#ff453a',
66
- rejected: '#8e8e93',
67
- }
54
+ import StatePill from './StatePill.vue'
68
55
 
69
56
  // The agent gateway (journal + respond + approve) is injected by the host app,
70
57
  // keeping this dialog domain-free.
@@ -82,14 +69,6 @@ const loading = ref(false)
82
69
  const expandedId = ref(null)
83
70
  const busyId = ref(null)
84
71
 
85
- /**
86
- * @param {string} status request status
87
- * @returns {string} accent color
88
- */
89
- function statusColor(status) {
90
- return STATUS_COLOR[status] ?? '#8e8e93'
91
- }
92
-
93
72
  /**
94
73
  * @param {number} millis epoch millis
95
74
  * @returns {string} locale time
@@ -234,26 +213,4 @@ async function onApprove(rec, ok) {
234
213
  .audit-body {
235
214
  padding: 6px 4px 12px;
236
215
  }
237
-
238
- .state-pill {
239
- display: inline-flex;
240
- align-items: center;
241
- gap: 5px;
242
- height: 20px;
243
- padding: 0 8px;
244
- border-radius: 6px;
245
- font-family: 'SF Mono', ui-monospace, 'JetBrains Mono', monospace;
246
- font-size: 11px;
247
- color: var(--c);
248
- background: color-mix(in srgb, var(--c) 14%, transparent);
249
- border: 1px solid color-mix(in srgb, var(--c) 28%, transparent);
250
- flex: 0 0 auto;
251
- }
252
-
253
- .state-pill__dot {
254
- width: 6px;
255
- height: 6px;
256
- border-radius: 50%;
257
- background: var(--c);
258
- }
259
216
  </style>
@@ -1,9 +1,6 @@
1
1
  <template>
2
2
  <div class="req-view">
3
- <span class="state-pill" :style="{ '--c': statusColor }">
4
- <span class="state-pill__dot" />
5
- {{ result.status }}
6
- </span>
3
+ <StatePill :status="result.status" />
7
4
 
8
5
  <div v-if="result.summary" class="req-summary">{{ result.summary }}</div>
9
6
  <div v-if="result.question" class="req-summary">{{ result.question }}</div>
@@ -23,24 +20,11 @@
23
20
  </template>
24
21
 
25
22
  <script setup>
26
- import { computed } from 'vue'
23
+ import StatePill from './StatePill.vue'
27
24
 
28
- const STATUS_COLOR = {
29
- pending: '#8e8e93',
30
- running: '#0a84ff',
31
- done: '#30d158',
32
- partial: '#ff9f0a',
33
- needs_clarification: '#64d2ff',
34
- needs_approval: '#ff9f0a',
35
- failed: '#ff453a',
36
- rejected: '#8e8e93',
37
- }
38
-
39
- const props = defineProps({
25
+ defineProps({
40
26
  result: { type: Object, required: true },
41
27
  })
42
-
43
- const statusColor = computed(() => STATUS_COLOR[props.result.status] ?? '#8e8e93')
44
28
  </script>
45
29
 
46
30
  <style scoped>
@@ -76,26 +60,4 @@ const statusColor = computed(() => STATUS_COLOR[props.result.status] ?? '#8e8e93
76
60
  opacity: 0.8;
77
61
  overflow-wrap: anywhere;
78
62
  }
79
-
80
- .state-pill {
81
- display: inline-flex;
82
- align-items: center;
83
- gap: 5px;
84
- align-self: flex-start;
85
- height: 20px;
86
- padding: 0 8px;
87
- border-radius: 6px;
88
- font-family: 'SF Mono', ui-monospace, 'JetBrains Mono', monospace;
89
- font-size: 11px;
90
- color: var(--c);
91
- background: color-mix(in srgb, var(--c) 14%, transparent);
92
- border: 1px solid color-mix(in srgb, var(--c) 28%, transparent);
93
- }
94
-
95
- .state-pill__dot {
96
- width: 6px;
97
- height: 6px;
98
- border-radius: 50%;
99
- background: var(--c);
100
- }
101
63
  </style>
@@ -0,0 +1,41 @@
1
+ <template>
2
+ <span class="state-pill" :style="{ '--c': statusColor(status) }">
3
+ <span class="state-pill__dot" />
4
+ {{ status }}
5
+ </span>
6
+ </template>
7
+
8
+ <script setup>
9
+ // The colored status chip used by RequestView and AuditDialog. Owns the pill
10
+ // markup + styles in one place (the color map lives in status.js).
11
+ import { statusColor } from './status.js'
12
+
13
+ defineProps({
14
+ status: { type: String, required: true },
15
+ })
16
+ </script>
17
+
18
+ <style scoped>
19
+ .state-pill {
20
+ display: inline-flex;
21
+ align-items: center;
22
+ gap: 5px;
23
+ align-self: flex-start;
24
+ flex: 0 0 auto;
25
+ height: 20px;
26
+ padding: 0 8px;
27
+ border-radius: 6px;
28
+ font-family: 'SF Mono', ui-monospace, 'JetBrains Mono', monospace;
29
+ font-size: 11px;
30
+ color: var(--c);
31
+ background: color-mix(in srgb, var(--c) 14%, transparent);
32
+ border: 1px solid color-mix(in srgb, var(--c) 28%, transparent);
33
+ }
34
+
35
+ .state-pill__dot {
36
+ width: 6px;
37
+ height: 6px;
38
+ border-radius: 50%;
39
+ background: var(--c);
40
+ }
41
+ </style>
@@ -8,3 +8,5 @@ export { default as AuditDialog } from './AuditDialog.vue'
8
8
  export { default as BaseDialog } from './BaseDialog.vue'
9
9
  export { default as DialogActions } from './DialogActions.vue'
10
10
  export { default as RequestView } from './RequestView.vue'
11
+ export { default as StatePill } from './StatePill.vue'
12
+ export { STATUS_COLOR, statusColor } from './status.js'
@@ -0,0 +1,23 @@
1
+ // Single source of truth for request-status accent colors, shared by the
2
+ // components that render a status pill (StatePill, and any custom UI).
3
+
4
+ export const STATUS_COLOR = {
5
+ pending: '#8e8e93',
6
+ running: '#0a84ff',
7
+ done: '#30d158',
8
+ partial: '#ff9f0a',
9
+ needs_clarification: '#64d2ff',
10
+ needs_approval: '#ff9f0a',
11
+ failed: '#ff453a',
12
+ rejected: '#8e8e93',
13
+ }
14
+
15
+ const FALLBACK = '#8e8e93'
16
+
17
+ /**
18
+ * @param {string} status request status
19
+ * @returns {string} accent color (fallback grey for unknown statuses)
20
+ */
21
+ export function statusColor(status) {
22
+ return STATUS_COLOR[status] ?? FALLBACK
23
+ }
@@ -44,7 +44,11 @@ export function createDispatch(catalog, transport) {
44
44
  return { ok: true, output }
45
45
  }
46
46
  catch (error) {
47
- return { ok: false, error: { code: 'io', message: String(error?.message ?? error) } }
47
+ const envelope = { code: 'io', message: String(error?.message ?? error) }
48
+ // Preserve a backend-provided error kind (e.g. a typed Tauri command error)
49
+ // so callers can branch on it — e.g. re-auth on a 'ReauthRequired' kind.
50
+ if (error?.kind !== undefined) envelope.kind = error.kind
51
+ return { ok: false, error: envelope }
48
52
  }
49
53
  }
50
54
  }
@@ -23,12 +23,13 @@ const DEFAULT_ACTOR = { kind: 'human', id: 'local' }
23
23
  * @param {Record<string, number>} [config.actorTiers] tier overrides
24
24
  * @param {{ kind: string, id: string }} [config.actor] caller identity (default human:local)
25
25
  * @param {{ storagePrefix?: string, defaultBaseUrl?: string, defaultModel?: string }} [config.omlx] omlx config options
26
+ * @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)
26
27
  * @returns {object} in-app agent gateway
27
28
  */
28
- export function useAgent({ catalog, systemPrompt, grounding, actorTiers, actor = DEFAULT_ACTOR, omlx } = {}) {
29
+ export function useAgent({ catalog, systemPrompt, grounding, actorTiers, actor = DEFAULT_ACTOR, omlx, transport = tauriTransport } = {}) {
29
30
  const { baseUrl, model, apiKey, save, loadEnv } = useOmlx(omlx)
30
31
  const journal = createTauriJournalStore()
31
- const kit = createAgentKit({ catalog, systemPrompt, transport: tauriTransport, journal, actorTiers, grounding })
32
+ const kit = createAgentKit({ catalog, systemPrompt, transport, journal, actorTiers, grounding })
32
33
 
33
34
  /**
34
35
  * Build an omlx chat fn from the current config (tauri-http transport).