@happyvertical/smrt-chat 0.51.5 → 0.51.6

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 (47) hide show
  1. package/AGENTS.md +19 -0
  2. package/dist/index.js +1 -1
  3. package/dist/manifest.json +1 -1
  4. package/dist/smrt-knowledge.json +5 -5
  5. package/dist/svelte/components/agent/ToolCallDisplay.svelte +103 -7
  6. package/dist/svelte/components/agent/ToolCallDisplay.svelte.d.ts +18 -0
  7. package/dist/svelte/components/agent/ToolCallDisplay.svelte.d.ts.map +1 -1
  8. package/dist/svelte/components/agent/__tests__/ToolCallDisplay.test.js +100 -9
  9. package/dist/svelte/components/assistant/AssistantComposer.svelte +354 -0
  10. package/dist/svelte/components/assistant/AssistantComposer.svelte.d.ts +20 -0
  11. package/dist/svelte/components/assistant/AssistantComposer.svelte.d.ts.map +1 -0
  12. package/dist/svelte/components/assistant/AssistantDock.svelte +534 -0
  13. package/dist/svelte/components/assistant/AssistantDock.svelte.d.ts +30 -0
  14. package/dist/svelte/components/assistant/AssistantDock.svelte.d.ts.map +1 -0
  15. package/dist/svelte/components/assistant/AssistantThreadList.svelte +136 -0
  16. package/dist/svelte/components/assistant/AssistantThreadList.svelte.d.ts +15 -0
  17. package/dist/svelte/components/assistant/AssistantThreadList.svelte.d.ts.map +1 -0
  18. package/dist/svelte/components/assistant/__tests__/AssistantComposer.test.js +75 -0
  19. package/dist/svelte/components/assistant/__tests__/AssistantDock.test.js +395 -0
  20. package/dist/svelte/components/assistant/__tests__/AssistantThreadList.test.js +45 -0
  21. package/dist/svelte/components/assistant/__tests__/action-status.test.js +25 -0
  22. package/dist/svelte/components/assistant/__tests__/assistant-transport.test.js +253 -0
  23. package/dist/svelte/components/assistant/__tests__/attachment-href.test.js +31 -0
  24. package/dist/svelte/components/assistant/__tests__/create-assistant-dock-controller.test.js +2492 -0
  25. package/dist/svelte/components/assistant/action-status.d.ts +14 -0
  26. package/dist/svelte/components/assistant/action-status.d.ts.map +1 -0
  27. package/dist/svelte/components/assistant/action-status.js +7 -0
  28. package/dist/svelte/components/assistant/assistant-transport.d.ts +239 -0
  29. package/dist/svelte/components/assistant/assistant-transport.d.ts.map +1 -0
  30. package/dist/svelte/components/assistant/assistant-transport.js +306 -0
  31. package/dist/svelte/components/assistant/attachment-href.d.ts +23 -0
  32. package/dist/svelte/components/assistant/attachment-href.d.ts.map +1 -0
  33. package/dist/svelte/components/assistant/attachment-href.js +36 -0
  34. package/dist/svelte/components/assistant/create-assistant-dock-controller.svelte.d.ts +172 -0
  35. package/dist/svelte/components/assistant/create-assistant-dock-controller.svelte.d.ts.map +1 -0
  36. package/dist/svelte/components/assistant/create-assistant-dock-controller.svelte.js +0 -0
  37. package/dist/svelte/components/shared/ModelPicker.svelte +84 -0
  38. package/dist/svelte/components/shared/ModelPicker.svelte.d.ts +26 -0
  39. package/dist/svelte/components/shared/ModelPicker.svelte.d.ts.map +1 -0
  40. package/dist/svelte/components/shared/__tests__/ModelPicker.test.js +36 -0
  41. package/dist/svelte/i18n.d.ts +21 -0
  42. package/dist/svelte/i18n.d.ts.map +1 -1
  43. package/dist/svelte/i18n.js +25 -0
  44. package/dist/svelte/index.d.ts +7 -0
  45. package/dist/svelte/index.d.ts.map +1 -1
  46. package/dist/svelte/index.js +12 -0
  47. package/package.json +11 -11
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Headless AssistantDock state (#2904).
3
+ *
4
+ * Composes: route-scoped `DataSurfaceDescriptor` discovery from a
5
+ * `DataSurfaceRegistry` (`@happyvertical/smrt-ui/data-surface`), an
6
+ * `AssistantTransport` (`./assistant-transport.js`) for thread/message I/O,
7
+ * and an `AssistantActionClient` for action preview/apply.
8
+ *
9
+ * Action preview/apply is NOT routed through `DataSurfaceCommandBridge`
10
+ * (`../../../data-surface-bridge.js`) — that bridge is the live-collaboration
11
+ * query/select command channel (see its own tests in
12
+ * `data-surface-conformance.integration.svelte.test.ts` around `ackBridge`).
13
+ * The actual action pathway is `DataSurfaceActionAdapter.preview()`/`.apply()`
14
+ * (`@happyvertical/smrt-agents/server`, exercised directly in
15
+ * `packages/smrt-svelte/src/web/__tests__/data-surface-conformance.integration.svelte.test.ts:1221-1441`).
16
+ * That adapter is server-only (it needs a `DataSurfaceExecutionContext` with a
17
+ * principal/tenant the browser cannot self-assert). `AssistantActionClient` is
18
+ * the client-side seam a host application implements to reach it — typically
19
+ * an authenticated HTTP call to a server route that wraps the adapter. Tests
20
+ * use an in-process implementation that calls the real adapter directly with
21
+ * a fixed context, the same shape the conformance exemplar uses.
22
+ *
23
+ * Polling and stale-send recovery follow the pattern in anytown's
24
+ * `PortalChatTool.svelte` (read in full for #2904 phase 2):
25
+ * - `clientRequestId` is generated once per distinct (threadId, content) draft
26
+ * and reused on retry until the send resolves or errors — mirrors
27
+ * `clientRequestIdForDraft`/`clearPendingRequest`,
28
+ * `PortalChatTool.svelte:304-322`.
29
+ * - A still-processing send (`inProgress: true`, mirrors
30
+ * `payload.inProgress`, `PortalChatTool.svelte:391`) schedules a poll of
31
+ * `loadMessages` rather than blocking — mirrors `scheduleThreadPoll`,
32
+ * `PortalChatTool.svelte:339-353` (there: fixed 8 attempts / 1500ms). This
33
+ * controller generalizes that into a configurable interval plus an
34
+ * absolute staleness timeout (default 90s) after which the pending send is
35
+ * marked `'stale'` and the composer can offer "retry", reusing the same
36
+ * `clientRequestId` so the transport dedups it (`assistant-transport.ts`
37
+ * `createInMemoryAssistantTransport.sendMessage`).
38
+ */
39
+ import { type DataSurfaceActionRequest, type DataSurfaceActionResult, type DataSurfaceIdentity, type DataSurfaceRegistry } from '@happyvertical/smrt-ui/data-surface';
40
+ import type { AssistantAttachmentRef, AssistantMessage, AssistantThreadSummary, AssistantTransport, ModelOption } from './assistant-transport.js';
41
+ export type AssistantPendingSendStatus = 'sending' | 'processing' | 'stale' | 'failed';
42
+ export interface AssistantPendingSend {
43
+ clientRequestId: string;
44
+ threadId: string;
45
+ content: string;
46
+ status: AssistantPendingSendStatus;
47
+ sentAt: number;
48
+ attachments?: AssistantAttachmentRef[];
49
+ }
50
+ /** Client-side seam to a server-hosted `DataSurfaceActionAdapter`. */
51
+ export interface AssistantActionClient {
52
+ preview(request: DataSurfaceActionRequest): Promise<DataSurfaceActionResult>;
53
+ /** `idempotencyKey` is distinct from the send transport's `clientRequestId`
54
+ * (binding decision #2904) and maps to
55
+ * `DataSurfaceActionWireRequest.idempotencyKey`
56
+ * (`packages/types/src/data-surface.ts:274`), which the host's actionClient
57
+ * implementation attaches when calling the server-side adapter. */
58
+ apply(request: DataSurfaceActionRequest, idempotencyKey: string): Promise<DataSurfaceActionResult>;
59
+ }
60
+ export interface AssistantActionState {
61
+ request: DataSurfaceActionRequest;
62
+ previewResult?: DataSurfaceActionResult;
63
+ applyResult?: DataSurfaceActionResult;
64
+ status: 'previewing' | 'previewed' | 'applying' | 'applied' | 'failed';
65
+ error?: string;
66
+ /** Minted once when the preview is created and reused for every apply
67
+ * attempt on this proposed action (including retries after a failure), so
68
+ * a retried Confirm click after a timeout where the server DID apply
69
+ * dedups against that earlier attempt instead of re-executing. */
70
+ idempotencyKey: string;
71
+ /** Cycle-4 final finding 2: true only when a genuine APPLY attempt itself
72
+ * failed (the apply-time mount re-check, `actionClient.apply` throwing, or
73
+ * resolving `{ ok: false }`) — never for a preview-phase failure. This is
74
+ * the ONLY thing `applyAction`'s guard consults to permit a retry on a
75
+ * `'failed'` entry; deriving retry eligibility from `status === 'failed'`
76
+ * plus a mutated `request.phase` (the earlier approach) let a refusal for
77
+ * an already-terminal state (e.g. `'applied'`) itself manufacture this
78
+ * condition by downgrading the entry to `'failed'`, permitting a SECOND
79
+ * `applyAction` call to replay an already-applied action. Cleared
80
+ * (`false`) whenever an apply attempt succeeds. */
81
+ retryable?: boolean;
82
+ }
83
+ export interface AssistantDockControllerOptions {
84
+ transport: AssistantTransport;
85
+ registry: DataSurfaceRegistry;
86
+ /** Explicit surface narrowing filter (design decision #2904: `AssistantDock`
87
+ * accepts `registry` plus an optional `surfaces` override rather than only
88
+ * ever trusting live discovery). When set, only identities present in
89
+ * BOTH this list and `registry.list()` are ever mounted (Copilot PR #2919
90
+ * jAwr0) — an override entry that isn't genuinely registered is never
91
+ * treated as mounted. */
92
+ surfaces?: DataSurfaceIdentity[];
93
+ actionClient?: AssistantActionClient;
94
+ now?: () => number;
95
+ createClientRequestId?: () => string;
96
+ /** Generator for the per-action idempotency key minted at preview time;
97
+ * defaults to `crypto.randomUUID()`. */
98
+ createIdempotencyKey?: () => string;
99
+ /** Poll cadence while a send is in flight. Default 3000ms. */
100
+ activePollIntervalMs?: number;
101
+ /** Poll cadence while idle (thread open, no send in flight). Default 15000ms. */
102
+ idlePollIntervalMs?: number;
103
+ /** Absolute age after which a pending send is marked stale. Default 90000ms. */
104
+ staleAfterMs?: number;
105
+ /** Whether the dock is currently visible; polling pauses when false. */
106
+ visible?: () => boolean;
107
+ }
108
+ export interface AssistantDockController {
109
+ readonly threads: AssistantThreadSummary[];
110
+ readonly activeThreadId: string | null;
111
+ readonly messages: AssistantMessage[];
112
+ readonly pendingSends: AssistantPendingSend[];
113
+ readonly surfaces: DataSurfaceIdentity[];
114
+ readonly actions: Map<string, AssistantActionState>;
115
+ readonly models: ModelOption[];
116
+ readonly selectedModel: string | undefined;
117
+ /** A background failure (e.g. a failed `loadThreads`/`loadModels` call the
118
+ * mount effect couldn't surface any other way) for the dock to render
119
+ * (#2904 review finding 4). `null` when nothing is wrong. Set via
120
+ * `setError`; a host or the dock's own `handleSend` can also report a
121
+ * failure here. */
122
+ readonly error: string | null;
123
+ /** Records (or clears, with `null`) a background failure for `error` to
124
+ * report. Distinct from a failed `AssistantPendingSend`/`AssistantActionState`,
125
+ * which already carry their own `error` field — this is for failures with
126
+ * no narrower place to live (a failed `loadThreads`/`loadModels`, or a
127
+ * `send()` rejection AssistantDock's `handleSend` wants surfaced at the
128
+ * dock level in addition to the pending send's own `'failed'` status). */
129
+ setError(message: string | null): void;
130
+ loadThreads(): Promise<void>;
131
+ loadModels(): Promise<void>;
132
+ setSelectedModel(modelId: string | undefined): void;
133
+ openThread(threadId: string): Promise<void>;
134
+ createThread(title: string): Promise<AssistantThreadSummary>;
135
+ send(content: string, attachments?: AssistantAttachmentRef[]): Promise<void>;
136
+ retry(clientRequestId: string): Promise<void>;
137
+ previewAction(request: DataSurfaceActionRequest): Promise<void>;
138
+ /** Applies the action using the idempotency key minted at preview time
139
+ * (`AssistantActionState.idempotencyKey`) — never a fresh key per call. */
140
+ applyAction(requestId: string): Promise<void>;
141
+ rejectAction(requestId: string): void;
142
+ startPolling(): void;
143
+ stopPolling(): void;
144
+ /** Re-checks whether the host has reassigned the `registry` prop to a
145
+ * different instance and, if so, re-subscribes, resyncs `surfaces`
146
+ * (#2904 review finding B), and clears/reloads conversation state
147
+ * (threads, activeThreadId, messages, pendingSends, actions, error,
148
+ * draftIds — Copilot PR #2919 jAwsd). A no-op when unchanged. Call from a
149
+ * `registry`-scoped effect, never from the mount effect (see
150
+ * AssistantDock.svelte — F1 requires that one to run exactly once). */
151
+ syncRegistry(): void;
152
+ /** Re-reads the `surfaces` override getter (and falls back to the live
153
+ * registry contents when unset) and invalidates outstanding previews for
154
+ * any surface that fell out of scope on a narrowing change (#2904 review,
155
+ * cycle-2 second final finding 1). A no-op when the effective set is
156
+ * unchanged. Call from a `surfaces`-scoped effect, never from the mount
157
+ * effect (see AssistantDock.svelte — F1 requires that one to run exactly
158
+ * once). */
159
+ syncSurfaces(): void;
160
+ /** Re-checks whether the host has reassigned the `transport` prop to a
161
+ * different instance and, if so, clears conversation state (threads,
162
+ * activeThreadId, messages, pendingSends, actions, error, draftIds) and
163
+ * reloads threads/models from the new transport (Copilot PR #2919 jAwsd —
164
+ * mirrors `syncRegistry()`'s reset for the identical class of stale-context
165
+ * bug). A no-op when unchanged. Call from a `transport`-scoped effect,
166
+ * never from the mount effect (see AssistantDock.svelte — F1 requires that
167
+ * one to run exactly once). */
168
+ syncTransport(): void;
169
+ dispose(): void;
170
+ }
171
+ export declare function createAssistantDockController(options: AssistantDockControllerOptions): AssistantDockController;
172
+ //# sourceMappingURL=create-assistant-dock-controller.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-assistant-dock-controller.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/assistant/create-assistant-dock-controller.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EAEzB,MAAM,qCAAqC,CAAC;AAE7C,OAAO,KAAK,EACV,sBAAsB,EACtB,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAElC,MAAM,MAAM,0BAA0B,GAClC,SAAS,GACT,YAAY,GACZ,OAAO,GACP,QAAQ,CAAC;AAEb,MAAM,WAAW,oBAAoB;IACnC,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,0BAA0B,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,sBAAsB,EAAE,CAAC;CACxC;AAED,sEAAsE;AACtE,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC7E;;;;uEAImE;IACnE,KAAK,CACH,OAAO,EAAE,wBAAwB,EACjC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,uBAAuB,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,wBAAwB,CAAC;IAClC,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC,WAAW,CAAC,EAAE,uBAAuB,CAAC;IACtC,MAAM,EAAE,YAAY,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;sEAGkE;IAClE,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;;;;;uDASmD;IACnD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,8BAA8B;IAC7C,SAAS,EAAE,kBAAkB,CAAC;IAC9B,QAAQ,EAAE,mBAAmB,CAAC;IAC9B;;;;;6BAKyB;IACzB,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACjC,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,qBAAqB,CAAC,EAAE,MAAM,MAAM,CAAC;IACrC;4CACwC;IACxC,oBAAoB,CAAC,EAAE,MAAM,MAAM,CAAC;IACpC,8DAA8D;IAC9D,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,sBAAsB,EAAE,CAAC;IAC3C,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,oBAAoB,EAAE,CAAC;IAC9C,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IACpD,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C;;;;uBAImB;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;;8EAK0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IACvC,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACpD,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC7D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,sBAAsB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,KAAK,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,aAAa,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE;+EAC2E;IAC3E,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,YAAY,IAAI,IAAI,CAAC;IACrB,WAAW,IAAI,IAAI,CAAC;IACpB;;;;;;2EAMuE;IACvE,YAAY,IAAI,IAAI,CAAC;IACrB;;;;;;gBAMY;IACZ,YAAY,IAAI,IAAI,CAAC;IACrB;;;;;;;mCAO+B;IAC/B,aAAa,IAAI,IAAI,CAAC;IACtB,OAAO,IAAI,IAAI,CAAC;CACjB;AA0BD,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,8BAA8B,GACtC,uBAAuB,CAyhCzB"}
@@ -0,0 +1,84 @@
1
+ <script lang="ts">
2
+ /**
3
+ * ModelPicker - AI model selector
4
+ *
5
+ * Extracted from `@happyvertical/smrt-content`'s `ContentAgentChat.svelte`
6
+ * (its `AI_MODELS` constant + `availableAIModels`/`allowedModelIds` filtering,
7
+ * `packages/content/src/svelte/components/ContentAgentChat.svelte:28-121`) for
8
+ * reuse by AssistantDock (#2904). `ContentAgentChat` itself is NOT migrated to
9
+ * this component in this change — that is a separate, behavior-preserving
10
+ * follow-up (docs/assistant-dock.md "Gaps").
11
+ */
12
+ import { Select } from '@happyvertical/smrt-ui/forms';
13
+ import { useI18n } from '@happyvertical/smrt-ui/i18n';
14
+ import { M } from '../../i18n.js';
15
+
16
+ export interface ModelOption {
17
+ id: string;
18
+ label: string;
19
+ }
20
+
21
+ export const DEFAULT_MODEL_OPTIONS: ModelOption[] = [
22
+ { id: 'gemini-2.5-pro', label: 'Gemini 2.5 Pro' },
23
+ { id: 'gemini-2.5-flash', label: 'Gemini 2.5 Flash' },
24
+ { id: 'claude-3-5-sonnet-latest', label: 'Claude 3.5 Sonnet' },
25
+ { id: 'claude-3-5-haiku-latest', label: 'Claude 3.5 Haiku' },
26
+ { id: 'gpt-4o', label: 'GPT-4o' },
27
+ { id: 'gpt-4o-mini', label: 'GPT-4o Mini' },
28
+ ];
29
+
30
+ export interface Props {
31
+ /** Full candidate model catalog; defaults to `DEFAULT_MODEL_OPTIONS`. */
32
+ models?: ModelOption[];
33
+ /** Allow-list of model ids; empty/omitted means all `models` are offered. */
34
+ allowedModelIds?: string[];
35
+ /** The selected model id; bindable. */
36
+ value: string;
37
+ /** Fired with the newly selected model id. */
38
+ onchange?: (modelId: string) => void;
39
+ /** Accessible name for the underlying `<select>` (#2904 review, cycle-3
40
+ * second final F2 — the control previously had no aria-label, id, or
41
+ * wrapping `FormGroup`, so axe/screen readers saw an unnamed combobox).
42
+ * Defaults to an i18n'd "Model" label; override when a host embeds this
43
+ * picker somewhere the generic default isn't descriptive enough. */
44
+ ariaLabel?: string;
45
+ }
46
+
47
+ let {
48
+ models = DEFAULT_MODEL_OPTIONS,
49
+ allowedModelIds = [],
50
+ value = $bindable(),
51
+ onchange,
52
+ ariaLabel,
53
+ }: Props = $props();
54
+
55
+ const { t } = useI18n();
56
+
57
+ const availableModels = $derived(
58
+ allowedModelIds.length > 0
59
+ ? [
60
+ ...models.filter((model) => allowedModelIds.includes(model.id)),
61
+ ...allowedModelIds
62
+ .filter((id) => !models.some((model) => model.id === id))
63
+ .map((id) => ({ id, label: id })),
64
+ ]
65
+ : models,
66
+ );
67
+
68
+ function handleChange(event: Event) {
69
+ const next = (event.target as HTMLSelectElement).value;
70
+ value = next;
71
+ onchange?.(next);
72
+ }
73
+ </script>
74
+
75
+ <Select
76
+ class="smrt-select model-picker-select"
77
+ bind:value
78
+ onchange={handleChange}
79
+ aria-label={ariaLabel ?? t(M['chat.model_picker.label'])}
80
+ >
81
+ {#each availableModels as model (model.id)}
82
+ <option value={model.id}>{model.label}</option>
83
+ {/each}
84
+ </Select>
@@ -0,0 +1,26 @@
1
+ export interface ModelOption {
2
+ id: string;
3
+ label: string;
4
+ }
5
+ export interface Props {
6
+ /** Full candidate model catalog; defaults to `DEFAULT_MODEL_OPTIONS`. */
7
+ models?: ModelOption[];
8
+ /** Allow-list of model ids; empty/omitted means all `models` are offered. */
9
+ allowedModelIds?: string[];
10
+ /** The selected model id; bindable. */
11
+ value: string;
12
+ /** Fired with the newly selected model id. */
13
+ onchange?: (modelId: string) => void;
14
+ /** Accessible name for the underlying `<select>` (#2904 review, cycle-3
15
+ * second final F2 — the control previously had no aria-label, id, or
16
+ * wrapping `FormGroup`, so axe/screen readers saw an unnamed combobox).
17
+ * Defaults to an i18n'd "Model" label; override when a host embeds this
18
+ * picker somewhere the generic default isn't descriptive enough. */
19
+ ariaLabel?: string;
20
+ }
21
+ declare const ModelPicker: import("svelte").Component<Props, {
22
+ DEFAULT_MODEL_OPTIONS: ModelOption[];
23
+ }, "value">;
24
+ type ModelPicker = ReturnType<typeof ModelPicker>;
25
+ export default ModelPicker;
26
+ //# sourceMappingURL=ModelPicker.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelPicker.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/shared/ModelPicker.svelte.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,KAAK;IACpB,yEAAyE;IACzE,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IACvB,6EAA6E;IAC7E,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;;;;wEAIoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsDD,QAAA,MAAM,WAAW;2BAD8G,WAAW,EAAE;WACnF,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -0,0 +1,36 @@
1
+ // @vitest-environment jsdom
2
+ /**
3
+ * Component-level coverage for ModelPicker (#2904 review, cycle-3 second
4
+ * final F2 — the underlying `<select>` had no accessible name, no test in
5
+ * this suite ever supplied `models` to any component, and this file had no
6
+ * test at all).
7
+ */
8
+ import { expectNoA11yViolations, render, screen, userEvent, } from '@happyvertical/smrt-vitest/svelte';
9
+ import { describe, expect, it, vi } from 'vitest';
10
+ import ModelPicker, {} from '../ModelPicker.svelte';
11
+ const models = [
12
+ { id: 'model-a', label: 'Model A' },
13
+ { id: 'model-b', label: 'Model B' },
14
+ ];
15
+ describe('ModelPicker', () => {
16
+ it('has an accessible name by default and lets the user pick a model', async () => {
17
+ const onchange = vi.fn();
18
+ render(ModelPicker, { props: { models, value: 'model-a', onchange } });
19
+ const select = screen.getByLabelText('Model');
20
+ expect(select).toBeInTheDocument();
21
+ await userEvent.selectOptions(select, 'model-b');
22
+ expect(onchange).toHaveBeenCalledWith('model-b');
23
+ });
24
+ it('accepts an override accessible name via ariaLabel', () => {
25
+ render(ModelPicker, {
26
+ props: { models, value: 'model-a', ariaLabel: 'Reply model' },
27
+ });
28
+ expect(screen.getByLabelText('Reply model')).toBeInTheDocument();
29
+ });
30
+ it('is axe-clean', async () => {
31
+ const { container } = render(ModelPicker, {
32
+ props: { models, value: 'model-a' },
33
+ });
34
+ await expectNoA11yViolations(container);
35
+ });
36
+ });
@@ -18,6 +18,27 @@ export declare const M: {
18
18
  readonly 'chat.agent_session_panel.empty': "chat.agent_session_panel.empty";
19
19
  readonly 'chat.tool_call_display.tool_call': "chat.tool_call_display.tool_call";
20
20
  readonly 'chat.tool_call_display.running': "chat.tool_call_display.running";
21
+ readonly 'chat.tool_call_display.applied_successfully': "chat.tool_call_display.applied_successfully";
22
+ readonly 'chat.tool_call_display.confirm': "chat.tool_call_display.confirm";
23
+ readonly 'chat.tool_call_display.reject': "chat.tool_call_display.reject";
24
+ readonly 'chat.model_picker.label': "chat.model_picker.label";
25
+ readonly 'chat.assistant_composer.attach_files': "chat.assistant_composer.attach_files";
26
+ readonly 'chat.assistant_composer.message_label': "chat.assistant_composer.message_label";
27
+ readonly 'chat.assistant_composer.send': "chat.assistant_composer.send";
28
+ readonly 'chat.assistant_composer.remove_attachment': "chat.assistant_composer.remove_attachment";
29
+ readonly 'chat.assistant_composer.send_error': "chat.assistant_composer.send_error";
30
+ readonly 'chat.assistant_composer.send_failed': "chat.assistant_composer.send_failed";
31
+ readonly 'chat.assistant_composer.upload_error': "chat.assistant_composer.upload_error";
32
+ readonly 'chat.assistant_composer.upload_failed': "chat.assistant_composer.upload_failed";
33
+ readonly 'chat.assistant_thread_list.conversations_label': "chat.assistant_thread_list.conversations_label";
34
+ readonly 'chat.assistant_thread_list.new_conversation': "chat.assistant_thread_list.new_conversation";
35
+ readonly 'chat.assistant_thread_list.untitled': "chat.assistant_thread_list.untitled";
36
+ readonly 'chat.assistant_dock.no_surfaces': "chat.assistant_dock.no_surfaces";
37
+ readonly 'chat.assistant_dock.taking_longer': "chat.assistant_dock.taking_longer";
38
+ readonly 'chat.assistant_dock.retry': "chat.assistant_dock.retry";
39
+ readonly 'chat.assistant_dock.error': "chat.assistant_dock.error";
40
+ readonly 'chat.assistant_dock.send_failed': "chat.assistant_dock.send_failed";
41
+ readonly 'chat.assistant_dock.attachments': "chat.assistant_dock.attachments";
21
42
  readonly 'chat.room_create_dialog.close': "chat.room_create_dialog.close";
22
43
  readonly 'chat.room_create_dialog.title': "chat.room_create_dialog.title";
23
44
  readonly 'chat.room_create_dialog.room_name': "chat.room_create_dialog.room_name";
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqEZ,CAAC"}
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqGZ,CAAC"}
@@ -34,6 +34,31 @@ export const M = defineMessages({
34
34
  // ToolCallDisplay
35
35
  'chat.tool_call_display.tool_call': 'Tool call: {toolName}',
36
36
  'chat.tool_call_display.running': 'Running',
37
+ 'chat.tool_call_display.applied_successfully': 'Change applied successfully.',
38
+ 'chat.tool_call_display.confirm': 'Confirm',
39
+ 'chat.tool_call_display.reject': 'Reject',
40
+ // ModelPicker (#2904)
41
+ 'chat.model_picker.label': 'Model',
42
+ // AssistantComposer (#2904)
43
+ 'chat.assistant_composer.attach_files': 'Attach files',
44
+ 'chat.assistant_composer.message_label': 'Message',
45
+ 'chat.assistant_composer.send': 'Send',
46
+ 'chat.assistant_composer.remove_attachment': 'Remove {name}',
47
+ 'chat.assistant_composer.send_error': 'Could not send: {message}',
48
+ 'chat.assistant_composer.send_failed': 'Send failed',
49
+ 'chat.assistant_composer.upload_error': 'Could not attach file: {message}',
50
+ 'chat.assistant_composer.upload_failed': 'Attachment failed',
51
+ // AssistantThreadList (#2904)
52
+ 'chat.assistant_thread_list.conversations_label': 'Assistant conversations',
53
+ 'chat.assistant_thread_list.new_conversation': '+ New conversation',
54
+ 'chat.assistant_thread_list.untitled': 'Untitled',
55
+ // AssistantDock (#2904)
56
+ 'chat.assistant_dock.no_surfaces': 'No data surfaces are mounted on this route — the assistant can chat but has no actions available here.',
57
+ 'chat.assistant_dock.taking_longer': 'The assistant is taking longer than expected.',
58
+ 'chat.assistant_dock.retry': 'Retry "{content}"',
59
+ 'chat.assistant_dock.error': 'Something went wrong: {message}',
60
+ 'chat.assistant_dock.send_failed': 'A message failed to send. You can retry it below.',
61
+ 'chat.assistant_dock.attachments': 'Attachments',
37
62
  // RoomCreateDialog
38
63
  'chat.room_create_dialog.close': 'Close room creation dialog',
39
64
  'chat.room_create_dialog.title': 'Create a Room',
@@ -22,6 +22,11 @@ export { default as AgentChat } from './components/agent/AgentChat.svelte';
22
22
  export { default as AgentSelector } from './components/agent/AgentSelector.svelte';
23
23
  export { default as AgentSessionPanel } from './components/agent/AgentSessionPanel.svelte';
24
24
  export { default as ToolCallDisplay } from './components/agent/ToolCallDisplay.svelte';
25
+ export { default as AssistantComposer } from './components/assistant/AssistantComposer.svelte';
26
+ export { default as AssistantDock } from './components/assistant/AssistantDock.svelte';
27
+ export { default as AssistantThreadList } from './components/assistant/AssistantThreadList.svelte';
28
+ export { type AssistantAttachmentRef, type AssistantMessage, type AssistantSendMessageInput, type AssistantSendMessageResult, type AssistantThreadSummary, type AssistantTransport, createInMemoryAssistantTransport, createSmrtAssistantTransport, type InMemoryAssistantTransportOptions, type SmrtAssistantTransportOptions, } from './components/assistant/assistant-transport.js';
29
+ export { type AssistantActionClient, type AssistantActionState, type AssistantDockController, type AssistantDockControllerOptions, type AssistantPendingSend, type AssistantPendingSendStatus, createAssistantDockController, } from './components/assistant/create-assistant-dock-controller.svelte.js';
25
30
  export { default as RoomCreateDialog } from './components/dialogs/RoomCreateDialog.svelte';
26
31
  export { default as SearchMessages } from './components/dialogs/SearchMessages.svelte';
27
32
  export { default as ChatLayout } from './components/layout/ChatLayout.svelte';
@@ -36,6 +41,8 @@ export { default as Avatar } from './components/shared/Avatar.svelte';
36
41
  export { default as FileUpload } from './components/shared/FileUpload.svelte';
37
42
  export { default as LinkPreview } from './components/shared/LinkPreview.svelte';
38
43
  export { default as MentionAutocomplete } from './components/shared/MentionAutocomplete.svelte';
44
+ export type { ModelOption } from './components/shared/ModelPicker.svelte';
45
+ export { default as ModelPicker } from './components/shared/ModelPicker.svelte';
39
46
  export { default as ReactionPicker } from './components/shared/ReactionPicker.svelte';
40
47
  export { default as ReadReceipts } from './components/shared/ReadReceipts.svelte';
41
48
  export { default as UserPresence } from './components/shared/UserPresence.svelte';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAwCH,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,yCAAyC,CAAC;AACnF,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAC3F,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,2CAA2C,CAAC;AACvF,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,8CAA8C,CAAC;AAC3F,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,4CAA4C,CAAC;AAEvF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,2CAA2C,CAAC;AACpF,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAGxE,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,eAAe,EACf,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"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"}
@@ -25,6 +25,10 @@ import AgentChat from './components/agent/AgentChat.svelte';
25
25
  import AgentSelector from './components/agent/AgentSelector.svelte';
26
26
  import AgentSessionPanel from './components/agent/AgentSessionPanel.svelte';
27
27
  import ToolCallDisplay from './components/agent/ToolCallDisplay.svelte';
28
+ // Assistant dock components (#2904)
29
+ import AssistantComposer from './components/assistant/AssistantComposer.svelte';
30
+ import AssistantDock from './components/assistant/AssistantDock.svelte';
31
+ import AssistantThreadList from './components/assistant/AssistantThreadList.svelte';
28
32
  // Dialog components
29
33
  import RoomCreateDialog from './components/dialogs/RoomCreateDialog.svelte';
30
34
  import SearchMessages from './components/dialogs/SearchMessages.svelte';
@@ -43,6 +47,8 @@ import Avatar from './components/shared/Avatar.svelte';
43
47
  import FileUpload from './components/shared/FileUpload.svelte';
44
48
  import LinkPreview from './components/shared/LinkPreview.svelte';
45
49
  import MentionAutocomplete from './components/shared/MentionAutocomplete.svelte';
50
+ // Shared model picker
51
+ import ModelPicker from './components/shared/ModelPicker.svelte';
46
52
  import ReactionPicker from './components/shared/ReactionPicker.svelte';
47
53
  import ReadReceipts from './components/shared/ReadReceipts.svelte';
48
54
  import UserPresence from './components/shared/UserPresence.svelte';
@@ -59,6 +65,11 @@ export { default as AgentChat } from './components/agent/AgentChat.svelte';
59
65
  export { default as AgentSelector } from './components/agent/AgentSelector.svelte';
60
66
  export { default as AgentSessionPanel } from './components/agent/AgentSessionPanel.svelte';
61
67
  export { default as ToolCallDisplay } from './components/agent/ToolCallDisplay.svelte';
68
+ export { default as AssistantComposer } from './components/assistant/AssistantComposer.svelte';
69
+ export { default as AssistantDock } from './components/assistant/AssistantDock.svelte';
70
+ export { default as AssistantThreadList } from './components/assistant/AssistantThreadList.svelte';
71
+ export { createInMemoryAssistantTransport, createSmrtAssistantTransport, } from './components/assistant/assistant-transport.js';
72
+ export { createAssistantDockController, } from './components/assistant/create-assistant-dock-controller.svelte.js';
62
73
  export { default as RoomCreateDialog } from './components/dialogs/RoomCreateDialog.svelte';
63
74
  export { default as SearchMessages } from './components/dialogs/SearchMessages.svelte';
64
75
  // Export components
@@ -74,6 +85,7 @@ export { default as Avatar } from './components/shared/Avatar.svelte';
74
85
  export { default as FileUpload } from './components/shared/FileUpload.svelte';
75
86
  export { default as LinkPreview } from './components/shared/LinkPreview.svelte';
76
87
  export { default as MentionAutocomplete } from './components/shared/MentionAutocomplete.svelte';
88
+ export { default as ModelPicker } from './components/shared/ModelPicker.svelte';
77
89
  export { default as ReactionPicker } from './components/shared/ReactionPicker.svelte';
78
90
  export { default as ReadReceipts } from './components/shared/ReadReceipts.svelte';
79
91
  export { default as UserPresence } from './components/shared/UserPresence.svelte';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-chat",
3
- "version": "0.51.5",
3
+ "version": "0.51.6",
4
4
  "smrtJsdoc": "strict",
5
5
  "description": "Chat rooms, DMs, threads, and agent conversations for the SMRT framework",
6
6
  "type": "module",
@@ -70,13 +70,13 @@
70
70
  },
71
71
  "dependencies": {
72
72
  "@happyvertical/ai": "^0.89.11",
73
- "@happyvertical/smrt-agents": "0.51.5",
74
- "@happyvertical/smrt-core": "0.51.5",
75
- "@happyvertical/smrt-personas": "0.51.5",
76
- "@happyvertical/smrt-tenancy": "0.51.5",
77
- "@happyvertical/smrt-types": "0.51.5",
78
- "@happyvertical/smrt-ui": "0.51.5",
79
- "@happyvertical/smrt-users": "0.51.5",
73
+ "@happyvertical/smrt-agents": "0.51.6",
74
+ "@happyvertical/smrt-core": "0.51.6",
75
+ "@happyvertical/smrt-personas": "0.51.6",
76
+ "@happyvertical/smrt-tenancy": "0.51.6",
77
+ "@happyvertical/smrt-types": "0.51.6",
78
+ "@happyvertical/smrt-ui": "0.51.6",
79
+ "@happyvertical/smrt-users": "0.51.6",
80
80
  "@happyvertical/sql": "^0.89.11"
81
81
  },
82
82
  "peerDependencies": {
@@ -88,9 +88,9 @@
88
88
  }
89
89
  },
90
90
  "devDependencies": {
91
- "@happyvertical/smrt-playground": "0.51.5",
92
- "@happyvertical/smrt-profiles": "0.51.5",
93
- "@happyvertical/smrt-vitest": "0.51.5",
91
+ "@happyvertical/smrt-playground": "0.51.6",
92
+ "@happyvertical/smrt-profiles": "0.51.6",
93
+ "@happyvertical/smrt-vitest": "0.51.6",
94
94
  "@sveltejs/kit": "^2.69.1",
95
95
  "@sveltejs/package": "^2.5.8",
96
96
  "@sveltejs/vite-plugin-svelte": "^7.1.2",