@meshmakers/shared-ui 3.4.1490 → 3.5.10

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/README.md +18 -0
  2. package/assets/octobot/lg/octo_blink.webp +0 -0
  3. package/assets/octobot/lg/octo_blink_still.png +0 -0
  4. package/assets/octobot/lg/octo_idle.webp +0 -0
  5. package/assets/octobot/lg/octo_idle_still.png +0 -0
  6. package/assets/octobot/lg/octo_look.webp +0 -0
  7. package/assets/octobot/lg/octo_look_still.png +0 -0
  8. package/assets/octobot/lg/octo_swim.webp +0 -0
  9. package/assets/octobot/lg/octo_swim_still.png +0 -0
  10. package/assets/octobot/lg/octo_thinking.webp +0 -0
  11. package/assets/octobot/lg/octo_thinking_still.png +0 -0
  12. package/assets/octobot/lg/octo_wave.webp +0 -0
  13. package/assets/octobot/lg/octo_wave_still.png +0 -0
  14. package/assets/octobot/md/octo_blink.webp +0 -0
  15. package/assets/octobot/md/octo_blink_still.png +0 -0
  16. package/assets/octobot/md/octo_idle.webp +0 -0
  17. package/assets/octobot/md/octo_idle_still.png +0 -0
  18. package/assets/octobot/md/octo_look.webp +0 -0
  19. package/assets/octobot/md/octo_look_still.png +0 -0
  20. package/assets/octobot/md/octo_swim.webp +0 -0
  21. package/assets/octobot/md/octo_swim_still.png +0 -0
  22. package/assets/octobot/md/octo_thinking.webp +0 -0
  23. package/assets/octobot/md/octo_thinking_still.png +0 -0
  24. package/assets/octobot/md/octo_wave.webp +0 -0
  25. package/assets/octobot/md/octo_wave_still.png +0 -0
  26. package/assets/octobot/sm/octo_blink.webp +0 -0
  27. package/assets/octobot/sm/octo_blink_still.png +0 -0
  28. package/assets/octobot/sm/octo_idle.webp +0 -0
  29. package/assets/octobot/sm/octo_idle_still.png +0 -0
  30. package/assets/octobot/sm/octo_look.webp +0 -0
  31. package/assets/octobot/sm/octo_look_still.png +0 -0
  32. package/assets/octobot/sm/octo_swim.webp +0 -0
  33. package/assets/octobot/sm/octo_swim_still.png +0 -0
  34. package/assets/octobot/sm/octo_thinking.webp +0 -0
  35. package/assets/octobot/sm/octo_thinking_still.png +0 -0
  36. package/assets/octobot/sm/octo_wave.webp +0 -0
  37. package/assets/octobot/sm/octo_wave_still.png +0 -0
  38. package/fesm2022/meshmakers-shared-ui-assistant-core.mjs +2 -0
  39. package/fesm2022/meshmakers-shared-ui-assistant-core.mjs.map +1 -1
  40. package/fesm2022/meshmakers-shared-ui-assistant.mjs +28 -5
  41. package/fesm2022/meshmakers-shared-ui-assistant.mjs.map +1 -1
  42. package/fesm2022/meshmakers-shared-ui.mjs +402 -21
  43. package/fesm2022/meshmakers-shared-ui.mjs.map +1 -1
  44. package/package.json +1 -1
  45. package/types/meshmakers-shared-ui-assistant-core.d.ts +4 -0
  46. package/types/meshmakers-shared-ui-assistant.d.ts +11 -0
  47. package/types/meshmakers-shared-ui.d.ts +270 -6
@@ -1 +1 @@
1
- {"version":3,"file":"meshmakers-shared-ui-assistant-core.mjs","sources":["../../../../projects/meshmakers/shared-ui/assistant-core/src/assistant.messages.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/not-connected.transport.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/assistant-tool-call-row.component.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/assistant.models.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/assistant-context.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/assistant.service.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/testing/fake-assistant-transport.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/assistant-attachments.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/assistant-explain.directive.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/public-api.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/meshmakers-shared-ui-assistant-core.ts"],"sourcesContent":["import { computed, inject, InjectionToken, Signal } from '@angular/core';\nimport type { AssistantProposalDecisionKind } from './assistant.models';\n\n/**\n * UI strings of the assistant (`mm-assistant-panel`, composer, thread, proposal card), the\n * context chips and the default \"not connected\" transport.\n *\n * Provide translations app wide with {@link ASSISTANT_MESSAGES} or per component with the\n * `messages` input (wins over the token). Missing, `undefined` or `null` members keep the English\n * default of {@link DEFAULT_ASSISTANT_MESSAGES}; `{name}` placeholders are filled with\n * {@link formatAssistantMessage}. Slash command descriptions come from `ASSISTANT_SLASH_COMMANDS`.\n */\nexport interface AssistantMessages {\n // --- Panel ---\n title: string;\n /** Chip in the header while a backend is connected. */\n readsWithYourPermissions: string;\n closeAssistant: string;\n /** `aria-label` of the context chip list. */\n contextLabel: string;\n /** `aria-label` of a chip's remove button; `{label}` = chip label. */\n removeContext: string;\n /** Fallback when the transport gives no status message. */\n notAvailable: string;\n /** Status message of the default transport (no backend). */\n notConnected: string;\n // --- Composer ---\n commandsLabel: string;\n composerLabel: string;\n composerPlaceholder: string;\n send: string;\n stop: string;\n // --- Thread ---\n conversationLabel: string;\n /** Screen-reader prefix of user turns. */\n youPrefix: string;\n /** Screen-reader prefix of assistant turns. */\n assistantPrefix: string;\n /** Screen-reader prefix of error rows. */\n errorPrefix: string;\n /** Screen-reader prefix of the typed slash command shown above its expanded prompt. */\n slashCommandPrefix: string;\n /** Error row when a slash command's `expand` fails; `{command}` = command word. */\n slashCommandFailed: string;\n // --- Proposal card ---\n /** `aria-label` of a proposal card; `{title}` = proposal title. */\n proposalLabel: string;\n proposal: string;\n /** Card header addition for writing proposals (after \"Proposal ·\"). */\n writesToTenant: string;\n tool: string;\n runsAfterConfirm: string;\n run: string;\n edit: string;\n discard: string;\n runRequested: string;\n editRequested: string;\n discarded: string;\n // --- Context chips ---\n /** `{tenant}` = tenant id. */\n contextTenant: string;\n /** `{page}` = page label. */\n contextPage: string;\n // --- Sessions (only with a transport that has sessions) ---\n /** Header icon button that opens the list of saved chats (tooltip + `aria-label`). */\n sessions: string;\n /** Header icon button that starts a fresh chat (tooltip + `aria-label`). */\n newChat: string;\n /** `aria-label` of the saved chats list. */\n sessionsLabel: string;\n /** Shown when there are no saved chats. */\n noSessions: string;\n /** Leaves the chat list without opening a chat. */\n backToChat: string;\n /** `aria-label` of a chat's delete button; `{title}` = chat title. */\n deleteSession: string;\n /** Inline confirmation; `{title}` = chat title. */\n deleteSessionConfirm: string;\n /** Confirms the deletion. */\n delete: string;\n cancel: string;\n /** Error row when a saved chat cannot be opened. */\n sessionLoadFailed: string;\n /** Error row when a saved chat cannot be deleted. */\n sessionDeleteFailed: string;\n // --- Attachments (only with a transport that accepts files) ---\n /** `aria-label` / tooltip of the attach button. */\n attachFile: string;\n /** `aria-label` of the attached files list. */\n attachmentsLabel: string;\n /** `aria-label` of an attachment's remove button; `{name}` = file name. */\n removeAttachment: string;\n /** `{name}` = file name. */\n attachmentWrongType: string;\n /** `{name}` = file name, `{max}` = size limit (e.g. \"10 MB\"). */\n attachmentTooLarge: string;\n /** `{max}` = most files per message. */\n attachmentTooMany: string;\n // --- Starter questions (only with a transport that provides them) ---\n /** Heading above the starter questions of an empty chat. */\n startersTitle: string;\n // --- Resizing ---\n /** `aria-label` / tooltip of the panel's resize handle. */\n resizePanel: string;\n}\n\nexport const DEFAULT_ASSISTANT_MESSAGES: AssistantMessages = {\n title: 'Assistant',\n readsWithYourPermissions: 'Reads with your permissions',\n closeAssistant: 'Close assistant',\n contextLabel: 'Context sent with your message',\n removeContext: 'Remove context {label}',\n notAvailable: 'Assistant not available',\n notConnected: 'Assistant backend not available yet',\n commandsLabel: 'Commands',\n composerLabel: 'Message the assistant',\n composerPlaceholder: 'Ask something or type / for commands…',\n send: 'Send',\n stop: 'Stop',\n conversationLabel: 'Conversation',\n youPrefix: 'You: ',\n assistantPrefix: 'Assistant: ',\n errorPrefix: 'Error: ',\n slashCommandPrefix: 'Command: ',\n slashCommandFailed: 'The command {command} could not be run.',\n proposalLabel: 'Proposal: {title}',\n proposal: 'Proposal',\n writesToTenant: 'writes to the tenant',\n tool: 'Tool',\n runsAfterConfirm: 'runs only after you confirm',\n run: 'Run',\n edit: 'Edit',\n discard: 'Discard',\n runRequested: 'Run requested',\n editRequested: 'Edit requested',\n discarded: 'Discarded',\n contextTenant: 'Tenant: {tenant}',\n contextPage: 'Page: {page}',\n sessions: 'Chats',\n newChat: 'New chat',\n sessionsLabel: 'Saved chats',\n noSessions: 'No saved chats yet',\n backToChat: 'Back to the chat',\n deleteSession: 'Delete chat {title}',\n deleteSessionConfirm: 'Delete “{title}”?',\n delete: 'Delete',\n cancel: 'Cancel',\n sessionLoadFailed: 'The chat could not be opened.',\n sessionDeleteFailed: 'The chat could not be deleted.',\n attachFile: 'Attach file',\n attachmentsLabel: 'Attached files',\n removeAttachment: 'Remove attachment {name}',\n attachmentWrongType: '{name} is not an accepted file type.',\n attachmentTooLarge: '{name} is larger than {max}.',\n attachmentTooMany: 'At most {max} file(s) per message.',\n startersTitle: 'Try asking',\n resizePanel: 'Resize assistant panel',\n};\n\n/** App-wide translations of the assistant (partial). */\nexport const ASSISTANT_MESSAGES = new InjectionToken<Partial<AssistantMessages>>('ASSISTANT_MESSAGES');\n\n/** Merges overrides over {@link DEFAULT_ASSISTANT_MESSAGES}, later sources winning; null/undefined members are ignored. */\nexport function resolveAssistantMessages(...overrides: (Partial<AssistantMessages> | null | undefined)[]): AssistantMessages {\n const resolved: AssistantMessages = { ...DEFAULT_ASSISTANT_MESSAGES };\n for (const messages of overrides) {\n if (!messages) {\n continue;\n }\n for (const key of Object.keys(messages) as (keyof AssistantMessages)[]) {\n const value = messages[key];\n if (value !== undefined && value !== null) {\n resolved[key] = value;\n }\n }\n }\n return resolved;\n}\n\n/** Replaces `{name}` placeholders; unknown placeholders stay as they are. */\nexport function formatAssistantMessage(message: string, values: Record<string, string | number>): string {\n return message.replace(/\\{(\\w+)\\}/g, (match, key: string) =>\n Object.prototype.hasOwnProperty.call(values, key) ? String(values[key]) : match);\n}\n\n/** The settled label of a proposal decision. */\nexport function proposalDecisionLabel(kind: AssistantProposalDecisionKind, messages: AssistantMessages): string {\n switch (kind) {\n case 'run': return messages.runRequested;\n case 'edit': return messages.editRequested;\n case 'discard': return messages.discarded;\n }\n}\n\n/**\n * {@link ASSISTANT_MESSAGES} merged with a component input (the input wins).\n * Call it in an injection context.\n * @internal\n */\nexport function assistantMessages(input: Signal<Partial<AssistantMessages> | null | undefined>): Signal<AssistantMessages> {\n const injected = inject(ASSISTANT_MESSAGES, { optional: true });\n return computed(() => resolveAssistantMessages(injected, input()));\n}\n","import { Injectable, inject, signal } from '@angular/core';\nimport { Observable, throwError } from 'rxjs';\nimport type { AssistantSendRequest, AssistantStreamEvent, AssistantTransport } from './assistant.models';\nimport { ASSISTANT_MESSAGES, DEFAULT_ASSISTANT_MESSAGES, resolveAssistantMessages } from './assistant.messages';\n\n/** The (English) text the panel shows while no backend exists. */\nexport const ASSISTANT_NOT_CONNECTED_MESSAGE = DEFAULT_ASSISTANT_MESSAGES.notConnected;\n\n/**\n * The default {@link AssistantTransport}: it is never `ready`, so the composer\n * cannot send, and it never produces an answer. It exists so the panel can say\n * honestly that there is no assistant backend (AB#5550) instead of faking one.\n * The message follows `ASSISTANT_MESSAGES.notConnected`.\n */\n@Injectable({ providedIn: 'root' })\nexport class NotConnectedAssistantTransport implements AssistantTransport {\n private readonly message = resolveAssistantMessages(inject(ASSISTANT_MESSAGES, { optional: true })).notConnected;\n\n readonly status = signal('unavailable' as const).asReadonly();\n readonly statusMessage = signal<string | null>(this.message).asReadonly();\n\n send(_request: AssistantSendRequest): Observable<AssistantStreamEvent> {\n return throwError(() => new Error(this.message));\n }\n}\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport type { AssistantToolCall } from './assistant.models';\n\n/**\n * Default renderer of a tool call in the thread: tool name in mono plus its status.\n * Replace it through `ASSISTANT_TOOL_CALL_COMPONENT`.\n */\n@Component({\n selector: 'mm-assistant-tool-call-row',\n template: '<span class=\"tool-name\">{{ call().toolName }}</span> <span class=\"tool-status\">{{ call().status }}</span>',\n styles: [`\n :host { display: inline-flex; gap: var(--theme-space-2, 8px); align-items: baseline; }\n .tool-name { font-family: var(--theme-font-mono, monospace); }\n .tool-status { color: var(--theme-text-secondary); }\n `],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AssistantToolCallRowComponent {\n readonly call = input.required<AssistantToolCall>();\n}\n","import { InjectionToken, Signal, Type, inject } from '@angular/core';\nimport { Observable } from 'rxjs';\nimport { NotConnectedAssistantTransport } from './not-connected.transport';\nimport { AssistantToolCallRowComponent } from './assistant-tool-call-row.component';\n\n/**\n * The single feature flag of the assistant (ui-concept §5.3, AB#5549).\n * **Off by default.** While it is off nothing assistant-related renders or binds:\n * no top-bar ✦ button, no Cmd/Ctrl+J, no \"✦ Explain\" affordances, and the command\n * palette's `?` scope only shows \"Assistant not available\".\n *\n * Enable it for a host with `{ provide: ASSISTANT_ENABLED, useValue: true }`. The host gates its\n * own affordances (top-bar toggle, Cmd/Ctrl+J, palette row) on `AssistantService.enabled`.\n * Turning it on without a real {@link ASSISTANT_TRANSPORT} shows the panel with an\n * honest \"Assistant backend not available yet\" state — never canned answers.\n */\nexport const ASSISTANT_ENABLED = new InjectionToken<boolean>('ASSISTANT_ENABLED', {\n providedIn: 'root',\n factory: () => false\n});\n\n/** Connection state of the transport; only `ready` lets the composer send. */\nexport type AssistantTransportStatus = 'unavailable' | 'ready' | 'busy' | 'error';\n\n/** Kinds of context the panel sends as structured data (ids, not DOM). */\nexport type AssistantContextKind = 'tenant' | 'page' | 'entity';\n\n/** One removable chip of the context row. */\nexport interface AssistantContextChip {\n /** Stable per value (`<kind>:<value>`) so a removed chip stays removed until the value changes. */\n id: string;\n kind: AssistantContextKind;\n /** Visible text, e.g. \"Integration › Adapters\". */\n label: string;\n /** Structured value sent to the backend: tenant id, router URL, or entity id. */\n value: string;\n /** Optional CK type of an entity chip. */\n ckTypeId?: string;\n}\n\n/** What an \"✦ Explain\" entry point asks about. */\nexport interface AssistantExplainTarget {\n /** Human readable name of the object, e.g. \"edge-plc-07\" or \"System.Communication/Adapter\". */\n label: string;\n /** Runtime id of the object, when it is an entity. */\n rtId?: string;\n /** CK type id of the object (or the type itself for \"explain this type\"). */\n ckTypeId?: string;\n /** Overrides the composer prefill; defaults to `/explain <label>`. */\n prompt?: string;\n}\n\n/** A request to open the panel. */\nexport interface AssistantOpenRequest {\n /** Prefills the composer (never sent automatically). */\n prompt?: string;\n /** Adds (or replaces) the entity chip, e.g. from an Explain entry point. */\n entity?: AssistantExplainTarget;\n}\n\n/** A write the assistant wants to perform; rendered as a proposal card. */\nexport interface AssistantProposal {\n id: string;\n title: string;\n /** Markdown-free one-liner explaining the effect. */\n description?: string;\n /** MCP tool that would run on confirmation, e.g. `deploy_adapter`. */\n toolName: string;\n /** Parameter table shown on the card. */\n parameters: { name: string; value: string }[];\n /** True when the proposal writes to the tenant (the card says so). */\n writes: boolean;\n}\n\n/**\n * A tool call the assistant made, shown as a row of the thread. Structurally compatible with\n * `AiToolCallDto` of `@meshmakers/octo-ai-console`, so its events can be passed on unchanged.\n */\nexport interface AssistantToolCall {\n readonly callId: string;\n readonly toolName: string;\n /** E.g. 'Pending' | 'Approved' | 'Rejected' | 'Succeeded' | 'Failed'. */\n readonly status: string;\n readonly sessionId?: string;\n readonly arguments?: unknown;\n readonly result?: unknown;\n readonly startedAt?: string;\n readonly completedAt?: string | null;\n readonly durationMs?: number | null;\n}\n\n/**\n * The component that renders one tool call in the thread. It must have a `call` input taking an\n * {@link AssistantToolCall}. Default: a compact name + status row. An OctoMesh host passes\n * `AiToolCallComponent` of `@meshmakers/octo-ai-console` (collapsible details):\n * `{ provide: ASSISTANT_TOOL_CALL_COMPONENT, useValue: AiToolCallComponent }`.\n */\nexport const ASSISTANT_TOOL_CALL_COMPONENT = new InjectionToken<Type<unknown>>('ASSISTANT_TOOL_CALL_COMPONENT', {\n providedIn: 'root',\n factory: () => AssistantToolCallRowComponent\n});\n\n/**\n * Labels of the active area and tab of the shell, used for the \"Page: Area › Tab\" context chip.\n * Optional; without it the page chip falls back to the first breadcrumb. With\n * `@meshmakers/shared-ui/shell`:\n *\n * ```ts\n * { provide: ASSISTANT_PAGE_CONTEXT, useFactory: () => {\n * const nav = inject(ShellNavigationService);\n * return { areaText: () => nav.activeArea()?.text ?? null, tabText: () => nav.activeTab()?.text ?? null };\n * } }\n * ```\n *\n * Read inside a computed, so signal-backed functions keep the chips up to date.\n */\nexport interface AssistantPageContext {\n areaText(): string | null;\n tabText(): string | null;\n}\n\nexport const ASSISTANT_PAGE_CONTEXT = new InjectionToken<AssistantPageContext>('ASSISTANT_PAGE_CONTEXT');\n\n/** One rendered item of the thread. */\nexport type AssistantThreadItem =\n | {\n kind: 'user';\n id: string;\n /** What was sent — for a slash command with `expand`, the expanded prompt. */\n text: string;\n attachments?: readonly AssistantAttachmentRef[];\n /**\n * The slash command as typed (e.g. `/open March`) when {@link text} is its expansion (AB#5621).\n * The thread shows it as a subtle label above the prompt. A transport may store it and return it\n * from `loadSession` so reopened chats show the label too; without it they show the prompt only.\n */\n slashCommand?: string;\n }\n | { kind: 'assistant'; id: string; markdown: string; streaming: boolean }\n | { kind: 'tool-call'; id: string; call: AssistantToolCall }\n | { kind: 'proposal'; id: string; proposal: AssistantProposal; decision: AssistantProposalDecisionKind | null }\n | { kind: 'error'; id: string; text: string };\n\nexport type AssistantProposalDecisionKind = 'run' | 'edit' | 'discard';\n\n/**\n * A decision on a proposal card. The card only emits it; whatever executes the\n * write (the backend's confirm round-trip, AB#5550) subscribes to\n * `AssistantService.proposalDecisions$`. Nothing in this library executes a proposal.\n */\nexport interface AssistantProposalDecision {\n kind: AssistantProposalDecisionKind;\n proposal: AssistantProposal;\n}\n\n/** What the composer hands to the transport. */\nexport interface AssistantSendRequest {\n /** The typed text; may be empty when the turn only carries {@link files}. */\n text: string;\n /** The chips that remained after the user removed what they did not want to share. */\n context: AssistantContextChip[];\n /**\n * Files attached in the composer. Only set when the transport declares\n * {@link AssistantTransport.attachments} and the person attached at least one file\n * (already checked against `accept`, `maxFiles` and `maxFileSizeBytes`).\n */\n files?: File[];\n /**\n * The slash command as typed (e.g. `/open March`) when {@link text} is the prompt its\n * {@link AssistantSlashCommand.expand} produced (AB#5621). `text` is always what the model should\n * read; store `text` as the turn so a reopened chat matches the live thread, and optionally keep\n * this alongside it (returned as `slashCommand` on the restored user item) for the label.\n */\n slashCommand?: string;\n}\n\n/** Name (and size) of a file sent with a user turn, shown under the turn in the thread. */\nexport interface AssistantAttachmentRef {\n name: string;\n /** Bytes, when known. */\n size?: number;\n}\n\n/**\n * File attachments a transport accepts (AB#5621). Declaring {@link AssistantTransport.attachments}\n * shows an \"Attach file\" button in the composer; without it there is no attachment UI.\n */\nexport interface AssistantAttachmentOptions {\n /**\n * Accepted types, in the syntax of `<input type=\"file\" accept>`: comma separated MIME types\n * (`application/pdf`, `image/*`) and/or extensions (`.pdf`). Empty or omitted = any type.\n */\n accept?: string;\n /** How many files one turn may carry (default 1). */\n maxFiles?: number;\n /** Largest accepted file in bytes; omitted = no limit in the UI. */\n maxFileSizeBytes?: number;\n}\n\n/** A saved conversation of the person, as listed by {@link AssistantTransport.sessions}. */\nexport interface AssistantSessionSummary {\n id: string;\n title: string;\n /** ISO 8601 timestamp; shown as a secondary line when present. */\n createdAt?: string;\n}\n\n/** Starter questions as a transport can provide them: synchronously, as a promise or as an observable (first value counts). */\nexport type AssistantStarterQuestions =\n | readonly string[]\n | Promise<readonly string[]>\n | Observable<readonly string[]>;\n\n/** A result a session method may return: a promise or an observable (its last value counts). */\nexport type AssistantAsyncResult<T> = Promise<T> | Observable<T>;\n\n/** Events a transport streams back for one send. */\nexport type AssistantStreamEvent =\n | { type: 'message-delta'; messageId: string; text: string }\n | { type: 'message-end'; messageId: string }\n | { type: 'tool-call'; call: AssistantToolCall }\n | { type: 'proposal'; proposal: AssistantProposal }\n | { type: 'error'; message: string };\n\n/**\n * Where assistant turns come from. The library ships **no** implementation that\n * answers: the default is {@link NotConnectedAssistantTransport}. A real one\n * (e.g. the OctoMesh AI services, AB#5550 delegated-identity chat sessions) provides\n * itself under {@link ASSISTANT_TRANSPORT}.\n */\nexport interface AssistantTransport {\n readonly status: Signal<AssistantTransportStatus>;\n /** Shown in the panel when the status is not `ready`. */\n readonly statusMessage: Signal<string | null>;\n /** One user turn; completes when the assistant turn is complete. */\n send(request: AssistantSendRequest): Observable<AssistantStreamEvent>;\n\n // --- Optional capabilities (AB#5621). The panel only shows the matching UI when present. ---\n\n /**\n * Accepted file attachments. When set, the composer gets an \"Attach file\" button and\n * {@link AssistantSendRequest.files} carries the files; a turn may then have empty text.\n */\n readonly attachments?: AssistantAttachmentOptions | null;\n\n /**\n * Example questions for an empty thread, in the UI language. Read each time the panel opens;\n * clicking one sends it as if it had been typed. An observable need not complete: its first\n * emitted value is taken (later emissions are ignored until the next opening).\n */\n starterQuestions?(): AssistantStarterQuestions;\n\n /**\n * Saved sessions of the signed-in person, newest first. Together with {@link loadSession} it\n * enables the panel's chat list (\"Chats\" and \"New chat\" in the header).\n */\n readonly sessions?: Signal<readonly AssistantSessionSummary[]>;\n /** The session the next send writes to; `null` = a fresh chat. Marks the current row in the list. */\n readonly activeSessionId?: Signal<string | null>;\n /** Reloads {@link sessions}; called when the chat list is opened. */\n refreshSessions?(): AssistantAsyncResult<void>;\n /** Makes a saved session active and returns its thread. */\n loadSession?(id: string): AssistantAsyncResult<AssistantThreadItem[]>;\n /** Deletes a saved session. Without it the chat list has no delete buttons. */\n deleteSession?(id: string): AssistantAsyncResult<void>;\n /** Starts a fresh chat: the next send creates a new session. */\n newSession?(): void;\n}\n\n/** The assistant's transport; defaults to the honest \"not connected\" one. */\nexport const ASSISTANT_TRANSPORT = new InjectionToken<AssistantTransport>('ASSISTANT_TRANSPORT', {\n providedIn: 'root',\n factory: () => inject(NotConnectedAssistantTransport)\n});\n\n/** A composer slash command (ui-concept §5.3). */\nexport interface AssistantSlashCommand {\n /** The command word with its slash, lower-case, e.g. `/explain`. */\n command: string;\n description: string;\n /**\n * Turns the typed command into the prompt that is sent (AB#5621). Called by\n * `AssistantService.send` when the text is `<command>` or `<command> <args>`: `command` is this\n * command's word, `args` the trimmed rest (`''` when none). The returned text — synchronously or\n * as a promise — is what goes to the transport **and** what the live thread shows (with the typed\n * command as a small label), so a chat reopened from the transport reads the same.\n *\n * If it throws, rejects or returns an empty text, nothing is sent: an error row is added and the\n * draft is restored. Without `expand` the typed text is sent unchanged (default behaviour).\n *\n * ```ts\n * { command: '/open', description: 'Open items',\n * expand: (_command, args) => args ? `Which items are open for ${args}?` : 'Which items are open?' }\n * ```\n */\n expand?: (command: string, args: string) => string | Promise<string>;\n}\n\n/** The default slash commands (English descriptions). */\nexport const DEFAULT_ASSISTANT_SLASH_COMMANDS: readonly AssistantSlashCommand[] = [\n { command: '/explain', description: 'Explain the object in context' },\n { command: '/query', description: 'Turn a question into a query' },\n { command: '/summarise', description: 'Summarise events or a selection' },\n { command: '/draft-pipeline', description: 'Draft a pipeline as a diff' }\n];\n\n/** The composer's slash commands; provide your own list (or translated descriptions) to change them. */\nexport const ASSISTANT_SLASH_COMMANDS = new InjectionToken<readonly AssistantSlashCommand[]>('ASSISTANT_SLASH_COMMANDS', {\n providedIn: 'root',\n factory: () => DEFAULT_ASSISTANT_SLASH_COMMANDS\n});\n\n/**\n * Layout of `mm-assistant-panel` (AB#5621); every member is optional and the panel's inputs of the\n * same name win. Defaults keep the original look: a docked panel 400 px wide (340 px ≤ 1180 px)\n * that pushes the content, without a resize handle (opt in with `resizable: true`).\n */\nexport interface AssistantPanelOptions {\n /**\n * `docked` (default): the panel takes its own column and pushes the content.\n * `overlay`: it floats over the content at the right edge (`position: fixed`), from\n * `--mm-assistant-overlay-top` (default 48 px, the shell's top bar) to the bottom.\n */\n mode?: AssistantPanelMode;\n /**\n * Shows the drag handle on the left edge (default `false`: no handle, no extra tab stop; never on\n * phones). Only with it on does a persisted width apply.\n */\n resizable?: boolean;\n /** Smallest width in px the handle allows (default {@link DEFAULT_ASSISTANT_PANEL_MIN_WIDTH}). */\n minWidth?: number;\n /**\n * Largest width in px the handle allows (default {@link DEFAULT_ASSISTANT_PANEL_MAX_WIDTH});\n * further capped so at least 240 px of the window stay free.\n */\n maxWidth?: number;\n /**\n * `localStorage` key of the width the person chose (default\n * {@link DEFAULT_ASSISTANT_PANEL_STORAGE_KEY}); `null` = do not persist. Storage that is missing or\n * throws (private mode, blocked site data) is ignored — the width then lasts as long as the panel.\n */\n storageKey?: string | null;\n}\n\nexport type AssistantPanelMode = 'docked' | 'overlay';\n\nexport const DEFAULT_ASSISTANT_PANEL_MIN_WIDTH = 320;\nexport const DEFAULT_ASSISTANT_PANEL_MAX_WIDTH = 720;\nexport const DEFAULT_ASSISTANT_PANEL_STORAGE_KEY = 'mm-assistant-panel-width';\n\n/** App-wide {@link AssistantPanelOptions}; optional. */\nexport const ASSISTANT_PANEL_OPTIONS = new InjectionToken<AssistantPanelOptions>('ASSISTANT_PANEL_OPTIONS');\n","import { ActivatedRouteSnapshot } from '@angular/router';\nimport { AssistantContextChip, AssistantExplainTarget } from './assistant.models';\nimport { AssistantMessages, formatAssistantMessage, resolveAssistantMessages } from './assistant.messages';\n\n/** Route params that name the object a page shows (detail pages, editors). */\nconst ENTITY_PARAM = /^(rtId|id|[a-zA-Z]+Id|userName)$/;\n/** Params that are scope, not the object. */\nconst SCOPE_PARAMS = new Set(['tenantId']);\n\n/** Inputs of {@link deriveAssistantContext}, all read from the shell. */\nexport interface AssistantContextSource {\n /** Root of the router state snapshot. */\n root: ActivatedRouteSnapshot | null | undefined;\n /** Router URL of the page (query and fragment are dropped). */\n url: string;\n /** Breadcrumb labels of the page, root first. */\n breadcrumbs: string[];\n /** Active rail area and tab (see `ASSISTANT_PAGE_CONTEXT`). */\n areaText?: string | null;\n tabText?: string | null;\n /** Entity set explicitly by an Explain entry point; wins over the route. */\n explicitEntity?: AssistantExplainTarget | null;\n}\n\n/**\n * Turns the current route into the panel's context chips (ui-concept §5.3):\n * tenant, page (\"Area › Tab\", else the breadcrumb) and the selected entity — the\n * one an Explain entry point named, otherwise the deepest id-like route param\n * (labelled with the last breadcrumb). Pure, so it is tested without a router.\n */\nexport function deriveAssistantContext(\n source: AssistantContextSource,\n messages?: Partial<AssistantMessages> | null\n): AssistantContextChip[] {\n const m = resolveAssistantMessages(messages);\n const params = collectParams(source.root);\n const chips: AssistantContextChip[] = [];\n\n const tenantId = params.get('tenantId');\n if (tenantId) {\n chips.push({ id: `tenant:${tenantId}`, kind: 'tenant', label: formatAssistantMessage(m.contextTenant, { tenant: tenantId }), value: tenantId });\n }\n\n const path = source.url.split('#')[0].split('?')[0];\n const pageLabel = source.areaText && source.tabText && source.tabText !== source.areaText\n ? `${source.areaText} › ${source.tabText}`\n : source.tabText ?? source.areaText ?? source.breadcrumbs[0] ?? null;\n if (pageLabel && path) {\n chips.push({ id: `page:${path}`, kind: 'page', label: formatAssistantMessage(m.contextPage, { page: pageLabel }), value: path });\n }\n\n const explicit = source.explicitEntity;\n if (explicit) {\n const value = explicit.rtId ?? explicit.ckTypeId ?? explicit.label;\n chips.push({\n id: `entity:${value}`, kind: 'entity', label: explicit.label, value,\n ...(explicit.ckTypeId ? { ckTypeId: explicit.ckTypeId } : {})\n });\n return chips;\n }\n\n const entity = [...params.entries()].reverse().find(([name]) => !SCOPE_PARAMS.has(name) && ENTITY_PARAM.test(name));\n if (entity) {\n const [, value] = entity;\n const crumbs = source.breadcrumbs;\n const label = crumbs.length > 1 ? crumbs[crumbs.length - 1] : value;\n chips.push({ id: `entity:${value}`, kind: 'entity', label, value });\n }\n return chips;\n}\n\n/** Params from the root to the deepest primary child, in that order (later wins on clashes). */\nfunction collectParams(root: ActivatedRouteSnapshot | null | undefined): Map<string, string> {\n const params = new Map<string, string>();\n let node: ActivatedRouteSnapshot | null | undefined = root;\n while (node) {\n for (const [name, value] of Object.entries(node.params ?? {})) {\n if (typeof value === 'string' && value) {\n params.delete(name);\n params.set(name, value);\n }\n }\n node = node.firstChild;\n }\n return params;\n}\n","import { DestroyRef, Injectable, Signal, computed, inject, signal } from '@angular/core';\nimport { NavigationEnd, Router } from '@angular/router';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { BreadCrumbService } from '@meshmakers/shared-services';\nimport { Observable, Subject, Subscription, firstValueFrom, isObservable, lastValueFrom } from 'rxjs';\nimport { filter } from 'rxjs/operators';\nimport { deriveAssistantContext } from './assistant-context';\nimport { ASSISTANT_MESSAGES, formatAssistantMessage, resolveAssistantMessages } from './assistant.messages';\nimport {\n ASSISTANT_ENABLED,\n ASSISTANT_SLASH_COMMANDS,\n AssistantSlashCommand,\n ASSISTANT_PAGE_CONTEXT,\n AssistantPageContext,\n ASSISTANT_TRANSPORT,\n AssistantContextChip,\n AssistantExplainTarget,\n AssistantOpenRequest,\n AssistantProposal,\n AssistantProposalDecision,\n AssistantProposalDecisionKind,\n AssistantAsyncResult,\n AssistantAttachmentOptions,\n AssistantSendRequest,\n AssistantSessionSummary,\n AssistantStreamEvent,\n AssistantThreadItem\n} from './assistant.models';\n\nconst NO_SESSIONS = signal<readonly AssistantSessionSummary[]>([]).asReadonly();\nconst NO_ACTIVE_SESSION = signal<string | null>(null).asReadonly();\n\n/** Awaits a promise or the last value of an observable; an observable that completes empty (e.g. `EMPTY` for a void result) yields `undefined` instead of rejecting. */\n/** `/word rest` → the word (lower-case) and the trimmed rest; anything else → null. */\nfunction parseSlashCommand(text: string): { word: string; args: string } | null {\n const match = /^(\\/[\\w-]+)(?:\\s+([\\s\\S]*))?$/.exec(text);\n return match ? { word: match[1].toLowerCase(), args: (match[2] ?? '').trim() } : null;\n}\n\nfunction settle<T>(result: AssistantAsyncResult<T>): Promise<T | undefined> {\n return isObservable(result) ? lastValueFrom(result, { defaultValue: undefined }) : result;\n}\n\n/**\n * State and entry points of the assistant panel (ui-concept §5.3, AB#5549).\n *\n * - **Flag.** Everything is gated by {@link ASSISTANT_ENABLED} (off by default):\n * while it is off every entry point is a no-op that returns `false`, and the\n * service does not even listen to the router.\n * - **Entry points.** {@link open} (top-bar ✦, Cmd/Ctrl+J, palette `?` scope),\n * {@link requestExplain} (\"✦ Explain <object>\", AB#5545/5547), {@link toggle}.\n * They open the panel with a prefilled composer and context; they never send.\n * - **Thread.** Survives closing the panel and navigating. Items only come from the\n * {@link ASSISTANT_TRANSPORT}; the default transport is not connected, so the\n * library itself never adds an assistant turn.\n * - **Context.** Tenant (route param `tenantId`), page (`ASSISTANT_PAGE_CONTEXT`, else the first\n * breadcrumb of shared-services' `BreadCrumbService`) and entity chips; see {@link deriveAssistantContext}.\n * - **Proposals.** Run / Edit / Discard are published on {@link proposalDecisions$}\n * and nothing else — executing a write is the backend's confirm round-trip (AB#5550).\n * - **Optional transport capabilities (AB#5621).** Sessions ({@link sessionsSupported},\n * {@link openSession}, {@link deleteSession}, {@link newThread}), file attachments\n * ({@link attachments}, {@link draftFiles}) and starter questions ({@link starterQuestions}) are\n * only offered when the transport implements them; otherwise they are inert.\n * - **Slash commands (AB#5621).** A command of `ASSISTANT_SLASH_COMMANDS` with `expand` is sent as\n * the prompt it returns; see {@link send}.\n */\n@Injectable({ providedIn: 'root' })\nexport class AssistantService {\n /** The feature flag. Read it to gate any assistant affordance. */\n readonly enabled = inject(ASSISTANT_ENABLED);\n\n private readonly transport = inject(ASSISTANT_TRANSPORT);\n private readonly router = inject(Router);\n private readonly destroyRef = inject(DestroyRef);\n /** Only resolved while enabled: a disabled assistant binds nothing. */\n private readonly pageContext: AssistantPageContext | null = null;\n private readonly messages = inject(ASSISTANT_MESSAGES, { optional: true });\n private readonly slashCommands: readonly AssistantSlashCommand[] = inject(ASSISTANT_SLASH_COMMANDS);\n\n private readonly _isOpen = signal(false);\n private readonly _draft = signal('');\n private readonly _focusRequest = signal(0);\n private readonly _explicitEntity = signal<AssistantExplainTarget | null>(null);\n private readonly _removedChips = signal<ReadonlySet<string>>(new Set());\n private readonly _thread = signal<AssistantThreadItem[]>([]);\n private readonly _sending = signal(false);\n private readonly _draftFiles = signal<readonly File[]>([]);\n private readonly _starterQuestions = signal<readonly string[]>([]);\n private starterRequest = 0;\n /** Bumped by every thread switch (open session, new chat, loadThread); stale session loads are dropped. */\n private threadGeneration = 0;\n private readonly _routeTick = signal(0);\n private readonly _breadcrumbs = signal<string[]>([]);\n private readonly decisions = new Subject<AssistantProposalDecision>();\n private returnFocusTo: HTMLElement | null = null;\n private pending: Subscription | null = null;\n private itemCounter = 0;\n /** Bumped by {@link stop}: an async slash-command expansion that resolves later is dropped. */\n private expansionGeneration = 0;\n\n /** Whether the panel is shown. */\n readonly isOpen = this._isOpen.asReadonly();\n /** Composer text; prefilled by entry points. */\n readonly draft = this._draft.asReadonly();\n /** Bumped whenever an entry point wants the composer focused. */\n readonly focusRequest = this._focusRequest.asReadonly();\n /** The rendered thread. */\n readonly thread = this._thread.asReadonly();\n /** A turn is streaming. */\n readonly sending = this._sending.asReadonly();\n readonly transportStatus = this.transport.status;\n readonly transportMessage = this.transport.statusMessage;\n /** The composer may send: the transport is ready and no turn is running. */\n readonly canSend = computed(() => this.transport.status() === 'ready' && !this._sending());\n\n /** The transport has saved sessions (`sessions` + `loadSession`): the panel shows its chat list. */\n readonly sessionsSupported = !!this.transport.sessions && typeof this.transport.loadSession === 'function';\n /** Saved sessions can be deleted (`deleteSession`). */\n readonly sessionDeleteSupported = this.sessionsSupported && typeof this.transport.deleteSession === 'function';\n /** Saved sessions of the transport (empty without session support). */\n readonly sessions: Signal<readonly AssistantSessionSummary[]> = this.transport.sessions ?? NO_SESSIONS;\n /** The session the next send writes to (`null` = fresh chat or no session support). */\n readonly activeSessionId: Signal<string | null> = this.transport.activeSessionId ?? NO_ACTIVE_SESSION;\n\n /** Accepted attachments, or `null` when the transport takes no files (no attach UI). */\n readonly attachments: AssistantAttachmentOptions | null = this.transport.attachments ?? null;\n /** Files attached in the composer; sent and cleared with the next turn. */\n readonly draftFiles = this._draftFiles.asReadonly();\n\n /** Starter questions for an empty thread (see {@link loadStarterQuestions}). */\n readonly starterQuestions = this._starterQuestions.asReadonly();\n\n /** Context of the current page minus the chips the person removed. */\n readonly contextChips: Signal<AssistantContextChip[]> = computed(() => {\n this._routeTick();\n const removed = this._removedChips();\n return deriveAssistantContext({\n root: this.router.routerState?.snapshot?.root,\n url: this.router.url ?? '',\n breadcrumbs: this._breadcrumbs(),\n areaText: this.pageContext?.areaText() ?? null,\n tabText: this.pageContext?.tabText() ?? null,\n explicitEntity: this._explicitEntity()\n }, this.messages).filter(chip => !removed.has(chip.id));\n });\n\n /** Run / Edit / Discard on proposal cards. Only emitted, never executed here. */\n readonly proposalDecisions$: Observable<AssistantProposalDecision> = this.decisions.asObservable();\n\n constructor() {\n if (!this.enabled) {\n return;\n }\n this.pageContext = inject(ASSISTANT_PAGE_CONTEXT, { optional: true });\n inject(BreadCrumbService).breadCrumbItems.pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(items => this._breadcrumbs.set(items.map(item => item.text ?? '').filter(text => text.length > 0)));\n this.router.events.pipe(filter(event => event instanceof NavigationEnd), takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n // An explicit Explain target belongs to the page it was requested on.\n this._explicitEntity.set(null);\n this._routeTick.update(tick => tick + 1);\n });\n this.destroyRef.onDestroy(() => this.pending?.unsubscribe());\n }\n\n /** Opens the panel (or re-focuses it) with an optional prefill. Returns false while disabled. */\n open(request: AssistantOpenRequest = {}): boolean {\n if (!this.enabled) {\n return false;\n }\n if (!this._isOpen()) {\n const active = document.activeElement;\n this.returnFocusTo = active instanceof HTMLElement && active !== document.body ? active : null;\n }\n if (request.entity) {\n this._explicitEntity.set(request.entity);\n this._removedChips.update(removed => removed.size ? new Set() : removed);\n }\n if (request.prompt !== undefined) {\n this._draft.set(request.prompt);\n }\n this._isOpen.set(true);\n this._focusRequest.update(count => count + 1);\n return true;\n }\n\n /** \"✦ Explain <object>\": opens the panel with `/explain <label>` and the object as context chip. */\n requestExplain(target: AssistantExplainTarget): boolean {\n return this.open({ prompt: target.prompt ?? `/explain ${target.label}`, entity: target });\n }\n\n /** Hides the panel and gives focus back to where it was (the ✦ button if that is gone). */\n close(): void {\n if (!this._isOpen()) {\n return;\n }\n this._isOpen.set(false);\n const target = this.returnFocusTo?.isConnected\n ? this.returnFocusTo\n : document.querySelector<HTMLElement>('[data-assistant-toggle]');\n this.returnFocusTo = null;\n target?.focus();\n }\n\n /**\n * Forgets an open panel without moving focus — the host calls it when the\n * panel can no longer be shown (tenant left or denied, connection lost), so it\n * does not pop up again later with a stale return-focus target.\n */\n dismiss(): void {\n this._isOpen.set(false);\n this.returnFocusTo = null;\n }\n\n /** Opens when closed, closes when open. Returns false while disabled. */\n toggle(): boolean {\n if (!this.enabled) {\n return false;\n }\n if (this._isOpen()) {\n this.close();\n } else {\n this.open();\n }\n return true;\n }\n\n setDraft(text: string): void {\n this._draft.set(text);\n }\n\n /** Replaces the attached files (ignored while the transport takes no files). */\n setDraftFiles(files: readonly File[]): void {\n if (this.attachments) {\n this._draftFiles.set([...files]);\n }\n }\n\n /**\n * Asks the transport for its starter questions (the panel calls it when it opens).\n * No-op without `starterQuestions`; a failing source leaves the list empty. Of an observable\n * only the first emitted value counts (it need not complete); one that completes empty yields none.\n */\n loadStarterQuestions(): void {\n const source = this.transport.starterQuestions;\n if (!this.enabled || typeof source !== 'function') {\n return;\n }\n const request = ++this.starterRequest;\n const accept = (questions: readonly string[] | null | undefined): void => {\n if (request === this.starterRequest) {\n this._starterQuestions.set((questions ?? []).filter(q => typeof q === 'string' && q.trim().length > 0));\n }\n };\n try {\n const result = source.call(this.transport);\n if (Array.isArray(result)) {\n accept(result);\n } else if (isObservable(result)) {\n // The first emitted value counts, so a never-completing source (BehaviorSubject, signal stream) works too.\n firstValueFrom(result as Observable<readonly string[]>, { defaultValue: [] as readonly string[] }).then(accept, () => accept([]));\n } else {\n (result as Promise<readonly string[]>).then(accept, () => accept([]));\n }\n } catch {\n accept([]);\n }\n }\n\n /** Reloads the transport's session list. Resolves false without session support or on failure. */\n async refreshSessions(): Promise<boolean> {\n if (!this.enabled || !this.sessionsSupported || typeof this.transport.refreshSessions !== 'function') {\n return false;\n }\n try {\n await settle(this.transport.refreshSessions());\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Opens a saved session: stops a running turn, asks the transport for the session's thread and\n * shows it. On failure the current thread stays and an error row is added. Resolves whether the\n * session was opened.\n */\n async openSession(id: string): Promise<boolean> {\n if (!this.enabled || !this.sessionsSupported) {\n return false;\n }\n this.stop();\n const generation = ++this.threadGeneration;\n try {\n const items = await settle(this.transport.loadSession!(id));\n if (generation !== this.threadGeneration) {\n // Another session was opened (or a new chat started) meanwhile: that one wins.\n return false;\n }\n this.loadThread(items ?? []);\n return true;\n } catch {\n if (generation === this.threadGeneration) {\n this.append({ kind: 'error', id: this.nextId('error'), text: resolveAssistantMessages(this.messages).sessionLoadFailed });\n }\n return false;\n }\n }\n\n /**\n * Deletes a saved session; deleting the active one leaves an empty thread. On failure an error\n * row is added. Resolves whether it was deleted.\n */\n async deleteSession(id: string): Promise<boolean> {\n if (!this.enabled || !this.sessionDeleteSupported) {\n return false;\n }\n const wasActive = this.activeSessionId() === id;\n const generation = this.threadGeneration;\n try {\n await settle(this.transport.deleteSession!(id));\n } catch {\n this.append({ kind: 'error', id: this.nextId('error'), text: resolveAssistantMessages(this.messages).sessionDeleteFailed });\n return false;\n }\n // Only clear when the thread still shows the deleted session (no switch while deleting).\n if (wasActive && generation === this.threadGeneration) {\n this.stop();\n this.threadGeneration += 1;\n this._thread.set([]);\n }\n return true;\n }\n\n /**\n * Starts a fresh chat: stops a running turn, empties the thread and the attached files and tells\n * the transport (`newSession`, when it has one). Works without session support too.\n */\n newThread(): void {\n if (!this.enabled) {\n return;\n }\n this.stop();\n this.threadGeneration += 1;\n this._thread.set([]);\n this._draftFiles.set([]);\n this.transport.newSession?.();\n this.loadStarterQuestions();\n }\n\n /** Replaces the thread, e.g. with a conversation the host restored itself. Stops a running turn. */\n loadThread(items: readonly AssistantThreadItem[]): void {\n if (!this.enabled) {\n return;\n }\n this.stop();\n this.threadGeneration += 1;\n this._thread.set([...items]);\n }\n\n /** Drops a context chip; it stays dropped until its value changes. */\n removeChip(id: string): void {\n this._removedChips.update(removed => new Set(removed).add(id));\n }\n\n /**\n * Sends one user turn through the transport. Does nothing (returns false) unless\n * the transport is `ready` — the default transport never is.\n *\n * With a transport that takes attachments, `files` (default: {@link draftFiles}) go along and\n * the text may be empty; the attached files are cleared with the draft. Explicitly passed `files`\n * are not checked again against {@link attachments} (`accept`, `maxFiles`, `maxFileSizeBytes`) —\n * the composer validates on pick; a host passing files itself is responsible for them.\n *\n * **Slash commands (AB#5621).** When the text is `<command> [args]` and that command of\n * `ASSISTANT_SLASH_COMMANDS` has `expand`, its result is sent instead and shown as the user turn,\n * with the typed text as `slashCommand` (label in the thread, also on the send request). A\n * promise-returning `expand` makes the turn start once it resolves (the composer is busy and Stop\n * cancels meanwhile); returns true when the expansion started. If `expand` throws, rejects or yields\n * an empty prompt, nothing is sent: an error row is added and the draft (text and files) comes back.\n */\n send(text: string, files?: readonly File[]): boolean {\n const trimmed = text.trim();\n const attached = this.attachments ? [...(files ?? this._draftFiles())] : [];\n if (!this.enabled || (!trimmed && !attached.length) || !this.canSend()) {\n return false;\n }\n const parsed = parseSlashCommand(trimmed);\n const command = parsed ? this.slashCommands.find(c => c.command.toLowerCase() === parsed.word && typeof c.expand === 'function') : undefined;\n if (!parsed || !command) {\n this._draft.set('');\n this._draftFiles.set([]);\n this.startTurn(trimmed, attached);\n return true;\n }\n\n const restoreDraft = (): void => {\n if (!this._draft()) {\n this._draft.set(text);\n }\n if (this.attachments && !this._draftFiles().length) {\n this._draftFiles.set(attached);\n }\n };\n const fail = (): void => {\n this.append({\n kind: 'error', id: this.nextId('error'),\n text: formatAssistantMessage(resolveAssistantMessages(this.messages).slashCommandFailed, { command: command.command })\n });\n restoreDraft();\n };\n const accept = (prompt: unknown): boolean => {\n const expanded = typeof prompt === 'string' ? prompt.trim() : '';\n if (!expanded) {\n fail();\n return false;\n }\n this.startTurn(expanded, attached, trimmed);\n return true;\n };\n\n let result: string | Promise<string>;\n try {\n result = command.expand!(command.command, parsed.args);\n } catch {\n fail();\n return false;\n }\n this._draft.set('');\n this._draftFiles.set([]);\n if (typeof result === 'string' || !result || typeof (result as Promise<string>).then !== 'function') {\n return accept(result);\n }\n // Async: busy until the prompt is there; stop() (or a thread switch) drops it.\n const generation = ++this.expansionGeneration;\n this._sending.set(true);\n (result as Promise<string>).then(\n prompt => {\n if (generation === this.expansionGeneration) {\n this._sending.set(false);\n accept(prompt);\n }\n },\n () => {\n if (generation === this.expansionGeneration) {\n this._sending.set(false);\n fail();\n }\n });\n return true;\n }\n\n /** Stops the running turn (the composer's stop button), including a pending slash-command expansion. */\n stop(): void {\n this.expansionGeneration += 1;\n this.pending?.unsubscribe();\n this.finishTurn();\n }\n\n /**\n * Records a decision on a proposal card and publishes it on\n * {@link proposalDecisions$}. Run and Discard settle the card; Edit leaves it open.\n * Nothing is executed here.\n */\n decideProposal(kind: AssistantProposalDecisionKind, proposal: AssistantProposal): void {\n if (kind !== 'edit') {\n this._thread.update(items => items.map(item =>\n item.kind === 'proposal' && item.proposal.id === proposal.id ? { ...item, decision: kind } : item));\n }\n this.decisions.next({ kind, proposal });\n }\n\n /** Appends the user turn and streams the transport's answer. */\n private startTurn(text: string, attached: File[], slashCommand?: string): void {\n const user: Extract<AssistantThreadItem, { kind: 'user' }> = { kind: 'user', id: this.nextId('user'), text };\n if (attached.length) {\n user.attachments = attached.map(file => ({ name: file.name, size: file.size }));\n }\n if (slashCommand !== undefined) {\n user.slashCommand = slashCommand;\n }\n this.append(user);\n this._sending.set(true);\n const request: AssistantSendRequest = { text, context: this.contextChips() };\n if (attached.length) {\n request.files = attached;\n }\n if (slashCommand !== undefined) {\n request.slashCommand = slashCommand;\n }\n this.pending = this.transport.send(request).subscribe({\n next: event => this.apply(event),\n error: (error: unknown) => {\n this.append({ kind: 'error', id: this.nextId('error'), text: error instanceof Error ? error.message : String(error) });\n this.finishTurn();\n },\n complete: () => this.finishTurn()\n });\n }\n\n private apply(event: AssistantStreamEvent): void {\n switch (event.type) {\n case 'message-delta': {\n const id = `assistant:${event.messageId}`;\n const existing = this._thread().find(item => item.id === id);\n if (existing?.kind === 'assistant') {\n this._thread.update(items => items.map(item =>\n item.id === id && item.kind === 'assistant' ? { ...item, markdown: item.markdown + event.text } : item));\n } else {\n this.append({ kind: 'assistant', id, markdown: event.text, streaming: true });\n }\n break;\n }\n case 'message-end':\n this.endMessage(`assistant:${event.messageId}`);\n break;\n case 'tool-call': {\n const id = `tool:${event.call.callId}`;\n if (this._thread().some(item => item.id === id)) {\n this._thread.update(items => items.map(item => item.id === id ? { ...item, call: event.call } as AssistantThreadItem : item));\n } else {\n this.append({ kind: 'tool-call', id, call: event.call });\n }\n break;\n }\n case 'proposal':\n this.append({ kind: 'proposal', id: `proposal:${event.proposal.id}`, proposal: event.proposal, decision: null });\n break;\n case 'error':\n this.append({ kind: 'error', id: this.nextId('error'), text: event.message });\n break;\n }\n }\n\n private finishTurn(): void {\n this.pending = null;\n this._sending.set(false);\n this._thread.update(items => items.map(item =>\n item.kind === 'assistant' && item.streaming ? { ...item, streaming: false } : item));\n }\n\n private endMessage(id: string): void {\n this._thread.update(items => items.map(item =>\n item.id === id && item.kind === 'assistant' ? { ...item, streaming: false } : item));\n }\n\n private append(item: AssistantThreadItem): void {\n this._thread.update(items => [...items, item]);\n }\n\n private nextId(prefix: string): string {\n this.itemCounter += 1;\n return `${prefix}:${this.itemCounter}`;\n }\n}\n\n/**\n * Cmd+J (macOS) / Ctrl+J toggles the assistant panel (ui-concept §4.3), also\n * from text fields — it types nothing. Events another handler consumed and\n * IME composition are ignored.\n */\nexport function assistantHotkey(event: KeyboardEvent): boolean {\n return !event.defaultPrevented && !event.isComposing && event.key?.toLowerCase() === 'j'\n && (event.metaKey || event.ctrlKey) && !event.altKey && !event.shiftKey;\n}\n","import { signal } from '@angular/core';\nimport { Observable, Subject } from 'rxjs';\nimport { AssistantSendRequest, AssistantStreamEvent, AssistantTransport, AssistantTransportStatus } from '../assistant.models';\n\n/**\n * Test double for {@link AssistantTransport} (specs only — never provided by the app).\n * Each `send` returns a Subject the spec drives with `emit` / `complete`.\n */\nexport class FakeAssistantTransport implements AssistantTransport {\n readonly status = signal<AssistantTransportStatus>('ready');\n readonly statusMessage = signal<string | null>(null);\n readonly requests: AssistantSendRequest[] = [];\n private turn: Subject<AssistantStreamEvent> | null = null;\n\n send(request: AssistantSendRequest): Observable<AssistantStreamEvent> {\n this.requests.push(request);\n this.turn = new Subject<AssistantStreamEvent>();\n return this.turn.asObservable();\n }\n\n emit(event: AssistantStreamEvent): void {\n this.turn?.next(event);\n }\n\n fail(error: Error): void {\n this.turn?.error(error);\n }\n\n complete(): void {\n this.turn?.complete();\n }\n}\n","import type { AssistantAttachmentOptions } from './assistant.models';\nimport { AssistantMessages, formatAssistantMessage } from './assistant.messages';\n\n/** Result of {@link selectAssistantAttachments}. */\nexport interface AssistantAttachmentSelection {\n /** The files that stay attached (previous ones first). */\n files: File[];\n /** One translated message per rejected file (or one for \"too many\"). */\n errors: string[];\n}\n\n/** \"512 B\", \"1.5 KB\", \"10 MB\" — for the size-limit message. */\nexport function formatAssistantFileSize(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`;\n }\n const units = ['KB', 'MB', 'GB'];\n let value = bytes / 1024;\n let unit = 0;\n while (value >= 1024 && unit < units.length - 1) {\n value /= 1024;\n unit += 1;\n }\n return `${Number.isInteger(value) ? value : value.toFixed(1)} ${units[unit]}`;\n}\n\n/**\n * Whether a file matches an `accept` list (`<input accept>` syntax: MIME types, `type/*`\n * wildcards and `.ext` extensions, comma separated). An empty list accepts everything.\n */\nexport function assistantFileAccepted(file: Pick<File, 'name' | 'type'>, accept: string | undefined): boolean {\n const patterns = (accept ?? '').split(',').map(p => p.trim().toLowerCase()).filter(p => p.length > 0);\n if (!patterns.length) {\n return true;\n }\n const name = file.name.toLowerCase();\n const type = (file.type ?? '').toLowerCase();\n return patterns.some(pattern => {\n if (pattern.startsWith('.')) {\n return name.endsWith(pattern);\n }\n if (pattern.endsWith('/*')) {\n return type.startsWith(pattern.slice(0, -1));\n }\n return type === pattern;\n });\n}\n\n/**\n * Adds newly picked files to the already attached ones, enforcing the transport's\n * {@link AssistantAttachmentOptions}: wrong type and too large files are rejected individually,\n * files beyond `maxFiles` (default 1) are dropped with one \"too many\" message. With\n * `maxFiles: 1` a newly picked valid file replaces the attached one. Pure.\n */\nexport function selectAssistantAttachments(\n current: readonly File[],\n added: readonly File[],\n options: AssistantAttachmentOptions,\n messages: AssistantMessages\n): AssistantAttachmentSelection {\n const maxFiles = Math.max(1, options.maxFiles ?? 1);\n let files = [...current];\n if (maxFiles === 1 && added.length === 1) {\n files = [];\n }\n const errors: string[] = [];\n let tooMany = false;\n for (const file of added) {\n if (!assistantFileAccepted(file, options.accept)) {\n errors.push(formatAssistantMessage(messages.attachmentWrongType, { name: file.name }));\n } else if (options.maxFileSizeBytes !== undefined && file.size > options.maxFileSizeBytes) {\n errors.push(formatAssistantMessage(messages.attachmentTooLarge,\n { name: file.name, max: formatAssistantFileSize(options.maxFileSizeBytes) }));\n } else if (files.length >= maxFiles) {\n tooMany = true;\n } else {\n files.push(file);\n }\n }\n if (maxFiles === 1 && added.length === 1 && !files.length) {\n files = [...current];\n }\n if (tooMany) {\n errors.push(formatAssistantMessage(messages.attachmentTooMany, { max: maxFiles }));\n }\n return { files, errors };\n}\n","import { Directive, TemplateRef, ViewContainerRef, inject, input } from '@angular/core';\nimport { AssistantService } from './assistant.service';\nimport { AssistantExplainTarget } from './assistant.models';\n\n/**\n * Renders its template only while the assistant is enabled — with the flag off\n * the element is not in the DOM at all. Use it on every AI affordance:\n *\n * ```html\n * <button *mmIfAssistant type=\"button\" class=\"ai-action\"\n * [mmAssistantExplain]=\"{ label: adapter.name, rtId: adapter.rtId, ckTypeId: 'System.Communication/Adapter' }\">\n * ✦ Explain\n * </button>\n * ```\n */\n@Directive({ selector: '[mmIfAssistant]' })\nexport class IfAssistantDirective {\n constructor() {\n if (inject(AssistantService).enabled) {\n inject(ViewContainerRef).createEmbeddedView(inject(TemplateRef));\n }\n }\n}\n\n/**\n * \"✦ Explain <object>\" entry point (ui-concept §5.4): a click opens the assistant\n * panel with `/explain <label>` in the composer and the object as context chip.\n * Nothing is sent. Pair it with {@link IfAssistantDirective} so the trigger does\n * not exist while the assistant is disabled; code without a template (a\n * `CommandItem.onClick`) calls `AssistantService.requestExplain()` instead.\n */\n@Directive({\n selector: '[mmAssistantExplain]',\n host: {\n '(click)': 'explain()',\n '[attr.aria-controls]': 'assistant.isOpen() ? \"assistant-panel\" : null'\n }\n})\nexport class AssistantExplainDirective {\n protected readonly assistant = inject(AssistantService);\n\n readonly target = input.required<AssistantExplainTarget>({ alias: 'mmAssistantExplain' });\n\n protected explain(): void {\n this.assistant.requestExplain(this.target());\n }\n}\n","/*\n * Public API Surface of @meshmakers/shared-ui/assistant-core (AB#5621)\n */\n\n/**\n * The startup part of the assistant: state ({@link AssistantService}), the Cmd/Ctrl+J hotkey,\n * the injection tokens with their defaults, the \"not connected\" transport, models, messages and the\n * \"✦ Explain\" directives. It never imports `marked` or the panel, so a host can wire the assistant\n * in `app.config.ts` / its root component without pulling the panel into the initial bundle and load\n * `AssistantPanelComponent` from `@meshmakers/shared-ui/assistant` lazily (e.g. with `@defer`).\n *\n * `@meshmakers/shared-ui/assistant` re-exports everything from here (same symbols, same tokens),\n * so both entry points can be mixed freely.\n */\n\n// --- Contract and tokens ---\nexport {\n ASSISTANT_ENABLED,\n ASSISTANT_TRANSPORT,\n ASSISTANT_PAGE_CONTEXT,\n ASSISTANT_TOOL_CALL_COMPONENT,\n ASSISTANT_SLASH_COMMANDS,\n DEFAULT_ASSISTANT_SLASH_COMMANDS,\n ASSISTANT_PANEL_OPTIONS,\n DEFAULT_ASSISTANT_PANEL_MIN_WIDTH,\n DEFAULT_ASSISTANT_PANEL_MAX_WIDTH,\n DEFAULT_ASSISTANT_PANEL_STORAGE_KEY,\n} from './assistant.models';\nexport type {\n AssistantTransportStatus,\n AssistantContextKind,\n AssistantContextChip,\n AssistantExplainTarget,\n AssistantOpenRequest,\n AssistantProposal,\n AssistantToolCall,\n AssistantPageContext,\n AssistantThreadItem,\n AssistantProposalDecisionKind,\n AssistantProposalDecision,\n AssistantSendRequest,\n AssistantStreamEvent,\n AssistantTransport,\n AssistantSlashCommand,\n AssistantAttachmentRef,\n AssistantAttachmentOptions,\n AssistantSessionSummary,\n AssistantStarterQuestions,\n AssistantAsyncResult,\n AssistantPanelOptions,\n AssistantPanelMode,\n} from './assistant.models';\n\n// --- Messages / i18n ---\nexport {\n DEFAULT_ASSISTANT_MESSAGES,\n ASSISTANT_MESSAGES,\n resolveAssistantMessages,\n formatAssistantMessage,\n proposalDecisionLabel,\n /** Internal helper of the panel components (signal of resolved messages); not part of the stable API. */\n assistantMessages,\n} from './assistant.messages';\nexport type { AssistantMessages } from './assistant.messages';\n\n// --- Services / transports ---\nexport { AssistantService, assistantHotkey } from './assistant.service';\nexport { NotConnectedAssistantTransport, ASSISTANT_NOT_CONNECTED_MESSAGE } from './not-connected.transport';\nexport { FakeAssistantTransport } from './testing/fake-assistant-transport';\n\n// --- Pure functions ---\nexport { deriveAssistantContext } from './assistant-context';\nexport type { AssistantContextSource } from './assistant-context';\nexport { selectAssistantAttachments, assistantFileAccepted, formatAssistantFileSize } from './assistant-attachments';\nexport type { AssistantAttachmentSelection } from './assistant-attachments';\n\n// --- Components / directives ---\nexport { AssistantToolCallRowComponent } from './assistant-tool-call-row.component';\nexport { IfAssistantDirective, AssistantExplainDirective } from './assistant-explain.directive';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"meshmakers-shared-ui-assistant-core.mjs","sources":["../../../../projects/meshmakers/shared-ui/assistant-core/src/assistant.messages.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/not-connected.transport.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/assistant-tool-call-row.component.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/assistant.models.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/assistant-context.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/assistant.service.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/testing/fake-assistant-transport.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/assistant-attachments.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/assistant-explain.directive.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/public-api.ts","../../../../projects/meshmakers/shared-ui/assistant-core/src/meshmakers-shared-ui-assistant-core.ts"],"sourcesContent":["import { computed, inject, InjectionToken, Signal } from '@angular/core';\nimport type { AssistantProposalDecisionKind } from './assistant.models';\n\n/**\n * UI strings of the assistant (`mm-assistant-panel`, composer, thread, proposal card), the\n * context chips and the default \"not connected\" transport.\n *\n * Provide translations app wide with {@link ASSISTANT_MESSAGES} or per component with the\n * `messages` input (wins over the token). Missing, `undefined` or `null` members keep the English\n * default of {@link DEFAULT_ASSISTANT_MESSAGES}; `{name}` placeholders are filled with\n * {@link formatAssistantMessage}. Slash command descriptions come from `ASSISTANT_SLASH_COMMANDS`.\n */\nexport interface AssistantMessages {\n // --- Panel ---\n title: string;\n /** Chip in the header while a backend is connected. */\n readsWithYourPermissions: string;\n closeAssistant: string;\n /** `aria-label` of the context chip list. */\n contextLabel: string;\n /** `aria-label` of a chip's remove button; `{label}` = chip label. */\n removeContext: string;\n /** Fallback when the transport gives no status message. */\n notAvailable: string;\n /** Status message of the default transport (no backend). */\n notConnected: string;\n // --- Composer ---\n commandsLabel: string;\n composerLabel: string;\n composerPlaceholder: string;\n send: string;\n stop: string;\n // --- Thread ---\n /** Greeting of an empty chat, next to the waving OctoBot (AB#3444). */\n greeting: string;\n /** Shown next to the thinking OctoBot while a reply streams (AB#3444). */\n thinking: string;\n conversationLabel: string;\n /** Screen-reader prefix of user turns. */\n youPrefix: string;\n /** Screen-reader prefix of assistant turns. */\n assistantPrefix: string;\n /** Screen-reader prefix of error rows. */\n errorPrefix: string;\n /** Screen-reader prefix of the typed slash command shown above its expanded prompt. */\n slashCommandPrefix: string;\n /** Error row when a slash command's `expand` fails; `{command}` = command word. */\n slashCommandFailed: string;\n // --- Proposal card ---\n /** `aria-label` of a proposal card; `{title}` = proposal title. */\n proposalLabel: string;\n proposal: string;\n /** Card header addition for writing proposals (after \"Proposal ·\"). */\n writesToTenant: string;\n tool: string;\n runsAfterConfirm: string;\n run: string;\n edit: string;\n discard: string;\n runRequested: string;\n editRequested: string;\n discarded: string;\n // --- Context chips ---\n /** `{tenant}` = tenant id. */\n contextTenant: string;\n /** `{page}` = page label. */\n contextPage: string;\n // --- Sessions (only with a transport that has sessions) ---\n /** Header icon button that opens the list of saved chats (tooltip + `aria-label`). */\n sessions: string;\n /** Header icon button that starts a fresh chat (tooltip + `aria-label`). */\n newChat: string;\n /** `aria-label` of the saved chats list. */\n sessionsLabel: string;\n /** Shown when there are no saved chats. */\n noSessions: string;\n /** Leaves the chat list without opening a chat. */\n backToChat: string;\n /** `aria-label` of a chat's delete button; `{title}` = chat title. */\n deleteSession: string;\n /** Inline confirmation; `{title}` = chat title. */\n deleteSessionConfirm: string;\n /** Confirms the deletion. */\n delete: string;\n cancel: string;\n /** Error row when a saved chat cannot be opened. */\n sessionLoadFailed: string;\n /** Error row when a saved chat cannot be deleted. */\n sessionDeleteFailed: string;\n // --- Attachments (only with a transport that accepts files) ---\n /** `aria-label` / tooltip of the attach button. */\n attachFile: string;\n /** `aria-label` of the attached files list. */\n attachmentsLabel: string;\n /** `aria-label` of an attachment's remove button; `{name}` = file name. */\n removeAttachment: string;\n /** `{name}` = file name. */\n attachmentWrongType: string;\n /** `{name}` = file name, `{max}` = size limit (e.g. \"10 MB\"). */\n attachmentTooLarge: string;\n /** `{max}` = most files per message. */\n attachmentTooMany: string;\n // --- Starter questions (only with a transport that provides them) ---\n /** Heading above the starter questions of an empty chat. */\n startersTitle: string;\n // --- Resizing ---\n /** `aria-label` / tooltip of the panel's resize handle. */\n resizePanel: string;\n}\n\nexport const DEFAULT_ASSISTANT_MESSAGES: AssistantMessages = {\n title: 'Assistant',\n readsWithYourPermissions: 'Reads with your permissions',\n closeAssistant: 'Close assistant',\n contextLabel: 'Context sent with your message',\n removeContext: 'Remove context {label}',\n notAvailable: 'Assistant not available',\n notConnected: 'Assistant backend not available yet',\n commandsLabel: 'Commands',\n composerLabel: 'Message the assistant',\n composerPlaceholder: 'Ask something or type / for commands…',\n send: 'Send',\n stop: 'Stop',\n greeting: 'Hi! How can I help?',\n thinking: 'Thinking…',\n conversationLabel: 'Conversation',\n youPrefix: 'You: ',\n assistantPrefix: 'Assistant: ',\n errorPrefix: 'Error: ',\n slashCommandPrefix: 'Command: ',\n slashCommandFailed: 'The command {command} could not be run.',\n proposalLabel: 'Proposal: {title}',\n proposal: 'Proposal',\n writesToTenant: 'writes to the tenant',\n tool: 'Tool',\n runsAfterConfirm: 'runs only after you confirm',\n run: 'Run',\n edit: 'Edit',\n discard: 'Discard',\n runRequested: 'Run requested',\n editRequested: 'Edit requested',\n discarded: 'Discarded',\n contextTenant: 'Tenant: {tenant}',\n contextPage: 'Page: {page}',\n sessions: 'Chats',\n newChat: 'New chat',\n sessionsLabel: 'Saved chats',\n noSessions: 'No saved chats yet',\n backToChat: 'Back to the chat',\n deleteSession: 'Delete chat {title}',\n deleteSessionConfirm: 'Delete “{title}”?',\n delete: 'Delete',\n cancel: 'Cancel',\n sessionLoadFailed: 'The chat could not be opened.',\n sessionDeleteFailed: 'The chat could not be deleted.',\n attachFile: 'Attach file',\n attachmentsLabel: 'Attached files',\n removeAttachment: 'Remove attachment {name}',\n attachmentWrongType: '{name} is not an accepted file type.',\n attachmentTooLarge: '{name} is larger than {max}.',\n attachmentTooMany: 'At most {max} file(s) per message.',\n startersTitle: 'Try asking',\n resizePanel: 'Resize assistant panel',\n};\n\n/** App-wide translations of the assistant (partial). */\nexport const ASSISTANT_MESSAGES = new InjectionToken<Partial<AssistantMessages>>('ASSISTANT_MESSAGES');\n\n/** Merges overrides over {@link DEFAULT_ASSISTANT_MESSAGES}, later sources winning; null/undefined members are ignored. */\nexport function resolveAssistantMessages(...overrides: (Partial<AssistantMessages> | null | undefined)[]): AssistantMessages {\n const resolved: AssistantMessages = { ...DEFAULT_ASSISTANT_MESSAGES };\n for (const messages of overrides) {\n if (!messages) {\n continue;\n }\n for (const key of Object.keys(messages) as (keyof AssistantMessages)[]) {\n const value = messages[key];\n if (value !== undefined && value !== null) {\n resolved[key] = value;\n }\n }\n }\n return resolved;\n}\n\n/** Replaces `{name}` placeholders; unknown placeholders stay as they are. */\nexport function formatAssistantMessage(message: string, values: Record<string, string | number>): string {\n return message.replace(/\\{(\\w+)\\}/g, (match, key: string) =>\n Object.prototype.hasOwnProperty.call(values, key) ? String(values[key]) : match);\n}\n\n/** The settled label of a proposal decision. */\nexport function proposalDecisionLabel(kind: AssistantProposalDecisionKind, messages: AssistantMessages): string {\n switch (kind) {\n case 'run': return messages.runRequested;\n case 'edit': return messages.editRequested;\n case 'discard': return messages.discarded;\n }\n}\n\n/**\n * {@link ASSISTANT_MESSAGES} merged with a component input (the input wins).\n * Call it in an injection context.\n * @internal\n */\nexport function assistantMessages(input: Signal<Partial<AssistantMessages> | null | undefined>): Signal<AssistantMessages> {\n const injected = inject(ASSISTANT_MESSAGES, { optional: true });\n return computed(() => resolveAssistantMessages(injected, input()));\n}\n","import { Injectable, inject, signal } from '@angular/core';\nimport { Observable, throwError } from 'rxjs';\nimport type { AssistantSendRequest, AssistantStreamEvent, AssistantTransport } from './assistant.models';\nimport { ASSISTANT_MESSAGES, DEFAULT_ASSISTANT_MESSAGES, resolveAssistantMessages } from './assistant.messages';\n\n/** The (English) text the panel shows while no backend exists. */\nexport const ASSISTANT_NOT_CONNECTED_MESSAGE = DEFAULT_ASSISTANT_MESSAGES.notConnected;\n\n/**\n * The default {@link AssistantTransport}: it is never `ready`, so the composer\n * cannot send, and it never produces an answer. It exists so the panel can say\n * honestly that there is no assistant backend (AB#5550) instead of faking one.\n * The message follows `ASSISTANT_MESSAGES.notConnected`.\n */\n@Injectable({ providedIn: 'root' })\nexport class NotConnectedAssistantTransport implements AssistantTransport {\n private readonly message = resolveAssistantMessages(inject(ASSISTANT_MESSAGES, { optional: true })).notConnected;\n\n readonly status = signal('unavailable' as const).asReadonly();\n readonly statusMessage = signal<string | null>(this.message).asReadonly();\n\n send(_request: AssistantSendRequest): Observable<AssistantStreamEvent> {\n return throwError(() => new Error(this.message));\n }\n}\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport type { AssistantToolCall } from './assistant.models';\n\n/**\n * Default renderer of a tool call in the thread: tool name in mono plus its status.\n * Replace it through `ASSISTANT_TOOL_CALL_COMPONENT`.\n */\n@Component({\n selector: 'mm-assistant-tool-call-row',\n template: '<span class=\"tool-name\">{{ call().toolName }}</span> <span class=\"tool-status\">{{ call().status }}</span>',\n styles: [`\n :host { display: inline-flex; gap: var(--theme-space-2, 8px); align-items: baseline; }\n .tool-name { font-family: var(--theme-font-mono, monospace); }\n .tool-status { color: var(--theme-text-secondary); }\n `],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AssistantToolCallRowComponent {\n readonly call = input.required<AssistantToolCall>();\n}\n","import { InjectionToken, Signal, Type, inject } from '@angular/core';\nimport { Observable } from 'rxjs';\nimport { NotConnectedAssistantTransport } from './not-connected.transport';\nimport { AssistantToolCallRowComponent } from './assistant-tool-call-row.component';\n\n/**\n * The single feature flag of the assistant (ui-concept §5.3, AB#5549).\n * **Off by default.** While it is off nothing assistant-related renders or binds:\n * no top-bar ✦ button, no Cmd/Ctrl+J, no \"✦ Explain\" affordances, and the command\n * palette's `?` scope only shows \"Assistant not available\".\n *\n * Enable it for a host with `{ provide: ASSISTANT_ENABLED, useValue: true }`. The host gates its\n * own affordances (top-bar toggle, Cmd/Ctrl+J, palette row) on `AssistantService.enabled`.\n * Turning it on without a real {@link ASSISTANT_TRANSPORT} shows the panel with an\n * honest \"Assistant backend not available yet\" state — never canned answers.\n */\nexport const ASSISTANT_ENABLED = new InjectionToken<boolean>('ASSISTANT_ENABLED', {\n providedIn: 'root',\n factory: () => false\n});\n\n/** Connection state of the transport; only `ready` lets the composer send. */\nexport type AssistantTransportStatus = 'unavailable' | 'ready' | 'busy' | 'error';\n\n/** Kinds of context the panel sends as structured data (ids, not DOM). */\nexport type AssistantContextKind = 'tenant' | 'page' | 'entity';\n\n/** One removable chip of the context row. */\nexport interface AssistantContextChip {\n /** Stable per value (`<kind>:<value>`) so a removed chip stays removed until the value changes. */\n id: string;\n kind: AssistantContextKind;\n /** Visible text, e.g. \"Integration › Adapters\". */\n label: string;\n /** Structured value sent to the backend: tenant id, router URL, or entity id. */\n value: string;\n /** Optional CK type of an entity chip. */\n ckTypeId?: string;\n}\n\n/** What an \"✦ Explain\" entry point asks about. */\nexport interface AssistantExplainTarget {\n /** Human readable name of the object, e.g. \"edge-plc-07\" or \"System.Communication/Adapter\". */\n label: string;\n /** Runtime id of the object, when it is an entity. */\n rtId?: string;\n /** CK type id of the object (or the type itself for \"explain this type\"). */\n ckTypeId?: string;\n /** Overrides the composer prefill; defaults to `/explain <label>`. */\n prompt?: string;\n}\n\n/** A request to open the panel. */\nexport interface AssistantOpenRequest {\n /** Prefills the composer (never sent automatically). */\n prompt?: string;\n /** Adds (or replaces) the entity chip, e.g. from an Explain entry point. */\n entity?: AssistantExplainTarget;\n}\n\n/** A write the assistant wants to perform; rendered as a proposal card. */\nexport interface AssistantProposal {\n id: string;\n title: string;\n /** Markdown-free one-liner explaining the effect. */\n description?: string;\n /** MCP tool that would run on confirmation, e.g. `deploy_adapter`. */\n toolName: string;\n /** Parameter table shown on the card. */\n parameters: { name: string; value: string }[];\n /** True when the proposal writes to the tenant (the card says so). */\n writes: boolean;\n}\n\n/**\n * A tool call the assistant made, shown as a row of the thread. Structurally compatible with\n * `AiToolCallDto` of `@meshmakers/octo-ai-console`, so its events can be passed on unchanged.\n */\nexport interface AssistantToolCall {\n readonly callId: string;\n readonly toolName: string;\n /** E.g. 'Pending' | 'Approved' | 'Rejected' | 'Succeeded' | 'Failed'. */\n readonly status: string;\n readonly sessionId?: string;\n readonly arguments?: unknown;\n readonly result?: unknown;\n readonly startedAt?: string;\n readonly completedAt?: string | null;\n readonly durationMs?: number | null;\n}\n\n/**\n * The component that renders one tool call in the thread. It must have a `call` input taking an\n * {@link AssistantToolCall}. Default: a compact name + status row. An OctoMesh host passes\n * `AiToolCallComponent` of `@meshmakers/octo-ai-console` (collapsible details):\n * `{ provide: ASSISTANT_TOOL_CALL_COMPONENT, useValue: AiToolCallComponent }`.\n */\nexport const ASSISTANT_TOOL_CALL_COMPONENT = new InjectionToken<Type<unknown>>('ASSISTANT_TOOL_CALL_COMPONENT', {\n providedIn: 'root',\n factory: () => AssistantToolCallRowComponent\n});\n\n/**\n * Labels of the active area and tab of the shell, used for the \"Page: Area › Tab\" context chip.\n * Optional; without it the page chip falls back to the first breadcrumb. With\n * `@meshmakers/shared-ui/shell`:\n *\n * ```ts\n * { provide: ASSISTANT_PAGE_CONTEXT, useFactory: () => {\n * const nav = inject(ShellNavigationService);\n * return { areaText: () => nav.activeArea()?.text ?? null, tabText: () => nav.activeTab()?.text ?? null };\n * } }\n * ```\n *\n * Read inside a computed, so signal-backed functions keep the chips up to date.\n */\nexport interface AssistantPageContext {\n areaText(): string | null;\n tabText(): string | null;\n}\n\nexport const ASSISTANT_PAGE_CONTEXT = new InjectionToken<AssistantPageContext>('ASSISTANT_PAGE_CONTEXT');\n\n/** One rendered item of the thread. */\nexport type AssistantThreadItem =\n | {\n kind: 'user';\n id: string;\n /** What was sent — for a slash command with `expand`, the expanded prompt. */\n text: string;\n attachments?: readonly AssistantAttachmentRef[];\n /**\n * The slash command as typed (e.g. `/open March`) when {@link text} is its expansion (AB#5621).\n * The thread shows it as a subtle label above the prompt. A transport may store it and return it\n * from `loadSession` so reopened chats show the label too; without it they show the prompt only.\n */\n slashCommand?: string;\n }\n | { kind: 'assistant'; id: string; markdown: string; streaming: boolean }\n | { kind: 'tool-call'; id: string; call: AssistantToolCall }\n | { kind: 'proposal'; id: string; proposal: AssistantProposal; decision: AssistantProposalDecisionKind | null }\n | { kind: 'error'; id: string; text: string };\n\nexport type AssistantProposalDecisionKind = 'run' | 'edit' | 'discard';\n\n/**\n * A decision on a proposal card. The card only emits it; whatever executes the\n * write (the backend's confirm round-trip, AB#5550) subscribes to\n * `AssistantService.proposalDecisions$`. Nothing in this library executes a proposal.\n */\nexport interface AssistantProposalDecision {\n kind: AssistantProposalDecisionKind;\n proposal: AssistantProposal;\n}\n\n/** What the composer hands to the transport. */\nexport interface AssistantSendRequest {\n /** The typed text; may be empty when the turn only carries {@link files}. */\n text: string;\n /** The chips that remained after the user removed what they did not want to share. */\n context: AssistantContextChip[];\n /**\n * Files attached in the composer. Only set when the transport declares\n * {@link AssistantTransport.attachments} and the person attached at least one file\n * (already checked against `accept`, `maxFiles` and `maxFileSizeBytes`).\n */\n files?: File[];\n /**\n * The slash command as typed (e.g. `/open March`) when {@link text} is the prompt its\n * {@link AssistantSlashCommand.expand} produced (AB#5621). `text` is always what the model should\n * read; store `text` as the turn so a reopened chat matches the live thread, and optionally keep\n * this alongside it (returned as `slashCommand` on the restored user item) for the label.\n */\n slashCommand?: string;\n}\n\n/** Name (and size) of a file sent with a user turn, shown under the turn in the thread. */\nexport interface AssistantAttachmentRef {\n name: string;\n /** Bytes, when known. */\n size?: number;\n}\n\n/**\n * File attachments a transport accepts (AB#5621). Declaring {@link AssistantTransport.attachments}\n * shows an \"Attach file\" button in the composer; without it there is no attachment UI.\n */\nexport interface AssistantAttachmentOptions {\n /**\n * Accepted types, in the syntax of `<input type=\"file\" accept>`: comma separated MIME types\n * (`application/pdf`, `image/*`) and/or extensions (`.pdf`). Empty or omitted = any type.\n */\n accept?: string;\n /** How many files one turn may carry (default 1). */\n maxFiles?: number;\n /** Largest accepted file in bytes; omitted = no limit in the UI. */\n maxFileSizeBytes?: number;\n}\n\n/** A saved conversation of the person, as listed by {@link AssistantTransport.sessions}. */\nexport interface AssistantSessionSummary {\n id: string;\n title: string;\n /** ISO 8601 timestamp; shown as a secondary line when present. */\n createdAt?: string;\n}\n\n/** Starter questions as a transport can provide them: synchronously, as a promise or as an observable (first value counts). */\nexport type AssistantStarterQuestions =\n | readonly string[]\n | Promise<readonly string[]>\n | Observable<readonly string[]>;\n\n/** A result a session method may return: a promise or an observable (its last value counts). */\nexport type AssistantAsyncResult<T> = Promise<T> | Observable<T>;\n\n/** Events a transport streams back for one send. */\nexport type AssistantStreamEvent =\n | { type: 'message-delta'; messageId: string; text: string }\n | { type: 'message-end'; messageId: string }\n | { type: 'tool-call'; call: AssistantToolCall }\n | { type: 'proposal'; proposal: AssistantProposal }\n | { type: 'error'; message: string };\n\n/**\n * Where assistant turns come from. The library ships **no** implementation that\n * answers: the default is {@link NotConnectedAssistantTransport}. A real one\n * (e.g. the OctoMesh AI services, AB#5550 delegated-identity chat sessions) provides\n * itself under {@link ASSISTANT_TRANSPORT}.\n */\nexport interface AssistantTransport {\n readonly status: Signal<AssistantTransportStatus>;\n /** Shown in the panel when the status is not `ready`. */\n readonly statusMessage: Signal<string | null>;\n /** One user turn; completes when the assistant turn is complete. */\n send(request: AssistantSendRequest): Observable<AssistantStreamEvent>;\n\n // --- Optional capabilities (AB#5621). The panel only shows the matching UI when present. ---\n\n /**\n * Accepted file attachments. When set, the composer gets an \"Attach file\" button and\n * {@link AssistantSendRequest.files} carries the files; a turn may then have empty text.\n */\n readonly attachments?: AssistantAttachmentOptions | null;\n\n /**\n * Example questions for an empty thread, in the UI language. Read each time the panel opens;\n * clicking one sends it as if it had been typed. An observable need not complete: its first\n * emitted value is taken (later emissions are ignored until the next opening).\n */\n starterQuestions?(): AssistantStarterQuestions;\n\n /**\n * Saved sessions of the signed-in person, newest first. Together with {@link loadSession} it\n * enables the panel's chat list (\"Chats\" and \"New chat\" in the header).\n */\n readonly sessions?: Signal<readonly AssistantSessionSummary[]>;\n /** The session the next send writes to; `null` = a fresh chat. Marks the current row in the list. */\n readonly activeSessionId?: Signal<string | null>;\n /** Reloads {@link sessions}; called when the chat list is opened. */\n refreshSessions?(): AssistantAsyncResult<void>;\n /** Makes a saved session active and returns its thread. */\n loadSession?(id: string): AssistantAsyncResult<AssistantThreadItem[]>;\n /** Deletes a saved session. Without it the chat list has no delete buttons. */\n deleteSession?(id: string): AssistantAsyncResult<void>;\n /** Starts a fresh chat: the next send creates a new session. */\n newSession?(): void;\n}\n\n/** The assistant's transport; defaults to the honest \"not connected\" one. */\nexport const ASSISTANT_TRANSPORT = new InjectionToken<AssistantTransport>('ASSISTANT_TRANSPORT', {\n providedIn: 'root',\n factory: () => inject(NotConnectedAssistantTransport)\n});\n\n/** A composer slash command (ui-concept §5.3). */\nexport interface AssistantSlashCommand {\n /** The command word with its slash, lower-case, e.g. `/explain`. */\n command: string;\n description: string;\n /**\n * Turns the typed command into the prompt that is sent (AB#5621). Called by\n * `AssistantService.send` when the text is `<command>` or `<command> <args>`: `command` is this\n * command's word, `args` the trimmed rest (`''` when none). The returned text — synchronously or\n * as a promise — is what goes to the transport **and** what the live thread shows (with the typed\n * command as a small label), so a chat reopened from the transport reads the same.\n *\n * If it throws, rejects or returns an empty text, nothing is sent: an error row is added and the\n * draft is restored. Without `expand` the typed text is sent unchanged (default behaviour).\n *\n * ```ts\n * { command: '/open', description: 'Open items',\n * expand: (_command, args) => args ? `Which items are open for ${args}?` : 'Which items are open?' }\n * ```\n */\n expand?: (command: string, args: string) => string | Promise<string>;\n}\n\n/** The default slash commands (English descriptions). */\nexport const DEFAULT_ASSISTANT_SLASH_COMMANDS: readonly AssistantSlashCommand[] = [\n { command: '/explain', description: 'Explain the object in context' },\n { command: '/query', description: 'Turn a question into a query' },\n { command: '/summarise', description: 'Summarise events or a selection' },\n { command: '/draft-pipeline', description: 'Draft a pipeline as a diff' }\n];\n\n/** The composer's slash commands; provide your own list (or translated descriptions) to change them. */\nexport const ASSISTANT_SLASH_COMMANDS = new InjectionToken<readonly AssistantSlashCommand[]>('ASSISTANT_SLASH_COMMANDS', {\n providedIn: 'root',\n factory: () => DEFAULT_ASSISTANT_SLASH_COMMANDS\n});\n\n/**\n * Layout of `mm-assistant-panel` (AB#5621); every member is optional and the panel's inputs of the\n * same name win. Defaults keep the original look: a docked panel 400 px wide (340 px ≤ 1180 px)\n * that pushes the content, without a resize handle (opt in with `resizable: true`).\n */\nexport interface AssistantPanelOptions {\n /**\n * `docked` (default): the panel takes its own column and pushes the content.\n * `overlay`: it floats over the content at the right edge (`position: fixed`), from\n * `--mm-assistant-overlay-top` (default 48 px, the shell's top bar) to the bottom.\n */\n mode?: AssistantPanelMode;\n /**\n * Shows the drag handle on the left edge (default `false`: no handle, no extra tab stop; never on\n * phones). Only with it on does a persisted width apply.\n */\n resizable?: boolean;\n /** Smallest width in px the handle allows (default {@link DEFAULT_ASSISTANT_PANEL_MIN_WIDTH}). */\n minWidth?: number;\n /**\n * Largest width in px the handle allows (default {@link DEFAULT_ASSISTANT_PANEL_MAX_WIDTH});\n * further capped so at least 240 px of the window stay free.\n */\n maxWidth?: number;\n /**\n * `localStorage` key of the width the person chose (default\n * {@link DEFAULT_ASSISTANT_PANEL_STORAGE_KEY}); `null` = do not persist. Storage that is missing or\n * throws (private mode, blocked site data) is ignored — the width then lasts as long as the panel.\n */\n storageKey?: string | null;\n}\n\nexport type AssistantPanelMode = 'docked' | 'overlay';\n\nexport const DEFAULT_ASSISTANT_PANEL_MIN_WIDTH = 320;\nexport const DEFAULT_ASSISTANT_PANEL_MAX_WIDTH = 720;\nexport const DEFAULT_ASSISTANT_PANEL_STORAGE_KEY = 'mm-assistant-panel-width';\n\n/** App-wide {@link AssistantPanelOptions}; optional. */\nexport const ASSISTANT_PANEL_OPTIONS = new InjectionToken<AssistantPanelOptions>('ASSISTANT_PANEL_OPTIONS');\n","import { ActivatedRouteSnapshot } from '@angular/router';\nimport { AssistantContextChip, AssistantExplainTarget } from './assistant.models';\nimport { AssistantMessages, formatAssistantMessage, resolveAssistantMessages } from './assistant.messages';\n\n/** Route params that name the object a page shows (detail pages, editors). */\nconst ENTITY_PARAM = /^(rtId|id|[a-zA-Z]+Id|userName)$/;\n/** Params that are scope, not the object. */\nconst SCOPE_PARAMS = new Set(['tenantId']);\n\n/** Inputs of {@link deriveAssistantContext}, all read from the shell. */\nexport interface AssistantContextSource {\n /** Root of the router state snapshot. */\n root: ActivatedRouteSnapshot | null | undefined;\n /** Router URL of the page (query and fragment are dropped). */\n url: string;\n /** Breadcrumb labels of the page, root first. */\n breadcrumbs: string[];\n /** Active rail area and tab (see `ASSISTANT_PAGE_CONTEXT`). */\n areaText?: string | null;\n tabText?: string | null;\n /** Entity set explicitly by an Explain entry point; wins over the route. */\n explicitEntity?: AssistantExplainTarget | null;\n}\n\n/**\n * Turns the current route into the panel's context chips (ui-concept §5.3):\n * tenant, page (\"Area › Tab\", else the breadcrumb) and the selected entity — the\n * one an Explain entry point named, otherwise the deepest id-like route param\n * (labelled with the last breadcrumb). Pure, so it is tested without a router.\n */\nexport function deriveAssistantContext(\n source: AssistantContextSource,\n messages?: Partial<AssistantMessages> | null\n): AssistantContextChip[] {\n const m = resolveAssistantMessages(messages);\n const params = collectParams(source.root);\n const chips: AssistantContextChip[] = [];\n\n const tenantId = params.get('tenantId');\n if (tenantId) {\n chips.push({ id: `tenant:${tenantId}`, kind: 'tenant', label: formatAssistantMessage(m.contextTenant, { tenant: tenantId }), value: tenantId });\n }\n\n const path = source.url.split('#')[0].split('?')[0];\n const pageLabel = source.areaText && source.tabText && source.tabText !== source.areaText\n ? `${source.areaText} › ${source.tabText}`\n : source.tabText ?? source.areaText ?? source.breadcrumbs[0] ?? null;\n if (pageLabel && path) {\n chips.push({ id: `page:${path}`, kind: 'page', label: formatAssistantMessage(m.contextPage, { page: pageLabel }), value: path });\n }\n\n const explicit = source.explicitEntity;\n if (explicit) {\n const value = explicit.rtId ?? explicit.ckTypeId ?? explicit.label;\n chips.push({\n id: `entity:${value}`, kind: 'entity', label: explicit.label, value,\n ...(explicit.ckTypeId ? { ckTypeId: explicit.ckTypeId } : {})\n });\n return chips;\n }\n\n const entity = [...params.entries()].reverse().find(([name]) => !SCOPE_PARAMS.has(name) && ENTITY_PARAM.test(name));\n if (entity) {\n const [, value] = entity;\n const crumbs = source.breadcrumbs;\n const label = crumbs.length > 1 ? crumbs[crumbs.length - 1] : value;\n chips.push({ id: `entity:${value}`, kind: 'entity', label, value });\n }\n return chips;\n}\n\n/** Params from the root to the deepest primary child, in that order (later wins on clashes). */\nfunction collectParams(root: ActivatedRouteSnapshot | null | undefined): Map<string, string> {\n const params = new Map<string, string>();\n let node: ActivatedRouteSnapshot | null | undefined = root;\n while (node) {\n for (const [name, value] of Object.entries(node.params ?? {})) {\n if (typeof value === 'string' && value) {\n params.delete(name);\n params.set(name, value);\n }\n }\n node = node.firstChild;\n }\n return params;\n}\n","import { DestroyRef, Injectable, Signal, computed, inject, signal } from '@angular/core';\nimport { NavigationEnd, Router } from '@angular/router';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { BreadCrumbService } from '@meshmakers/shared-services';\nimport { Observable, Subject, Subscription, firstValueFrom, isObservable, lastValueFrom } from 'rxjs';\nimport { filter } from 'rxjs/operators';\nimport { deriveAssistantContext } from './assistant-context';\nimport { ASSISTANT_MESSAGES, formatAssistantMessage, resolveAssistantMessages } from './assistant.messages';\nimport {\n ASSISTANT_ENABLED,\n ASSISTANT_SLASH_COMMANDS,\n AssistantSlashCommand,\n ASSISTANT_PAGE_CONTEXT,\n AssistantPageContext,\n ASSISTANT_TRANSPORT,\n AssistantContextChip,\n AssistantExplainTarget,\n AssistantOpenRequest,\n AssistantProposal,\n AssistantProposalDecision,\n AssistantProposalDecisionKind,\n AssistantAsyncResult,\n AssistantAttachmentOptions,\n AssistantSendRequest,\n AssistantSessionSummary,\n AssistantStreamEvent,\n AssistantThreadItem\n} from './assistant.models';\n\nconst NO_SESSIONS = signal<readonly AssistantSessionSummary[]>([]).asReadonly();\nconst NO_ACTIVE_SESSION = signal<string | null>(null).asReadonly();\n\n/** Awaits a promise or the last value of an observable; an observable that completes empty (e.g. `EMPTY` for a void result) yields `undefined` instead of rejecting. */\n/** `/word rest` → the word (lower-case) and the trimmed rest; anything else → null. */\nfunction parseSlashCommand(text: string): { word: string; args: string } | null {\n const match = /^(\\/[\\w-]+)(?:\\s+([\\s\\S]*))?$/.exec(text);\n return match ? { word: match[1].toLowerCase(), args: (match[2] ?? '').trim() } : null;\n}\n\nfunction settle<T>(result: AssistantAsyncResult<T>): Promise<T | undefined> {\n return isObservable(result) ? lastValueFrom(result, { defaultValue: undefined }) : result;\n}\n\n/**\n * State and entry points of the assistant panel (ui-concept §5.3, AB#5549).\n *\n * - **Flag.** Everything is gated by {@link ASSISTANT_ENABLED} (off by default):\n * while it is off every entry point is a no-op that returns `false`, and the\n * service does not even listen to the router.\n * - **Entry points.** {@link open} (top-bar ✦, Cmd/Ctrl+J, palette `?` scope),\n * {@link requestExplain} (\"✦ Explain <object>\", AB#5545/5547), {@link toggle}.\n * They open the panel with a prefilled composer and context; they never send.\n * - **Thread.** Survives closing the panel and navigating. Items only come from the\n * {@link ASSISTANT_TRANSPORT}; the default transport is not connected, so the\n * library itself never adds an assistant turn.\n * - **Context.** Tenant (route param `tenantId`), page (`ASSISTANT_PAGE_CONTEXT`, else the first\n * breadcrumb of shared-services' `BreadCrumbService`) and entity chips; see {@link deriveAssistantContext}.\n * - **Proposals.** Run / Edit / Discard are published on {@link proposalDecisions$}\n * and nothing else — executing a write is the backend's confirm round-trip (AB#5550).\n * - **Optional transport capabilities (AB#5621).** Sessions ({@link sessionsSupported},\n * {@link openSession}, {@link deleteSession}, {@link newThread}), file attachments\n * ({@link attachments}, {@link draftFiles}) and starter questions ({@link starterQuestions}) are\n * only offered when the transport implements them; otherwise they are inert.\n * - **Slash commands (AB#5621).** A command of `ASSISTANT_SLASH_COMMANDS` with `expand` is sent as\n * the prompt it returns; see {@link send}.\n */\n@Injectable({ providedIn: 'root' })\nexport class AssistantService {\n /** The feature flag. Read it to gate any assistant affordance. */\n readonly enabled = inject(ASSISTANT_ENABLED);\n\n private readonly transport = inject(ASSISTANT_TRANSPORT);\n private readonly router = inject(Router);\n private readonly destroyRef = inject(DestroyRef);\n /** Only resolved while enabled: a disabled assistant binds nothing. */\n private readonly pageContext: AssistantPageContext | null = null;\n private readonly messages = inject(ASSISTANT_MESSAGES, { optional: true });\n private readonly slashCommands: readonly AssistantSlashCommand[] = inject(ASSISTANT_SLASH_COMMANDS);\n\n private readonly _isOpen = signal(false);\n private readonly _draft = signal('');\n private readonly _focusRequest = signal(0);\n private readonly _explicitEntity = signal<AssistantExplainTarget | null>(null);\n private readonly _removedChips = signal<ReadonlySet<string>>(new Set());\n private readonly _thread = signal<AssistantThreadItem[]>([]);\n private readonly _sending = signal(false);\n private readonly _draftFiles = signal<readonly File[]>([]);\n private readonly _starterQuestions = signal<readonly string[]>([]);\n private starterRequest = 0;\n /** Bumped by every thread switch (open session, new chat, loadThread); stale session loads are dropped. */\n private threadGeneration = 0;\n private readonly _routeTick = signal(0);\n private readonly _breadcrumbs = signal<string[]>([]);\n private readonly decisions = new Subject<AssistantProposalDecision>();\n private returnFocusTo: HTMLElement | null = null;\n private pending: Subscription | null = null;\n private itemCounter = 0;\n /** Bumped by {@link stop}: an async slash-command expansion that resolves later is dropped. */\n private expansionGeneration = 0;\n\n /** Whether the panel is shown. */\n readonly isOpen = this._isOpen.asReadonly();\n /** Composer text; prefilled by entry points. */\n readonly draft = this._draft.asReadonly();\n /** Bumped whenever an entry point wants the composer focused. */\n readonly focusRequest = this._focusRequest.asReadonly();\n /** The rendered thread. */\n readonly thread = this._thread.asReadonly();\n /** A turn is streaming. */\n readonly sending = this._sending.asReadonly();\n readonly transportStatus = this.transport.status;\n readonly transportMessage = this.transport.statusMessage;\n /** The composer may send: the transport is ready and no turn is running. */\n readonly canSend = computed(() => this.transport.status() === 'ready' && !this._sending());\n\n /** The transport has saved sessions (`sessions` + `loadSession`): the panel shows its chat list. */\n readonly sessionsSupported = !!this.transport.sessions && typeof this.transport.loadSession === 'function';\n /** Saved sessions can be deleted (`deleteSession`). */\n readonly sessionDeleteSupported = this.sessionsSupported && typeof this.transport.deleteSession === 'function';\n /** Saved sessions of the transport (empty without session support). */\n readonly sessions: Signal<readonly AssistantSessionSummary[]> = this.transport.sessions ?? NO_SESSIONS;\n /** The session the next send writes to (`null` = fresh chat or no session support). */\n readonly activeSessionId: Signal<string | null> = this.transport.activeSessionId ?? NO_ACTIVE_SESSION;\n\n /** Accepted attachments, or `null` when the transport takes no files (no attach UI). */\n readonly attachments: AssistantAttachmentOptions | null = this.transport.attachments ?? null;\n /** Files attached in the composer; sent and cleared with the next turn. */\n readonly draftFiles = this._draftFiles.asReadonly();\n\n /** Starter questions for an empty thread (see {@link loadStarterQuestions}). */\n readonly starterQuestions = this._starterQuestions.asReadonly();\n\n /** Context of the current page minus the chips the person removed. */\n readonly contextChips: Signal<AssistantContextChip[]> = computed(() => {\n this._routeTick();\n const removed = this._removedChips();\n return deriveAssistantContext({\n root: this.router.routerState?.snapshot?.root,\n url: this.router.url ?? '',\n breadcrumbs: this._breadcrumbs(),\n areaText: this.pageContext?.areaText() ?? null,\n tabText: this.pageContext?.tabText() ?? null,\n explicitEntity: this._explicitEntity()\n }, this.messages).filter(chip => !removed.has(chip.id));\n });\n\n /** Run / Edit / Discard on proposal cards. Only emitted, never executed here. */\n readonly proposalDecisions$: Observable<AssistantProposalDecision> = this.decisions.asObservable();\n\n constructor() {\n if (!this.enabled) {\n return;\n }\n this.pageContext = inject(ASSISTANT_PAGE_CONTEXT, { optional: true });\n inject(BreadCrumbService).breadCrumbItems.pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(items => this._breadcrumbs.set(items.map(item => item.text ?? '').filter(text => text.length > 0)));\n this.router.events.pipe(filter(event => event instanceof NavigationEnd), takeUntilDestroyed(this.destroyRef))\n .subscribe(() => {\n // An explicit Explain target belongs to the page it was requested on.\n this._explicitEntity.set(null);\n this._routeTick.update(tick => tick + 1);\n });\n this.destroyRef.onDestroy(() => this.pending?.unsubscribe());\n }\n\n /** Opens the panel (or re-focuses it) with an optional prefill. Returns false while disabled. */\n open(request: AssistantOpenRequest = {}): boolean {\n if (!this.enabled) {\n return false;\n }\n if (!this._isOpen()) {\n const active = document.activeElement;\n this.returnFocusTo = active instanceof HTMLElement && active !== document.body ? active : null;\n }\n if (request.entity) {\n this._explicitEntity.set(request.entity);\n this._removedChips.update(removed => removed.size ? new Set() : removed);\n }\n if (request.prompt !== undefined) {\n this._draft.set(request.prompt);\n }\n this._isOpen.set(true);\n this._focusRequest.update(count => count + 1);\n return true;\n }\n\n /** \"✦ Explain <object>\": opens the panel with `/explain <label>` and the object as context chip. */\n requestExplain(target: AssistantExplainTarget): boolean {\n return this.open({ prompt: target.prompt ?? `/explain ${target.label}`, entity: target });\n }\n\n /** Hides the panel and gives focus back to where it was (the ✦ button if that is gone). */\n close(): void {\n if (!this._isOpen()) {\n return;\n }\n this._isOpen.set(false);\n const target = this.returnFocusTo?.isConnected\n ? this.returnFocusTo\n : document.querySelector<HTMLElement>('[data-assistant-toggle]');\n this.returnFocusTo = null;\n target?.focus();\n }\n\n /**\n * Forgets an open panel without moving focus — the host calls it when the\n * panel can no longer be shown (tenant left or denied, connection lost), so it\n * does not pop up again later with a stale return-focus target.\n */\n dismiss(): void {\n this._isOpen.set(false);\n this.returnFocusTo = null;\n }\n\n /** Opens when closed, closes when open. Returns false while disabled. */\n toggle(): boolean {\n if (!this.enabled) {\n return false;\n }\n if (this._isOpen()) {\n this.close();\n } else {\n this.open();\n }\n return true;\n }\n\n setDraft(text: string): void {\n this._draft.set(text);\n }\n\n /** Replaces the attached files (ignored while the transport takes no files). */\n setDraftFiles(files: readonly File[]): void {\n if (this.attachments) {\n this._draftFiles.set([...files]);\n }\n }\n\n /**\n * Asks the transport for its starter questions (the panel calls it when it opens).\n * No-op without `starterQuestions`; a failing source leaves the list empty. Of an observable\n * only the first emitted value counts (it need not complete); one that completes empty yields none.\n */\n loadStarterQuestions(): void {\n const source = this.transport.starterQuestions;\n if (!this.enabled || typeof source !== 'function') {\n return;\n }\n const request = ++this.starterRequest;\n const accept = (questions: readonly string[] | null | undefined): void => {\n if (request === this.starterRequest) {\n this._starterQuestions.set((questions ?? []).filter(q => typeof q === 'string' && q.trim().length > 0));\n }\n };\n try {\n const result = source.call(this.transport);\n if (Array.isArray(result)) {\n accept(result);\n } else if (isObservable(result)) {\n // The first emitted value counts, so a never-completing source (BehaviorSubject, signal stream) works too.\n firstValueFrom(result as Observable<readonly string[]>, { defaultValue: [] as readonly string[] }).then(accept, () => accept([]));\n } else {\n (result as Promise<readonly string[]>).then(accept, () => accept([]));\n }\n } catch {\n accept([]);\n }\n }\n\n /** Reloads the transport's session list. Resolves false without session support or on failure. */\n async refreshSessions(): Promise<boolean> {\n if (!this.enabled || !this.sessionsSupported || typeof this.transport.refreshSessions !== 'function') {\n return false;\n }\n try {\n await settle(this.transport.refreshSessions());\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Opens a saved session: stops a running turn, asks the transport for the session's thread and\n * shows it. On failure the current thread stays and an error row is added. Resolves whether the\n * session was opened.\n */\n async openSession(id: string): Promise<boolean> {\n if (!this.enabled || !this.sessionsSupported) {\n return false;\n }\n this.stop();\n const generation = ++this.threadGeneration;\n try {\n const items = await settle(this.transport.loadSession!(id));\n if (generation !== this.threadGeneration) {\n // Another session was opened (or a new chat started) meanwhile: that one wins.\n return false;\n }\n this.loadThread(items ?? []);\n return true;\n } catch {\n if (generation === this.threadGeneration) {\n this.append({ kind: 'error', id: this.nextId('error'), text: resolveAssistantMessages(this.messages).sessionLoadFailed });\n }\n return false;\n }\n }\n\n /**\n * Deletes a saved session; deleting the active one leaves an empty thread. On failure an error\n * row is added. Resolves whether it was deleted.\n */\n async deleteSession(id: string): Promise<boolean> {\n if (!this.enabled || !this.sessionDeleteSupported) {\n return false;\n }\n const wasActive = this.activeSessionId() === id;\n const generation = this.threadGeneration;\n try {\n await settle(this.transport.deleteSession!(id));\n } catch {\n this.append({ kind: 'error', id: this.nextId('error'), text: resolveAssistantMessages(this.messages).sessionDeleteFailed });\n return false;\n }\n // Only clear when the thread still shows the deleted session (no switch while deleting).\n if (wasActive && generation === this.threadGeneration) {\n this.stop();\n this.threadGeneration += 1;\n this._thread.set([]);\n }\n return true;\n }\n\n /**\n * Starts a fresh chat: stops a running turn, empties the thread and the attached files and tells\n * the transport (`newSession`, when it has one). Works without session support too.\n */\n newThread(): void {\n if (!this.enabled) {\n return;\n }\n this.stop();\n this.threadGeneration += 1;\n this._thread.set([]);\n this._draftFiles.set([]);\n this.transport.newSession?.();\n this.loadStarterQuestions();\n }\n\n /** Replaces the thread, e.g. with a conversation the host restored itself. Stops a running turn. */\n loadThread(items: readonly AssistantThreadItem[]): void {\n if (!this.enabled) {\n return;\n }\n this.stop();\n this.threadGeneration += 1;\n this._thread.set([...items]);\n }\n\n /** Drops a context chip; it stays dropped until its value changes. */\n removeChip(id: string): void {\n this._removedChips.update(removed => new Set(removed).add(id));\n }\n\n /**\n * Sends one user turn through the transport. Does nothing (returns false) unless\n * the transport is `ready` — the default transport never is.\n *\n * With a transport that takes attachments, `files` (default: {@link draftFiles}) go along and\n * the text may be empty; the attached files are cleared with the draft. Explicitly passed `files`\n * are not checked again against {@link attachments} (`accept`, `maxFiles`, `maxFileSizeBytes`) —\n * the composer validates on pick; a host passing files itself is responsible for them.\n *\n * **Slash commands (AB#5621).** When the text is `<command> [args]` and that command of\n * `ASSISTANT_SLASH_COMMANDS` has `expand`, its result is sent instead and shown as the user turn,\n * with the typed text as `slashCommand` (label in the thread, also on the send request). A\n * promise-returning `expand` makes the turn start once it resolves (the composer is busy and Stop\n * cancels meanwhile); returns true when the expansion started. If `expand` throws, rejects or yields\n * an empty prompt, nothing is sent: an error row is added and the draft (text and files) comes back.\n */\n send(text: string, files?: readonly File[]): boolean {\n const trimmed = text.trim();\n const attached = this.attachments ? [...(files ?? this._draftFiles())] : [];\n if (!this.enabled || (!trimmed && !attached.length) || !this.canSend()) {\n return false;\n }\n const parsed = parseSlashCommand(trimmed);\n const command = parsed ? this.slashCommands.find(c => c.command.toLowerCase() === parsed.word && typeof c.expand === 'function') : undefined;\n if (!parsed || !command) {\n this._draft.set('');\n this._draftFiles.set([]);\n this.startTurn(trimmed, attached);\n return true;\n }\n\n const restoreDraft = (): void => {\n if (!this._draft()) {\n this._draft.set(text);\n }\n if (this.attachments && !this._draftFiles().length) {\n this._draftFiles.set(attached);\n }\n };\n const fail = (): void => {\n this.append({\n kind: 'error', id: this.nextId('error'),\n text: formatAssistantMessage(resolveAssistantMessages(this.messages).slashCommandFailed, { command: command.command })\n });\n restoreDraft();\n };\n const accept = (prompt: unknown): boolean => {\n const expanded = typeof prompt === 'string' ? prompt.trim() : '';\n if (!expanded) {\n fail();\n return false;\n }\n this.startTurn(expanded, attached, trimmed);\n return true;\n };\n\n let result: string | Promise<string>;\n try {\n result = command.expand!(command.command, parsed.args);\n } catch {\n fail();\n return false;\n }\n this._draft.set('');\n this._draftFiles.set([]);\n if (typeof result === 'string' || !result || typeof (result as Promise<string>).then !== 'function') {\n return accept(result);\n }\n // Async: busy until the prompt is there; stop() (or a thread switch) drops it.\n const generation = ++this.expansionGeneration;\n this._sending.set(true);\n (result as Promise<string>).then(\n prompt => {\n if (generation === this.expansionGeneration) {\n this._sending.set(false);\n accept(prompt);\n }\n },\n () => {\n if (generation === this.expansionGeneration) {\n this._sending.set(false);\n fail();\n }\n });\n return true;\n }\n\n /** Stops the running turn (the composer's stop button), including a pending slash-command expansion. */\n stop(): void {\n this.expansionGeneration += 1;\n this.pending?.unsubscribe();\n this.finishTurn();\n }\n\n /**\n * Records a decision on a proposal card and publishes it on\n * {@link proposalDecisions$}. Run and Discard settle the card; Edit leaves it open.\n * Nothing is executed here.\n */\n decideProposal(kind: AssistantProposalDecisionKind, proposal: AssistantProposal): void {\n if (kind !== 'edit') {\n this._thread.update(items => items.map(item =>\n item.kind === 'proposal' && item.proposal.id === proposal.id ? { ...item, decision: kind } : item));\n }\n this.decisions.next({ kind, proposal });\n }\n\n /** Appends the user turn and streams the transport's answer. */\n private startTurn(text: string, attached: File[], slashCommand?: string): void {\n const user: Extract<AssistantThreadItem, { kind: 'user' }> = { kind: 'user', id: this.nextId('user'), text };\n if (attached.length) {\n user.attachments = attached.map(file => ({ name: file.name, size: file.size }));\n }\n if (slashCommand !== undefined) {\n user.slashCommand = slashCommand;\n }\n this.append(user);\n this._sending.set(true);\n const request: AssistantSendRequest = { text, context: this.contextChips() };\n if (attached.length) {\n request.files = attached;\n }\n if (slashCommand !== undefined) {\n request.slashCommand = slashCommand;\n }\n this.pending = this.transport.send(request).subscribe({\n next: event => this.apply(event),\n error: (error: unknown) => {\n this.append({ kind: 'error', id: this.nextId('error'), text: error instanceof Error ? error.message : String(error) });\n this.finishTurn();\n },\n complete: () => this.finishTurn()\n });\n }\n\n private apply(event: AssistantStreamEvent): void {\n switch (event.type) {\n case 'message-delta': {\n const id = `assistant:${event.messageId}`;\n const existing = this._thread().find(item => item.id === id);\n if (existing?.kind === 'assistant') {\n this._thread.update(items => items.map(item =>\n item.id === id && item.kind === 'assistant' ? { ...item, markdown: item.markdown + event.text } : item));\n } else {\n this.append({ kind: 'assistant', id, markdown: event.text, streaming: true });\n }\n break;\n }\n case 'message-end':\n this.endMessage(`assistant:${event.messageId}`);\n break;\n case 'tool-call': {\n const id = `tool:${event.call.callId}`;\n if (this._thread().some(item => item.id === id)) {\n this._thread.update(items => items.map(item => item.id === id ? { ...item, call: event.call } as AssistantThreadItem : item));\n } else {\n this.append({ kind: 'tool-call', id, call: event.call });\n }\n break;\n }\n case 'proposal':\n this.append({ kind: 'proposal', id: `proposal:${event.proposal.id}`, proposal: event.proposal, decision: null });\n break;\n case 'error':\n this.append({ kind: 'error', id: this.nextId('error'), text: event.message });\n break;\n }\n }\n\n private finishTurn(): void {\n this.pending = null;\n this._sending.set(false);\n this._thread.update(items => items.map(item =>\n item.kind === 'assistant' && item.streaming ? { ...item, streaming: false } : item));\n }\n\n private endMessage(id: string): void {\n this._thread.update(items => items.map(item =>\n item.id === id && item.kind === 'assistant' ? { ...item, streaming: false } : item));\n }\n\n private append(item: AssistantThreadItem): void {\n this._thread.update(items => [...items, item]);\n }\n\n private nextId(prefix: string): string {\n this.itemCounter += 1;\n return `${prefix}:${this.itemCounter}`;\n }\n}\n\n/**\n * Cmd+J (macOS) / Ctrl+J toggles the assistant panel (ui-concept §4.3), also\n * from text fields — it types nothing. Events another handler consumed and\n * IME composition are ignored.\n */\nexport function assistantHotkey(event: KeyboardEvent): boolean {\n return !event.defaultPrevented && !event.isComposing && event.key?.toLowerCase() === 'j'\n && (event.metaKey || event.ctrlKey) && !event.altKey && !event.shiftKey;\n}\n","import { signal } from '@angular/core';\nimport { Observable, Subject } from 'rxjs';\nimport { AssistantSendRequest, AssistantStreamEvent, AssistantTransport, AssistantTransportStatus } from '../assistant.models';\n\n/**\n * Test double for {@link AssistantTransport} (specs only — never provided by the app).\n * Each `send` returns a Subject the spec drives with `emit` / `complete`.\n */\nexport class FakeAssistantTransport implements AssistantTransport {\n readonly status = signal<AssistantTransportStatus>('ready');\n readonly statusMessage = signal<string | null>(null);\n readonly requests: AssistantSendRequest[] = [];\n private turn: Subject<AssistantStreamEvent> | null = null;\n\n send(request: AssistantSendRequest): Observable<AssistantStreamEvent> {\n this.requests.push(request);\n this.turn = new Subject<AssistantStreamEvent>();\n return this.turn.asObservable();\n }\n\n emit(event: AssistantStreamEvent): void {\n this.turn?.next(event);\n }\n\n fail(error: Error): void {\n this.turn?.error(error);\n }\n\n complete(): void {\n this.turn?.complete();\n }\n}\n","import type { AssistantAttachmentOptions } from './assistant.models';\nimport { AssistantMessages, formatAssistantMessage } from './assistant.messages';\n\n/** Result of {@link selectAssistantAttachments}. */\nexport interface AssistantAttachmentSelection {\n /** The files that stay attached (previous ones first). */\n files: File[];\n /** One translated message per rejected file (or one for \"too many\"). */\n errors: string[];\n}\n\n/** \"512 B\", \"1.5 KB\", \"10 MB\" — for the size-limit message. */\nexport function formatAssistantFileSize(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`;\n }\n const units = ['KB', 'MB', 'GB'];\n let value = bytes / 1024;\n let unit = 0;\n while (value >= 1024 && unit < units.length - 1) {\n value /= 1024;\n unit += 1;\n }\n return `${Number.isInteger(value) ? value : value.toFixed(1)} ${units[unit]}`;\n}\n\n/**\n * Whether a file matches an `accept` list (`<input accept>` syntax: MIME types, `type/*`\n * wildcards and `.ext` extensions, comma separated). An empty list accepts everything.\n */\nexport function assistantFileAccepted(file: Pick<File, 'name' | 'type'>, accept: string | undefined): boolean {\n const patterns = (accept ?? '').split(',').map(p => p.trim().toLowerCase()).filter(p => p.length > 0);\n if (!patterns.length) {\n return true;\n }\n const name = file.name.toLowerCase();\n const type = (file.type ?? '').toLowerCase();\n return patterns.some(pattern => {\n if (pattern.startsWith('.')) {\n return name.endsWith(pattern);\n }\n if (pattern.endsWith('/*')) {\n return type.startsWith(pattern.slice(0, -1));\n }\n return type === pattern;\n });\n}\n\n/**\n * Adds newly picked files to the already attached ones, enforcing the transport's\n * {@link AssistantAttachmentOptions}: wrong type and too large files are rejected individually,\n * files beyond `maxFiles` (default 1) are dropped with one \"too many\" message. With\n * `maxFiles: 1` a newly picked valid file replaces the attached one. Pure.\n */\nexport function selectAssistantAttachments(\n current: readonly File[],\n added: readonly File[],\n options: AssistantAttachmentOptions,\n messages: AssistantMessages\n): AssistantAttachmentSelection {\n const maxFiles = Math.max(1, options.maxFiles ?? 1);\n let files = [...current];\n if (maxFiles === 1 && added.length === 1) {\n files = [];\n }\n const errors: string[] = [];\n let tooMany = false;\n for (const file of added) {\n if (!assistantFileAccepted(file, options.accept)) {\n errors.push(formatAssistantMessage(messages.attachmentWrongType, { name: file.name }));\n } else if (options.maxFileSizeBytes !== undefined && file.size > options.maxFileSizeBytes) {\n errors.push(formatAssistantMessage(messages.attachmentTooLarge,\n { name: file.name, max: formatAssistantFileSize(options.maxFileSizeBytes) }));\n } else if (files.length >= maxFiles) {\n tooMany = true;\n } else {\n files.push(file);\n }\n }\n if (maxFiles === 1 && added.length === 1 && !files.length) {\n files = [...current];\n }\n if (tooMany) {\n errors.push(formatAssistantMessage(messages.attachmentTooMany, { max: maxFiles }));\n }\n return { files, errors };\n}\n","import { Directive, TemplateRef, ViewContainerRef, inject, input } from '@angular/core';\nimport { AssistantService } from './assistant.service';\nimport { AssistantExplainTarget } from './assistant.models';\n\n/**\n * Renders its template only while the assistant is enabled — with the flag off\n * the element is not in the DOM at all. Use it on every AI affordance:\n *\n * ```html\n * <button *mmIfAssistant type=\"button\" class=\"ai-action\"\n * [mmAssistantExplain]=\"{ label: adapter.name, rtId: adapter.rtId, ckTypeId: 'System.Communication/Adapter' }\">\n * ✦ Explain\n * </button>\n * ```\n */\n@Directive({ selector: '[mmIfAssistant]' })\nexport class IfAssistantDirective {\n constructor() {\n if (inject(AssistantService).enabled) {\n inject(ViewContainerRef).createEmbeddedView(inject(TemplateRef));\n }\n }\n}\n\n/**\n * \"✦ Explain <object>\" entry point (ui-concept §5.4): a click opens the assistant\n * panel with `/explain <label>` in the composer and the object as context chip.\n * Nothing is sent. Pair it with {@link IfAssistantDirective} so the trigger does\n * not exist while the assistant is disabled; code without a template (a\n * `CommandItem.onClick`) calls `AssistantService.requestExplain()` instead.\n */\n@Directive({\n selector: '[mmAssistantExplain]',\n host: {\n '(click)': 'explain()',\n '[attr.aria-controls]': 'assistant.isOpen() ? \"assistant-panel\" : null'\n }\n})\nexport class AssistantExplainDirective {\n protected readonly assistant = inject(AssistantService);\n\n readonly target = input.required<AssistantExplainTarget>({ alias: 'mmAssistantExplain' });\n\n protected explain(): void {\n this.assistant.requestExplain(this.target());\n }\n}\n","/*\n * Public API Surface of @meshmakers/shared-ui/assistant-core (AB#5621)\n */\n\n/**\n * The startup part of the assistant: state ({@link AssistantService}), the Cmd/Ctrl+J hotkey,\n * the injection tokens with their defaults, the \"not connected\" transport, models, messages and the\n * \"✦ Explain\" directives. It never imports `marked` or the panel, so a host can wire the assistant\n * in `app.config.ts` / its root component without pulling the panel into the initial bundle and load\n * `AssistantPanelComponent` from `@meshmakers/shared-ui/assistant` lazily (e.g. with `@defer`).\n *\n * `@meshmakers/shared-ui/assistant` re-exports everything from here (same symbols, same tokens),\n * so both entry points can be mixed freely.\n */\n\n// --- Contract and tokens ---\nexport {\n ASSISTANT_ENABLED,\n ASSISTANT_TRANSPORT,\n ASSISTANT_PAGE_CONTEXT,\n ASSISTANT_TOOL_CALL_COMPONENT,\n ASSISTANT_SLASH_COMMANDS,\n DEFAULT_ASSISTANT_SLASH_COMMANDS,\n ASSISTANT_PANEL_OPTIONS,\n DEFAULT_ASSISTANT_PANEL_MIN_WIDTH,\n DEFAULT_ASSISTANT_PANEL_MAX_WIDTH,\n DEFAULT_ASSISTANT_PANEL_STORAGE_KEY,\n} from './assistant.models';\nexport type {\n AssistantTransportStatus,\n AssistantContextKind,\n AssistantContextChip,\n AssistantExplainTarget,\n AssistantOpenRequest,\n AssistantProposal,\n AssistantToolCall,\n AssistantPageContext,\n AssistantThreadItem,\n AssistantProposalDecisionKind,\n AssistantProposalDecision,\n AssistantSendRequest,\n AssistantStreamEvent,\n AssistantTransport,\n AssistantSlashCommand,\n AssistantAttachmentRef,\n AssistantAttachmentOptions,\n AssistantSessionSummary,\n AssistantStarterQuestions,\n AssistantAsyncResult,\n AssistantPanelOptions,\n AssistantPanelMode,\n} from './assistant.models';\n\n// --- Messages / i18n ---\nexport {\n DEFAULT_ASSISTANT_MESSAGES,\n ASSISTANT_MESSAGES,\n resolveAssistantMessages,\n formatAssistantMessage,\n proposalDecisionLabel,\n /** Internal helper of the panel components (signal of resolved messages); not part of the stable API. */\n assistantMessages,\n} from './assistant.messages';\nexport type { AssistantMessages } from './assistant.messages';\n\n// --- Services / transports ---\nexport { AssistantService, assistantHotkey } from './assistant.service';\nexport { NotConnectedAssistantTransport, ASSISTANT_NOT_CONNECTED_MESSAGE } from './not-connected.transport';\nexport { FakeAssistantTransport } from './testing/fake-assistant-transport';\n\n// --- Pure functions ---\nexport { deriveAssistantContext } from './assistant-context';\nexport type { AssistantContextSource } from './assistant-context';\nexport { selectAssistantAttachments, assistantFileAccepted, formatAssistantFileSize } from './assistant-attachments';\nexport type { AssistantAttachmentSelection } from './assistant-attachments';\n\n// --- Components / directives ---\nexport { AssistantToolCallRowComponent } from './assistant-tool-call-row.component';\nexport { IfAssistantDirective, AssistantExplainDirective } from './assistant-explain.directive';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}