@memberjunction/ng-conversations 6.2.0-edge.4 → 6.2.0-edge.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/README.md +29 -0
  2. package/dist/lib/components/attachment/image-viewer.component.d.ts +3 -1
  3. package/dist/lib/components/attachment/image-viewer.component.d.ts.map +1 -1
  4. package/dist/lib/components/attachment/image-viewer.component.js +5 -1
  5. package/dist/lib/components/attachment/image-viewer.component.js.map +1 -1
  6. package/dist/lib/components/conversation/conversation-agent-picker.component.d.ts +1 -1
  7. package/dist/lib/components/conversation/conversation-agent-picker.component.js +3 -3
  8. package/dist/lib/components/conversation/conversation-agent-picker.component.js.map +1 -1
  9. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +88 -20
  10. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  11. package/dist/lib/components/conversation/conversation-chat-area.component.js +785 -387
  12. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  13. package/dist/lib/components/message/message-input.component.d.ts +60 -20
  14. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  15. package/dist/lib/components/message/message-input.component.js +290 -389
  16. package/dist/lib/components/message/message-input.component.js.map +1 -1
  17. package/dist/lib/components/message/message-item.component.d.ts +153 -17
  18. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  19. package/dist/lib/components/message/message-item.component.js +1400 -299
  20. package/dist/lib/components/message/message-item.component.js.map +1 -1
  21. package/dist/lib/components/message/message-list.component.d.ts +25 -2
  22. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  23. package/dist/lib/components/message/message-list.component.js +79 -40
  24. package/dist/lib/components/message/message-list.component.js.map +1 -1
  25. package/dist/lib/components/overlay/chat-overlay.component.d.ts +19 -0
  26. package/dist/lib/components/overlay/chat-overlay.component.d.ts.map +1 -1
  27. package/dist/lib/components/overlay/chat-overlay.component.js +125 -13
  28. package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
  29. package/dist/lib/components/project/project-form-modal.component.js +2 -2
  30. package/dist/lib/components/project/project-form-modal.component.js.map +1 -1
  31. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +6 -1
  32. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
  33. package/dist/lib/components/realtime/realtime-agent-banner.component.js +110 -82
  34. package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
  35. package/dist/lib/components/realtime/realtime-call-failure-notice.d.ts +13 -0
  36. package/dist/lib/components/realtime/realtime-call-failure-notice.d.ts.map +1 -0
  37. package/dist/lib/components/realtime/realtime-call-failure-notice.js +21 -0
  38. package/dist/lib/components/realtime/realtime-call-failure-notice.js.map +1 -0
  39. package/dist/lib/components/realtime/realtime-composer.component.js +114 -102
  40. package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
  41. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +21 -2
  42. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
  43. package/dist/lib/components/realtime/realtime-session-overlay.component.js +113 -76
  44. package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
  45. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
  46. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +7 -1
  47. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
  48. package/dist/lib/components/sidebar/routines-section.component.js +1 -1
  49. package/dist/lib/components/sidebar/routines-section.component.js.map +1 -1
  50. package/dist/lib/components/task/tasks-full-view.component.d.ts +152 -31
  51. package/dist/lib/components/task/tasks-full-view.component.d.ts.map +1 -1
  52. package/dist/lib/components/task/tasks-full-view.component.js +2227 -214
  53. package/dist/lib/components/task/tasks-full-view.component.js.map +1 -1
  54. package/dist/lib/components/tasks/tasks-dropdown.component.js +4 -4
  55. package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
  56. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +11 -1
  57. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  58. package/dist/lib/components/workspace/conversation-workspace.component.js +25 -28
  59. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  60. package/dist/lib/services/agent-state.service.d.ts.map +1 -1
  61. package/dist/lib/services/agent-state.service.js +8 -8
  62. package/dist/lib/services/agent-state.service.js.map +1 -1
  63. package/dist/lib/services/browser-realtime-media-host.d.ts +7 -7
  64. package/dist/lib/services/browser-realtime-media-host.js +8 -78
  65. package/dist/lib/services/browser-realtime-media-host.js.map +1 -1
  66. package/dist/lib/services/conversation-agent.service.d.ts +53 -20
  67. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  68. package/dist/lib/services/conversation-agent.service.js +108 -54
  69. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  70. package/dist/lib/services/conversation-detail-window.store.d.ts +5 -0
  71. package/dist/lib/services/conversation-detail-window.store.d.ts.map +1 -1
  72. package/dist/lib/services/conversation-detail-window.store.js +52 -5
  73. package/dist/lib/services/conversation-detail-window.store.js.map +1 -1
  74. package/dist/lib/services/conversation-naming.d.ts.map +1 -1
  75. package/dist/lib/services/conversation-naming.js +9 -2
  76. package/dist/lib/services/conversation-naming.js.map +1 -1
  77. package/dist/lib/services/conversation-tasks-filter.d.ts +15 -0
  78. package/dist/lib/services/conversation-tasks-filter.d.ts.map +1 -0
  79. package/dist/lib/services/conversation-tasks-filter.js +69 -0
  80. package/dist/lib/services/conversation-tasks-filter.js.map +1 -0
  81. package/dist/lib/services/realtime-audio-recorder.d.ts +94 -86
  82. package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -1
  83. package/dist/lib/services/realtime-audio-recorder.js +222 -195
  84. package/dist/lib/services/realtime-audio-recorder.js.map +1 -1
  85. package/dist/lib/services/realtime-session.service.d.ts +30 -2
  86. package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
  87. package/dist/lib/services/realtime-session.service.js +35 -7
  88. package/dist/lib/services/realtime-session.service.js.map +1 -1
  89. package/dist/lib/services/recording/libopus-wasm-binary.d.ts +3 -0
  90. package/dist/lib/services/recording/libopus-wasm-binary.d.ts.map +1 -0
  91. package/dist/lib/services/recording/libopus-wasm-binary.js +489 -0
  92. package/dist/lib/services/recording/libopus-wasm-binary.js.map +1 -0
  93. package/dist/lib/services/recording/libopus-worker-source.d.ts +48 -0
  94. package/dist/lib/services/recording/libopus-worker-source.d.ts.map +1 -0
  95. package/dist/lib/services/recording/libopus-worker-source.js +170 -0
  96. package/dist/lib/services/recording/libopus-worker-source.js.map +1 -0
  97. package/dist/lib/services/recording/linear-resampler.d.ts +45 -0
  98. package/dist/lib/services/recording/linear-resampler.d.ts.map +1 -0
  99. package/dist/lib/services/recording/linear-resampler.js +85 -0
  100. package/dist/lib/services/recording/linear-resampler.js.map +1 -0
  101. package/dist/lib/services/recording/opus-packet-encoder.d.ts +50 -0
  102. package/dist/lib/services/recording/opus-packet-encoder.d.ts.map +1 -0
  103. package/dist/lib/services/recording/opus-packet-encoder.js +41 -0
  104. package/dist/lib/services/recording/opus-packet-encoder.js.map +1 -0
  105. package/dist/lib/services/recording/wasm-opus-encoder.d.ts +86 -0
  106. package/dist/lib/services/recording/wasm-opus-encoder.d.ts.map +1 -0
  107. package/dist/lib/services/recording/wasm-opus-encoder.js +232 -0
  108. package/dist/lib/services/recording/wasm-opus-encoder.js.map +1 -0
  109. package/dist/lib/services/recording/webcodecs-opus-encoder.d.ts +39 -0
  110. package/dist/lib/services/recording/webcodecs-opus-encoder.d.ts.map +1 -0
  111. package/dist/lib/services/recording/webcodecs-opus-encoder.js +101 -0
  112. package/dist/lib/services/recording/webcodecs-opus-encoder.js.map +1 -0
  113. package/dist/lib/services/search.service.d.ts.map +1 -1
  114. package/dist/lib/services/search.service.js +3 -16
  115. package/dist/lib/services/search.service.js.map +1 -1
  116. package/dist/lib/utils/agent-failure-display.d.ts +14 -0
  117. package/dist/lib/utils/agent-failure-display.d.ts.map +1 -0
  118. package/dist/lib/utils/agent-failure-display.js +26 -0
  119. package/dist/lib/utils/agent-failure-display.js.map +1 -0
  120. package/dist/lib/utils/distinct-artifacts.d.ts +9 -3
  121. package/dist/lib/utils/distinct-artifacts.d.ts.map +1 -1
  122. package/dist/lib/utils/distinct-artifacts.js +24 -5
  123. package/dist/lib/utils/distinct-artifacts.js.map +1 -1
  124. package/dist/lib/utils/message-list-order.d.ts +13 -0
  125. package/dist/lib/utils/message-list-order.d.ts.map +1 -0
  126. package/dist/lib/utils/message-list-order.js +31 -0
  127. package/dist/lib/utils/message-list-order.js.map +1 -0
  128. package/dist/lib/utils/pin-state.d.ts +11 -0
  129. package/dist/lib/utils/pin-state.d.ts.map +1 -0
  130. package/dist/lib/utils/pin-state.js +9 -0
  131. package/dist/lib/utils/pin-state.js.map +1 -0
  132. package/dist/public-api.d.ts +1 -0
  133. package/dist/public-api.d.ts.map +1 -1
  134. package/dist/public-api.js +1 -0
  135. package/dist/public-api.js.map +1 -1
  136. package/package.json +36 -36
  137. package/dist/lib/services/browser-recording-unload-guard.d.ts +0 -30
  138. package/dist/lib/services/browser-recording-unload-guard.d.ts.map +0 -1
  139. package/dist/lib/services/browser-recording-unload-guard.js +0 -43
  140. package/dist/lib/services/browser-recording-unload-guard.js.map +0 -1
  141. package/dist/lib/services/realtime-pcm-wav.d.ts +0 -79
  142. package/dist/lib/services/realtime-pcm-wav.d.ts.map +0 -1
  143. package/dist/lib/services/realtime-pcm-wav.js +0 -213
  144. package/dist/lib/services/realtime-pcm-wav.js.map +0 -1
package/README.md CHANGED
@@ -120,6 +120,8 @@ Embedding products (white-labeled end-user apps, embedded widgets) can pare the
120
120
  | `allowAttachments` | The file-attachment button |
121
121
  | `allowPlanMode` | The composer's Plan Mode toggle button |
122
122
  | `allowRealtime` | The composer's real-time voice (co-agent) launcher button |
123
+ | `AllowForking` | Starting forks: Fork from here, and Edit or Regenerate as a fork. When `false`, Edit and Regenerate change the latest turn in place, as without the `Conversations: Fork` authorization. UI only; deny that authorization to a role to block forks on the server too |
124
+ | `AllowStopRun` | Stopping and continuing agent runs: the composer's Stop and Stop all, the Stop pill on an in-progress reply, the Continue button on a stopped reply, and the "Continue, or tell {agent} what to do differently" placeholder. UI only: a run stopped from another client still shows as stopped, and the next message still continues it. The composer's status line ("Sage is working, 0:41") is not part of this cap; it shows for any reply in flight |
123
125
  | `showEmptyFill` | The message list's built-in "No messages yet" filler |
124
126
  | `showLoadingState` | The centered loading spinner (loading still short-circuits rendering, so hiding it does not flash the empty state) |
125
127
  | `showAgentPicker` | The agent picker |
@@ -529,6 +531,33 @@ never writes into the engine's detail cache.
529
531
  Paging is measured in **display items**, not database rows: a realtime session collapses many
530
532
  rows into one timeline card, and a session is never split across pages.
531
533
 
534
+ ### Post-Turn Artifact Panel Auto-Open, Refresh & Switch (`decidePostTurnArtifactPanelAction`)
535
+
536
+ When an agent turn completes in `ConversationChatAreaComponent`, the component captures the pre-turn set of non-system output `ArtifactID`s (`captureVisibleArtifactIdBaseline`) before the server turn runs and evaluates `decidePostTurnArtifactPanelAction` once the newly created/versioned artifacts for that turn are loaded:
537
+
538
+ - **Panel Closed + Brand-New Artifact (`action: 'open-new'`)**: Automatically opens the right-hand Artifact Panel when the completed turn created an `ArtifactID` that did not exist in the pre-turn baseline (preserving the intentional behavior that versioning an *already-existing* artifact while the user has closed the panel does not force it back open).
539
+ - **Panel Open + Currently Viewed Artifact Versioned (`action: 'refresh-current'`)**: Increments `artifactViewerRefreshTrigger` and updates `activeVersionNumber` in place so the open viewer immediately reflects the new version (e.g., `v1` → `v2`).
540
+ - **Panel Open + Different Artifact Created or Versioned (`action: 'switch-artifact'`)**: Automatically switches the open Artifact Panel to display the newly created or newly versioned artifact (`activeArtifactId`, `activeVersionNumber`).
541
+ - **Reconnected In-Flight Runs**: When reconnecting to an already-running turn on conversation open (`reconnectToInFlightAgentRuns`), the pre-turn baseline excludes any output artifacts attached to the in-progress message itself so a newly produced artifact still auto-opens when the reconnected turn finishes.
542
+
543
+ ### First-Class Inline Workflow Execution Card & Durable Task-Graph Continuation
544
+
545
+ When an agent (such as `Sage`) dispatches a multi-step durable task graph associated with a `ConversationDetail` message:
546
+
547
+ - **Inline Workflow Execution Card (`.msg-workflow-card` in `MessageItemComponent`)**: Renders directly inside `.message-body` (without requiring the user to open the developer gear menu). Deduplicates parent workflow container tasks (`ParentID == null`) from ordered step tasks (`WorkflowSteps`), displays an active shimmer progress bar, completed step ratio (`X/Y steps`), live elapsed duration, per-step specialist agent badges (`@Query Builder`, `@Research Report Writer`), and a one-click slide-over step inspector drawer (`mj-task-detail-panel`).
548
+ - **Real-Time Multi-Tab Broadcast & Continuation (`ConversationChatAreaComponent`)**: `TaskGraphFrameBroadcaster` and `TaskGraphContinuationDeliverer` publish task-node progress and completion frames over `PUSH_STATUS_UPDATES_TOPIC` (`sessionId: '*'`, filtered by `ownerUserId` in `PushStatusResolver`). When a durable workflow finishes with `continuation: 'reinvoke'`, the server creates a new visible AI `ConversationDetail` reply row, runs the synthesizing agent, persists both step-level and continuation artifacts (`ProcessAgentArtifacts`), and notifies `ConversationChatAreaComponent` (`NewMessageCreated: true`) so the active conversation reloads messages, refreshes task statuses, and auto-opens any newly produced artifact.
549
+
550
+ ### AI Agent Workflows & Tasks Command Center (`TasksFullViewComponent`)
551
+
552
+ `TasksFullViewComponent` (`<mj-tasks-full-view>`) provides the **AI Agent Workflows & Tasks Command Center** for inspecting and navigating agent-invoked workflows and standalone tasks across conversations:
553
+
554
+ - **5-Card KPI Metric Ribbon**: Interactive filter cards for **Active Now**, **Completed**, **Needs Attention** (Failed/Cancelled), **Total Workflows**, and **Avg Execution Time** (plus completed-step throughput).
555
+ - **Unified Filter & Search Bar**: Instant full-text search across workflow names, descriptions, and conversation names, status pill filters (`All`, `Active`, `Completed`, `Failed`), a dynamic **Specialist Agent** dropdown filter, and a scope toggle (**All Tasks** vs. **My Tasks**).
556
+ - **3 Synchronized View Modes**:
557
+ 1. **Workflow Cards View**: Hierarchy-aware cards showing workflow status, parent conversation deep-link pill, horizontal **Agent Pipeline** chips (`Step 1 -> Step 2`), progress bar, and expandable step rows with step numbers, agent badges, durations, and output previews.
558
+ 2. **Execution Timeline & DAG View**: Custom second/minute-resolution **Execution Waterfall** bar chart for multi-step workflows (rendered automatically whenever tasks span `< 2 days` where day-level Gantt bars would collapse), paired with the full `mj-gantt-task-viewer` for multi-day schedules.
559
+ 3. **Slide-Over Workflow & Step Inspector Drawer**: Selecting any workflow or step opens a contextual right-hand inspector drawer with step-switcher tabs, clickable telemetry pills for the **AI Agent** (`MJ: AI Agents`) and **AI Agent Run** (`MJ: AI Agent Runs`), separated **Task Instructions (Input)** vs. **Agent Output / Deliverable** (parsed cleanly around the `--- Output ---` delimiter), and a primary **Jump to Chat** action.
560
+
532
561
  ### MJ Entity Integration
533
562
 
534
563
  All data operations use the MemberJunction entity system:
@@ -138,7 +138,9 @@ export declare class ImageViewerComponent implements OnInit, OnDestroy {
138
138
  */
139
139
  onMouseUp(): void;
140
140
  /**
141
- * Download the image
141
+ * Download the image. A browser ignores `download` on a cross-origin URL (an image from a
142
+ * message's text, served by the API host) and navigates instead, so the link opens a new tab
143
+ * rather than replacing the app; a data: or same-origin URL still downloads.
142
144
  */
143
145
  DownloadImage(): void;
144
146
  /** @deprecated Use {@link DownloadImage}. */
@@ -1 +1 @@
1
- {"version":3,"file":"image-viewer.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/attachment/image-viewer.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"image-viewer.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/attachment/image-viewer.component.ts"],"names":[],"mappings":"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"}
@@ -345,12 +345,16 @@ export class ImageViewerComponent {
345
345
  this.IsDragging = false;
346
346
  }
347
347
  /**
348
- * Download the image
348
+ * Download the image. A browser ignores `download` on a cross-origin URL (an image from a
349
+ * message's text, served by the API host) and navigates instead, so the link opens a new tab
350
+ * rather than replacing the app; a data: or same-origin URL still downloads.
349
351
  */
350
352
  DownloadImage() {
351
353
  const link = document.createElement('a');
352
354
  link.href = this.ImageUrl;
353
355
  link.download = this.FileName;
356
+ link.target = '_blank';
357
+ link.rel = 'noopener noreferrer';
354
358
  link.click();
355
359
  }
356
360
  /** @deprecated Use {@link DownloadImage}. */
@@ -1 +1 @@
1
- {"version":3,"file":"image-viewer.component.js","sourceRoot":"","sources":["../../../../src/lib/components/attachment/image-viewer.component.ts","../../../../src/lib/components/attachment/image-viewer.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n HostListener,\n OnInit,\n OnDestroy\n} from '@angular/core';\n\n/**\n * Full-screen image viewer modal with zoom and pan capabilities.\n * Provides a lightbox-style experience for viewing attachment images.\n */\n@Component({\n standalone: false,\n selector: 'mj-image-viewer',\n templateUrl: './image-viewer.component.html',\n styleUrls: ['./image-viewer.component.css']\n})\nexport class ImageViewerComponent implements OnInit, OnDestroy {\n /** Image source URL (can be data URL or regular URL) */\n @Input() ImageUrl: string = '';\n\n /** @deprecated Use {@link ImageUrl}. */\n @Input() set imageUrl(value: string) {\n this.ImageUrl = value;\n }\n /** @deprecated Use {@link ImageUrl}. */\n get imageUrl(): string {\n return this.ImageUrl;\n }\n\n /** Image alt text */\n @Input() Alt: string = 'Image';\n\n /** @deprecated Use {@link Alt}. */\n @Input() set alt(value: string) {\n this.Alt = value;\n }\n /** @deprecated Use {@link Alt}. */\n get alt(): string {\n return this.Alt;\n }\n\n /** Image filename for download */\n @Input() FileName: string = 'image';\n\n /** @deprecated Use {@link FileName}. */\n @Input() set fileName(value: string) {\n this.FileName = value;\n }\n /** @deprecated Use {@link FileName}. */\n get fileName(): string {\n return this.FileName;\n }\n\n /** Whether the viewer is visible */\n @Input() Visible: boolean = false;\n\n /** @deprecated Use {@link Visible}. */\n @Input() set visible(value: boolean) {\n this.Visible = value;\n }\n /** @deprecated Use {@link Visible}. */\n get visible(): boolean {\n return this.Visible;\n }\n\n /** Emits when the viewer should be closed */\n @Output() Closed = new EventEmitter<void>();\n\n /**\n * @deprecated Use {@link Closed}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (closed) keeps working. Must stay AFTER Closed: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() closed = this.Closed;\n\n // Zoom and pan state\n public ZoomLevel: number = 1;\n\n /** @deprecated Use {@link ZoomLevel}. */\n public get zoomLevel(): number {\n return this.ZoomLevel;\n }\n /** @deprecated Use {@link ZoomLevel}. */\n public set zoomLevel(value: number) {\n this.ZoomLevel = value;\n }\n public MinZoom: number = 0.1;\n\n /** @deprecated Use {@link MinZoom}. */\n public get minZoom(): number {\n return this.MinZoom;\n }\n /** @deprecated Use {@link MinZoom}. */\n public set minZoom(value: number) {\n this.MinZoom = value;\n }\n public MaxZoom: number = 5;\n\n /** @deprecated Use {@link MaxZoom}. */\n public get maxZoom(): number {\n return this.MaxZoom;\n }\n /** @deprecated Use {@link MaxZoom}. */\n public set maxZoom(value: number) {\n this.MaxZoom = value;\n }\n public TranslateX: number = 0;\n\n /** @deprecated Use {@link TranslateX}. */\n public get translateX(): number {\n return this.TranslateX;\n }\n /** @deprecated Use {@link TranslateX}. */\n public set translateX(value: number) {\n this.TranslateX = value;\n }\n public TranslateY: number = 0;\n\n /** @deprecated Use {@link TranslateY}. */\n public get translateY(): number {\n return this.TranslateY;\n }\n /** @deprecated Use {@link TranslateY}. */\n public set translateY(value: number) {\n this.TranslateY = value;\n }\n\n // Drag state\n public IsDragging: boolean = false;\n\n /** @deprecated Use {@link IsDragging}. */\n public get isDragging(): boolean {\n return this.IsDragging;\n }\n /** @deprecated Use {@link IsDragging}. */\n public set isDragging(value: boolean) {\n this.IsDragging = value;\n }\n private lastMouseX: number = 0;\n private lastMouseY: number = 0;\n\n ngOnInit(): void {\n // Lock body scroll when viewer is open\n if (this.Visible) {\n document.body.style.overflow = 'hidden';\n }\n }\n\n ngOnDestroy(): void {\n // Restore body scroll\n document.body.style.overflow = '';\n }\n\n /**\n * Handle escape key to close\n */\n @HostListener('document:keydown.escape')\n onEscapeKey(): void {\n if (this.Visible) {\n this.close();\n }\n }\n\n /**\n * Handle mouse wheel for zoom\n */\n @HostListener('wheel', ['$event'])\n onWheel(event: WheelEvent): void {\n if (!this.Visible) return;\n event.preventDefault();\n\n const delta = event.deltaY > 0 ? -0.1 : 0.1;\n this.adjustZoom(delta, event.clientX, event.clientY);\n }\n\n /**\n * Close the viewer\n */\n close(): void {\n this.resetView();\n document.body.style.overflow = '';\n this.Closed.emit();\n }\n\n /**\n * Handle backdrop click\n */\n OnBackdropClick(event: MouseEvent): void {\n // Only close if clicking directly on backdrop\n const target = event.target as HTMLElement;\n if (target.classList.contains('image-viewer-backdrop')) {\n this.close();\n }\n }\n\n /** @deprecated Use {@link OnBackdropClick}. */\n onBackdropClick(event: MouseEvent): void {\n return this.OnBackdropClick(event);\n }\n\n /**\n * Zoom in\n */\n ZoomIn(): void {\n this.adjustZoom(0.25);\n }\n\n /** @deprecated Use {@link ZoomIn}. */\n zoomIn(): void {\n return this.ZoomIn();\n }\n\n /**\n * Zoom out\n */\n ZoomOut(): void {\n this.adjustZoom(-0.25);\n }\n\n /** @deprecated Use {@link ZoomOut}. */\n zoomOut(): void {\n return this.ZoomOut();\n }\n\n /**\n * Reset to 100% zoom\n */\n ResetZoom(): void {\n this.ZoomLevel = 1;\n this.TranslateX = 0;\n this.TranslateY = 0;\n }\n\n /** @deprecated Use {@link ResetZoom}. */\n resetZoom(): void {\n return this.ResetZoom();\n }\n\n /**\n * Fit image to screen\n */\n FitToScreen(): void {\n // Reset position and set zoom to 1 (CSS will handle fitting)\n this.resetView();\n }\n\n /** @deprecated Use {@link FitToScreen}. */\n fitToScreen(): void {\n return this.FitToScreen();\n }\n\n /**\n * Reset view to initial state\n */\n private resetView(): void {\n this.ZoomLevel = 1;\n this.TranslateX = 0;\n this.TranslateY = 0;\n }\n\n /**\n * Adjust zoom level\n */\n private adjustZoom(delta: number, centerX?: number, centerY?: number): void {\n const newZoom = Math.max(this.MinZoom, Math.min(this.MaxZoom, this.ZoomLevel + delta));\n\n if (centerX !== undefined && centerY !== undefined && newZoom !== this.ZoomLevel) {\n // Zoom towards mouse position\n const factor = newZoom / this.ZoomLevel;\n const imageContainer = document.querySelector('.image-container') as HTMLElement;\n if (imageContainer) {\n const rect = imageContainer.getBoundingClientRect();\n const offsetX = centerX - rect.left - rect.width / 2 - this.TranslateX;\n const offsetY = centerY - rect.top - rect.height / 2 - this.TranslateY;\n\n this.TranslateX = this.TranslateX - offsetX * (factor - 1);\n this.TranslateY = this.TranslateY - offsetY * (factor - 1);\n }\n }\n\n this.ZoomLevel = newZoom;\n }\n\n /**\n * Handle mouse down for dragging\n */\n OnMouseDown(event: MouseEvent): void {\n if (event.button !== 0) return; // Only left click\n if (this.ZoomLevel <= 1) return; // Only allow pan when zoomed in\n\n this.IsDragging = true;\n this.lastMouseX = event.clientX;\n this.lastMouseY = event.clientY;\n event.preventDefault();\n }\n\n /** @deprecated Use {@link OnMouseDown}. */\n onMouseDown(event: MouseEvent): void {\n return this.OnMouseDown(event);\n }\n\n /**\n * Handle mouse move for dragging\n */\n @HostListener('document:mousemove', ['$event'])\n onMouseMove(event: MouseEvent): void {\n if (!this.IsDragging) return;\n\n const deltaX = event.clientX - this.lastMouseX;\n const deltaY = event.clientY - this.lastMouseY;\n\n this.TranslateX += deltaX;\n this.TranslateY += deltaY;\n\n this.lastMouseX = event.clientX;\n this.lastMouseY = event.clientY;\n }\n\n /**\n * Handle mouse up to stop dragging\n */\n @HostListener('document:mouseup')\n onMouseUp(): void {\n this.IsDragging = false;\n }\n\n /**\n * Download the image\n */\n DownloadImage(): void {\n const link = document.createElement('a');\n link.href = this.ImageUrl;\n link.download = this.FileName;\n link.click();\n }\n\n /** @deprecated Use {@link DownloadImage}. */\n downloadImage(): void {\n return this.DownloadImage();\n }\n\n /**\n * Get current zoom percentage for display\n */\n get ZoomPercentage(): string {\n return Math.round(this.ZoomLevel * 100) + '%';\n }\n\n /** @deprecated Use {@link ZoomPercentage}. */\n get zoomPercentage(): string {\n return this.ZoomPercentage;\n }\n\n /**\n * Get transform style for image\n */\n get ImageTransform(): string {\n return `translate(${this.TranslateX}px, ${this.TranslateY}px) scale(${this.ZoomLevel})`;\n }\n\n /** @deprecated Use {@link ImageTransform}. */\n get imageTransform(): string {\n return this.ImageTransform;\n }\n}\n","@if (visible) {\n <div class=\"image-viewer-backdrop\"\n (click)=\"onBackdropClick($event)\">\n <!-- Toolbar -->\n <div class=\"viewer-toolbar\">\n <div class=\"toolbar-left\">\n @if (fileName) {\n <span class=\"file-name\">{{ fileName }}</span>\n }\n </div>\n <div class=\"toolbar-center\">\n <button class=\"toolbar-btn\" (click)=\"zoomOut()\" title=\"Zoom Out\">\n <i class=\"fa-solid fa-minus\"></i>\n </button>\n <span class=\"zoom-display\">{{ zoomPercentage }}</span>\n <button class=\"toolbar-btn\" (click)=\"zoomIn()\" title=\"Zoom In\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n <div class=\"toolbar-separator\"></div>\n <button class=\"toolbar-btn\" (click)=\"resetZoom()\" title=\"Reset Zoom (100%)\">\n <i class=\"fa-solid fa-expand\"></i>\n </button>\n <button class=\"toolbar-btn\" (click)=\"fitToScreen()\" title=\"Fit to Screen\">\n <i class=\"fa-solid fa-compress\"></i>\n </button>\n </div>\n <div class=\"toolbar-right\">\n <button class=\"toolbar-btn\" (click)=\"downloadImage()\" title=\"Download\">\n <i class=\"fa-solid fa-download\"></i>\n </button>\n <button class=\"toolbar-btn close-btn\" (click)=\"close()\" title=\"Close (Esc)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n <!-- Image Container -->\n <div class=\"image-container\"\n (mousedown)=\"onMouseDown($event)\"\n [style.cursor]=\"zoomLevel > 1 ? (isDragging ? 'grabbing' : 'grab') : 'default'\">\n <img [src]=\"imageUrl\"\n [alt]=\"alt\"\n class=\"viewer-image\"\n [style.transform]=\"imageTransform\"\n draggable=\"false\">\n </div>\n <!-- Instructions -->\n <div class=\"viewer-instructions\">\n <span>Scroll to zoom</span>\n <span class=\"separator\">|</span>\n <span>Drag to pan when zoomed</span>\n <span class=\"separator\">|</span>\n <span>Esc to close</span>\n </div>\n </div>\n}\n"]}
1
+ {"version":3,"file":"image-viewer.component.js","sourceRoot":"","sources":["../../../../src/lib/components/attachment/image-viewer.component.ts","../../../../src/lib/components/attachment/image-viewer.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n HostListener,\n OnInit,\n OnDestroy\n} from '@angular/core';\n\n/**\n * Full-screen image viewer modal with zoom and pan capabilities.\n * Provides a lightbox-style experience for viewing attachment images.\n */\n@Component({\n standalone: false,\n selector: 'mj-image-viewer',\n templateUrl: './image-viewer.component.html',\n styleUrls: ['./image-viewer.component.css']\n})\nexport class ImageViewerComponent implements OnInit, OnDestroy {\n /** Image source URL (can be data URL or regular URL) */\n @Input() ImageUrl: string = '';\n\n /** @deprecated Use {@link ImageUrl}. */\n @Input() set imageUrl(value: string) {\n this.ImageUrl = value;\n }\n /** @deprecated Use {@link ImageUrl}. */\n get imageUrl(): string {\n return this.ImageUrl;\n }\n\n /** Image alt text */\n @Input() Alt: string = 'Image';\n\n /** @deprecated Use {@link Alt}. */\n @Input() set alt(value: string) {\n this.Alt = value;\n }\n /** @deprecated Use {@link Alt}. */\n get alt(): string {\n return this.Alt;\n }\n\n /** Image filename for download */\n @Input() FileName: string = 'image';\n\n /** @deprecated Use {@link FileName}. */\n @Input() set fileName(value: string) {\n this.FileName = value;\n }\n /** @deprecated Use {@link FileName}. */\n get fileName(): string {\n return this.FileName;\n }\n\n /** Whether the viewer is visible */\n @Input() Visible: boolean = false;\n\n /** @deprecated Use {@link Visible}. */\n @Input() set visible(value: boolean) {\n this.Visible = value;\n }\n /** @deprecated Use {@link Visible}. */\n get visible(): boolean {\n return this.Visible;\n }\n\n /** Emits when the viewer should be closed */\n @Output() Closed = new EventEmitter<void>();\n\n /**\n * @deprecated Use {@link Closed}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (closed) keeps working. Must stay AFTER Closed: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() closed = this.Closed;\n\n // Zoom and pan state\n public ZoomLevel: number = 1;\n\n /** @deprecated Use {@link ZoomLevel}. */\n public get zoomLevel(): number {\n return this.ZoomLevel;\n }\n /** @deprecated Use {@link ZoomLevel}. */\n public set zoomLevel(value: number) {\n this.ZoomLevel = value;\n }\n public MinZoom: number = 0.1;\n\n /** @deprecated Use {@link MinZoom}. */\n public get minZoom(): number {\n return this.MinZoom;\n }\n /** @deprecated Use {@link MinZoom}. */\n public set minZoom(value: number) {\n this.MinZoom = value;\n }\n public MaxZoom: number = 5;\n\n /** @deprecated Use {@link MaxZoom}. */\n public get maxZoom(): number {\n return this.MaxZoom;\n }\n /** @deprecated Use {@link MaxZoom}. */\n public set maxZoom(value: number) {\n this.MaxZoom = value;\n }\n public TranslateX: number = 0;\n\n /** @deprecated Use {@link TranslateX}. */\n public get translateX(): number {\n return this.TranslateX;\n }\n /** @deprecated Use {@link TranslateX}. */\n public set translateX(value: number) {\n this.TranslateX = value;\n }\n public TranslateY: number = 0;\n\n /** @deprecated Use {@link TranslateY}. */\n public get translateY(): number {\n return this.TranslateY;\n }\n /** @deprecated Use {@link TranslateY}. */\n public set translateY(value: number) {\n this.TranslateY = value;\n }\n\n // Drag state\n public IsDragging: boolean = false;\n\n /** @deprecated Use {@link IsDragging}. */\n public get isDragging(): boolean {\n return this.IsDragging;\n }\n /** @deprecated Use {@link IsDragging}. */\n public set isDragging(value: boolean) {\n this.IsDragging = value;\n }\n private lastMouseX: number = 0;\n private lastMouseY: number = 0;\n\n ngOnInit(): void {\n // Lock body scroll when viewer is open\n if (this.Visible) {\n document.body.style.overflow = 'hidden';\n }\n }\n\n ngOnDestroy(): void {\n // Restore body scroll\n document.body.style.overflow = '';\n }\n\n /**\n * Handle escape key to close\n */\n @HostListener('document:keydown.escape')\n onEscapeKey(): void {\n if (this.Visible) {\n this.close();\n }\n }\n\n /**\n * Handle mouse wheel for zoom\n */\n @HostListener('wheel', ['$event'])\n onWheel(event: WheelEvent): void {\n if (!this.Visible) return;\n event.preventDefault();\n\n const delta = event.deltaY > 0 ? -0.1 : 0.1;\n this.adjustZoom(delta, event.clientX, event.clientY);\n }\n\n /**\n * Close the viewer\n */\n close(): void {\n this.resetView();\n document.body.style.overflow = '';\n this.Closed.emit();\n }\n\n /**\n * Handle backdrop click\n */\n OnBackdropClick(event: MouseEvent): void {\n // Only close if clicking directly on backdrop\n const target = event.target as HTMLElement;\n if (target.classList.contains('image-viewer-backdrop')) {\n this.close();\n }\n }\n\n /** @deprecated Use {@link OnBackdropClick}. */\n onBackdropClick(event: MouseEvent): void {\n return this.OnBackdropClick(event);\n }\n\n /**\n * Zoom in\n */\n ZoomIn(): void {\n this.adjustZoom(0.25);\n }\n\n /** @deprecated Use {@link ZoomIn}. */\n zoomIn(): void {\n return this.ZoomIn();\n }\n\n /**\n * Zoom out\n */\n ZoomOut(): void {\n this.adjustZoom(-0.25);\n }\n\n /** @deprecated Use {@link ZoomOut}. */\n zoomOut(): void {\n return this.ZoomOut();\n }\n\n /**\n * Reset to 100% zoom\n */\n ResetZoom(): void {\n this.ZoomLevel = 1;\n this.TranslateX = 0;\n this.TranslateY = 0;\n }\n\n /** @deprecated Use {@link ResetZoom}. */\n resetZoom(): void {\n return this.ResetZoom();\n }\n\n /**\n * Fit image to screen\n */\n FitToScreen(): void {\n // Reset position and set zoom to 1 (CSS will handle fitting)\n this.resetView();\n }\n\n /** @deprecated Use {@link FitToScreen}. */\n fitToScreen(): void {\n return this.FitToScreen();\n }\n\n /**\n * Reset view to initial state\n */\n private resetView(): void {\n this.ZoomLevel = 1;\n this.TranslateX = 0;\n this.TranslateY = 0;\n }\n\n /**\n * Adjust zoom level\n */\n private adjustZoom(delta: number, centerX?: number, centerY?: number): void {\n const newZoom = Math.max(this.MinZoom, Math.min(this.MaxZoom, this.ZoomLevel + delta));\n\n if (centerX !== undefined && centerY !== undefined && newZoom !== this.ZoomLevel) {\n // Zoom towards mouse position\n const factor = newZoom / this.ZoomLevel;\n const imageContainer = document.querySelector('.image-container') as HTMLElement;\n if (imageContainer) {\n const rect = imageContainer.getBoundingClientRect();\n const offsetX = centerX - rect.left - rect.width / 2 - this.TranslateX;\n const offsetY = centerY - rect.top - rect.height / 2 - this.TranslateY;\n\n this.TranslateX = this.TranslateX - offsetX * (factor - 1);\n this.TranslateY = this.TranslateY - offsetY * (factor - 1);\n }\n }\n\n this.ZoomLevel = newZoom;\n }\n\n /**\n * Handle mouse down for dragging\n */\n OnMouseDown(event: MouseEvent): void {\n if (event.button !== 0) return; // Only left click\n if (this.ZoomLevel <= 1) return; // Only allow pan when zoomed in\n\n this.IsDragging = true;\n this.lastMouseX = event.clientX;\n this.lastMouseY = event.clientY;\n event.preventDefault();\n }\n\n /** @deprecated Use {@link OnMouseDown}. */\n onMouseDown(event: MouseEvent): void {\n return this.OnMouseDown(event);\n }\n\n /**\n * Handle mouse move for dragging\n */\n @HostListener('document:mousemove', ['$event'])\n onMouseMove(event: MouseEvent): void {\n if (!this.IsDragging) return;\n\n const deltaX = event.clientX - this.lastMouseX;\n const deltaY = event.clientY - this.lastMouseY;\n\n this.TranslateX += deltaX;\n this.TranslateY += deltaY;\n\n this.lastMouseX = event.clientX;\n this.lastMouseY = event.clientY;\n }\n\n /**\n * Handle mouse up to stop dragging\n */\n @HostListener('document:mouseup')\n onMouseUp(): void {\n this.IsDragging = false;\n }\n\n /**\n * Download the image. A browser ignores `download` on a cross-origin URL (an image from a\n * message's text, served by the API host) and navigates instead, so the link opens a new tab\n * rather than replacing the app; a data: or same-origin URL still downloads.\n */\n DownloadImage(): void {\n const link = document.createElement('a');\n link.href = this.ImageUrl;\n link.download = this.FileName;\n link.target = '_blank';\n link.rel = 'noopener noreferrer';\n link.click();\n }\n\n /** @deprecated Use {@link DownloadImage}. */\n downloadImage(): void {\n return this.DownloadImage();\n }\n\n /**\n * Get current zoom percentage for display\n */\n get ZoomPercentage(): string {\n return Math.round(this.ZoomLevel * 100) + '%';\n }\n\n /** @deprecated Use {@link ZoomPercentage}. */\n get zoomPercentage(): string {\n return this.ZoomPercentage;\n }\n\n /**\n * Get transform style for image\n */\n get ImageTransform(): string {\n return `translate(${this.TranslateX}px, ${this.TranslateY}px) scale(${this.ZoomLevel})`;\n }\n\n /** @deprecated Use {@link ImageTransform}. */\n get imageTransform(): string {\n return this.ImageTransform;\n }\n}\n","@if (visible) {\n <div class=\"image-viewer-backdrop\"\n (click)=\"onBackdropClick($event)\">\n <!-- Toolbar -->\n <div class=\"viewer-toolbar\">\n <div class=\"toolbar-left\">\n @if (fileName) {\n <span class=\"file-name\">{{ fileName }}</span>\n }\n </div>\n <div class=\"toolbar-center\">\n <button class=\"toolbar-btn\" (click)=\"zoomOut()\" title=\"Zoom Out\">\n <i class=\"fa-solid fa-minus\"></i>\n </button>\n <span class=\"zoom-display\">{{ zoomPercentage }}</span>\n <button class=\"toolbar-btn\" (click)=\"zoomIn()\" title=\"Zoom In\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n <div class=\"toolbar-separator\"></div>\n <button class=\"toolbar-btn\" (click)=\"resetZoom()\" title=\"Reset Zoom (100%)\">\n <i class=\"fa-solid fa-expand\"></i>\n </button>\n <button class=\"toolbar-btn\" (click)=\"fitToScreen()\" title=\"Fit to Screen\">\n <i class=\"fa-solid fa-compress\"></i>\n </button>\n </div>\n <div class=\"toolbar-right\">\n <button class=\"toolbar-btn\" (click)=\"downloadImage()\" title=\"Download\">\n <i class=\"fa-solid fa-download\"></i>\n </button>\n <button class=\"toolbar-btn close-btn\" (click)=\"close()\" title=\"Close (Esc)\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n <!-- Image Container -->\n <div class=\"image-container\"\n (mousedown)=\"onMouseDown($event)\"\n [style.cursor]=\"zoomLevel > 1 ? (isDragging ? 'grabbing' : 'grab') : 'default'\">\n <img [src]=\"imageUrl\"\n [alt]=\"alt\"\n class=\"viewer-image\"\n [style.transform]=\"imageTransform\"\n draggable=\"false\">\n </div>\n <!-- Instructions -->\n <div class=\"viewer-instructions\">\n <span>Scroll to zoom</span>\n <span class=\"separator\">|</span>\n <span>Drag to pan when zoomed</span>\n <span class=\"separator\">|</span>\n <span>Esc to close</span>\n </div>\n </div>\n}\n"]}
@@ -11,7 +11,7 @@ import * as i0 from "@angular/core";
11
11
  * non-mention messages route to it instead of Sage.
12
12
  *
13
13
  * Eligible agents are top-level, Active, non-Sub-Agent rows from
14
- * `AIEngineBase.Instance.Agents`. The widget renders as a compact button
14
+ * `AIEngineBase.Instance.ReadableAgents`. The widget renders as a compact button
15
15
  * showing the current pin (or "Auto" when nothing is pinned). Clicking
16
16
  * opens an inline list with a "Clear" option to remove the pin.
17
17
  *
@@ -65,7 +65,7 @@ function ConversationAgentPickerComponent_Conditional_6_Template(rf, ctx) { if (
65
65
  * non-mention messages route to it instead of Sage.
66
66
  *
67
67
  * Eligible agents are top-level, Active, non-Sub-Agent rows from
68
- * `AIEngineBase.Instance.Agents`. The widget renders as a compact button
68
+ * `AIEngineBase.Instance.ReadableAgents`. The widget renders as a compact button
69
69
  * showing the current pin (or "Auto" when nothing is pinned). Clicking
70
70
  * opens an inline list with a "Clear" option to remove the pin.
71
71
  *
@@ -106,7 +106,7 @@ export class ConversationAgentPickerComponent {
106
106
  // loaded — most app shells warm it up at boot, but the picker
107
107
  // could mount before that completes.
108
108
  await AIEngineBase.Instance.Config(false);
109
- this.catalogAgents = (AIEngineBase.Instance.Agents ?? [])
109
+ this.catalogAgents = (AIEngineBase.Instance.ReadableAgents ?? [])
110
110
  .filter(a => !a.ParentID &&
111
111
  a.Status === 'Active' &&
112
112
  a.InvocationMode !== 'Sub-Agent')
@@ -131,7 +131,7 @@ export class ConversationAgentPickerComponent {
131
131
  // sub-agent), still surface its name from the cache so the user can
132
132
  // see what was pinned even though they can't re-pin it.
133
133
  const fromCache = match
134
- ?? (AIEngineBase.Instance.Agents ?? []).find(a => UUIDsEqual(a.ID, id));
134
+ ?? (AIEngineBase.Instance.ReadableAgents ?? []).find(a => UUIDsEqual(a.ID, id));
135
135
  return fromCache?.Name ?? 'Pinned agent';
136
136
  }
137
137
  get ButtonTitle() {
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-agent-picker.component.js","sourceRoot":"","sources":["../../../../src/lib/components/conversation/conversation-agent-picker.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n EventEmitter,\n HostListener,\n Input,\n OnInit,\n Output,\n inject,\n} from '@angular/core';\nimport { LogError } from '@memberjunction/core';\nimport type { UserInfo } from '@memberjunction/core';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport type { MJAIAgentEntityExtended } from '@memberjunction/ai-core-plus';\nimport type { MJConversationEntity } from '@memberjunction/core-entities';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { IsAgentAllowed } from '@memberjunction/ai-core-plus';\n\n/**\n * Header widget that lets a user pin a default AI agent on the active\n * conversation. The pinned agent (saved to\n * `MJConversationEntity.DefaultAgentID`) takes precedence over the\n * embedder-supplied default in `MessageInputComponent.routeMessage()` —\n * non-mention messages route to it instead of Sage.\n *\n * Eligible agents are top-level, Active, non-Sub-Agent rows from\n * `AIEngineBase.Instance.Agents`. The widget renders as a compact button\n * showing the current pin (or \"Auto\" when nothing is pinned). Clicking\n * opens an inline list with a \"Clear\" option to remove the pin.\n *\n * The host controls visibility via `<mj-conversation-chat-area>`'s\n * `[showAgentPicker]` input (default true). Surfaces that don't want this\n * UX (e.g. agent-less embed) set it to false.\n */\n@Component({\n standalone: false,\n selector: 'mj-conversation-agent-picker',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"mj-cv-agent-picker\" [class.mj-cv-agent-picker--open]=\"IsOpen\">\n <button\n type=\"button\"\n class=\"mj-cv-agent-picker__trigger\"\n [title]=\"ButtonTitle\"\n [disabled]=\"Disabled || !Conversation\"\n (click)=\"Toggle($event)\">\n <i class=\"fa-solid fa-robot\"></i>\n <span class=\"mj-cv-agent-picker__label\">{{ CurrentAgentLabel }}</span>\n <i class=\"fa-solid fa-caret-down mj-cv-agent-picker__caret\"></i>\n </button>\n @if (IsOpen) {\n <div class=\"mj-cv-agent-picker__menu\" (click)=\"$event.stopPropagation()\">\n <div class=\"mj-cv-agent-picker__menu-header\">Default agent for this conversation</div>\n <button\n type=\"button\"\n class=\"mj-cv-agent-picker__item\"\n [class.mj-cv-agent-picker__item--selected]=\"!Conversation?.DefaultAgentID\"\n (click)=\"PickAgent(null)\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Auto (use default)</span>\n </button>\n @if (EligibleAgents.length === 0) {\n <div class=\"mj-cv-agent-picker__empty\">No agents available</div>\n } @else {\n @for (agent of EligibleAgents; track agent.ID) {\n <button\n type=\"button\"\n class=\"mj-cv-agent-picker__item\"\n [class.mj-cv-agent-picker__item--selected]=\"IsSelected(agent)\"\n [title]=\"agent.Description || agent.Name\"\n (click)=\"PickAgent(agent)\">\n <i [class]=\"IconClassFor(agent)\"></i>\n <span>{{ agent.Name }}</span>\n </button>\n }\n }\n </div>\n }\n </div>\n `,\n styles: [`\n /* Match mjButton size=\"sm\" so the trigger lines up with neighboring\n Export / Share buttons: min-height 32px, 6px/12px padding,\n 0.8125rem font. Same border-radius as the other chrome buttons. */\n .mj-cv-agent-picker { position: relative; display: inline-flex; align-items: center; }\n .mj-cv-agent-picker__trigger {\n display: inline-flex; align-items: center; gap: 6px;\n padding: 6px 12px; min-height: 32px; box-sizing: border-box;\n background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default);\n border-radius: 4px; cursor: pointer;\n color: var(--mj-text-primary); font-size: 0.8125rem; line-height: 1.5;\n transition: background 120ms, border-color 120ms;\n }\n .mj-cv-agent-picker__trigger:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover); border-color: var(--mj-border-strong);\n }\n .mj-cv-agent-picker__trigger:disabled { opacity: 0.5; cursor: not-allowed; }\n .mj-cv-agent-picker--open .mj-cv-agent-picker__trigger { border-color: var(--mj-border-focus); }\n .mj-cv-agent-picker__label { max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .mj-cv-agent-picker__caret { font-size: 10px; opacity: 0.7; }\n .mj-cv-agent-picker__menu {\n position: absolute; top: calc(100% + 4px); right: 0; z-index: 50;\n min-width: 220px; max-height: 320px; overflow-y: auto;\n background: var(--mj-bg-surface-elevated); border: 1px solid var(--mj-border-default);\n border-radius: 6px; box-shadow: 0 4px 16px rgba(0,0,0,0.12);\n padding: 4px 0;\n }\n .mj-cv-agent-picker__menu-header {\n padding: 6px 12px 4px; font-size: 11px; text-transform: uppercase;\n letter-spacing: 0.04em; color: var(--mj-text-muted);\n }\n .mj-cv-agent-picker__item {\n display: flex; align-items: center; gap: 8px; width: 100%;\n padding: 6px 12px; background: transparent; border: none; cursor: pointer;\n color: var(--mj-text-primary); font-size: 13px; text-align: left;\n }\n .mj-cv-agent-picker__item i { width: 14px; text-align: center; color: var(--mj-text-secondary); }\n .mj-cv-agent-picker__item:hover { background: var(--mj-bg-surface-hover); }\n .mj-cv-agent-picker__item--selected { background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent); }\n .mj-cv-agent-picker__item--selected i { color: var(--mj-brand-primary); }\n .mj-cv-agent-picker__empty { padding: 8px 12px; font-size: 12px; color: var(--mj-text-muted); }\n `]\n})\nexport class ConversationAgentPickerComponent implements OnInit {\n /** The conversation whose `DefaultAgentID` this widget edits. */\n @Input() Conversation: MJConversationEntity | null = null;\n\n /** Required for the Save() audit context. */\n @Input() CurrentUser: UserInfo | null = null;\n\n /** Disable the picker (e.g. read-only conversation). */\n @Input() Disabled: boolean = false;\n\n /**\n * The agents the chat allows (the chat area's `AllowedAgentIDs`). Only these can be pinned.\n * Null (the default) offers every eligible agent.\n */\n @Input()\n set AllowedAgentIDs(value: readonly string[] | null) {\n this._allowedAgentIDs = value ?? null;\n this.applyAllowedAgents();\n }\n get AllowedAgentIDs(): readonly string[] | null {\n return this._allowedAgentIDs;\n }\n\n /** Emitted after a successful save with the new (or null) agent ID. */\n @Output() AgentChanged = new EventEmitter<string | null>();\n\n public IsOpen = false;\n public EligibleAgents: MJAIAgentEntityExtended[] = [];\n\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly notifications = inject(MJNotificationService);\n private _allowedAgentIDs: readonly string[] | null = null;\n /** Every top-level, active agent, before the allowed list narrows it. */\n private catalogAgents: MJAIAgentEntityExtended[] = [];\n\n public async ngOnInit(): Promise<void> {\n try {\n // AIEngineBase is the live, cached agent catalog. Ensure it's\n // loaded — most app shells warm it up at boot, but the picker\n // could mount before that completes.\n await AIEngineBase.Instance.Config(false);\n this.catalogAgents = (AIEngineBase.Instance.Agents ?? [])\n .filter(a =>\n !a.ParentID &&\n a.Status === 'Active' &&\n a.InvocationMode !== 'Sub-Agent'\n )\n .sort((a, b) => (a.Name ?? '').localeCompare(b.Name ?? ''));\n this.applyAllowedAgents();\n } catch (err) {\n LogError(`ConversationAgentPicker.ngOnInit: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n /** Narrows the catalog to the allowed agents. */\n private applyAllowedAgents(): void {\n this.EligibleAgents = this.catalogAgents.filter(a => IsAgentAllowed(a.ID, this._allowedAgentIDs));\n this.cdr.markForCheck();\n }\n\n public get CurrentAgentLabel(): string {\n const id = this.Conversation?.DefaultAgentID;\n if (!id) return 'Auto';\n const match = this.EligibleAgents.find(a => UUIDsEqual(a.ID, id));\n // If the pinned agent is no longer eligible (deactivated, demoted to\n // sub-agent), still surface its name from the cache so the user can\n // see what was pinned even though they can't re-pin it.\n const fromCache = match\n ?? (AIEngineBase.Instance.Agents ?? []).find(a => UUIDsEqual(a.ID, id));\n return fromCache?.Name ?? 'Pinned agent';\n }\n\n public get ButtonTitle(): string {\n return this.Conversation?.DefaultAgentID\n ? `This conversation routes to ${this.CurrentAgentLabel}. Click to change.`\n : 'No agent pinned — messages route via the standard rules. Click to pin an agent.';\n }\n\n public IconClassFor(agent: MJAIAgentEntityExtended): string {\n return agent.IconClass?.trim() || 'fa-solid fa-robot';\n }\n\n public IsSelected(agent: MJAIAgentEntityExtended): boolean {\n return !!this.Conversation?.DefaultAgentID\n && UUIDsEqual(agent.ID, this.Conversation.DefaultAgentID);\n }\n\n public Toggle(event: MouseEvent): void {\n event.stopPropagation();\n if (this.Disabled || !this.Conversation) return;\n this.IsOpen = !this.IsOpen;\n this.cdr.markForCheck();\n }\n\n public async PickAgent(agent: MJAIAgentEntityExtended | null): Promise<void> {\n this.IsOpen = false;\n const conv = this.Conversation;\n if (!conv) return;\n const newId = agent?.ID ?? null;\n if (conv.DefaultAgentID === newId) {\n this.cdr.markForCheck();\n return;\n }\n const prev = conv.DefaultAgentID;\n conv.DefaultAgentID = newId;\n try {\n const saved = await conv.Save();\n if (!saved) {\n conv.DefaultAgentID = prev;\n this.notifications.CreateSimpleNotification(\n conv.LatestResult?.CompleteMessage ?? 'Failed to update conversation default agent.',\n 'error', 4500);\n return;\n }\n this.AgentChanged.emit(newId);\n } catch (err) {\n conv.DefaultAgentID = prev;\n LogError(`ConversationAgentPicker.PickAgent: ${err instanceof Error ? err.message : String(err)}`);\n } finally {\n this.cdr.markForCheck();\n }\n }\n\n /** Close the menu when the user clicks outside the picker. */\n @HostListener('document:click', ['$event'])\n public OnDocumentClick(_event: MouseEvent): void {\n if (this.IsOpen) {\n this.IsOpen = false;\n this.cdr.markForCheck();\n }\n }\n}\n"]}
1
+ {"version":3,"file":"conversation-agent-picker.component.js","sourceRoot":"","sources":["../../../../src/lib/components/conversation/conversation-agent-picker.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n EventEmitter,\n HostListener,\n Input,\n OnInit,\n Output,\n inject,\n} from '@angular/core';\nimport { LogError } from '@memberjunction/core';\nimport type { UserInfo } from '@memberjunction/core';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport type { MJAIAgentEntityExtended } from '@memberjunction/ai-core-plus';\nimport type { MJConversationEntity } from '@memberjunction/core-entities';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { IsAgentAllowed } from '@memberjunction/ai-core-plus';\n\n/**\n * Header widget that lets a user pin a default AI agent on the active\n * conversation. The pinned agent (saved to\n * `MJConversationEntity.DefaultAgentID`) takes precedence over the\n * embedder-supplied default in `MessageInputComponent.routeMessage()` —\n * non-mention messages route to it instead of Sage.\n *\n * Eligible agents are top-level, Active, non-Sub-Agent rows from\n * `AIEngineBase.Instance.ReadableAgents`. The widget renders as a compact button\n * showing the current pin (or \"Auto\" when nothing is pinned). Clicking\n * opens an inline list with a \"Clear\" option to remove the pin.\n *\n * The host controls visibility via `<mj-conversation-chat-area>`'s\n * `[showAgentPicker]` input (default true). Surfaces that don't want this\n * UX (e.g. agent-less embed) set it to false.\n */\n@Component({\n standalone: false,\n selector: 'mj-conversation-agent-picker',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"mj-cv-agent-picker\" [class.mj-cv-agent-picker--open]=\"IsOpen\">\n <button\n type=\"button\"\n class=\"mj-cv-agent-picker__trigger\"\n [title]=\"ButtonTitle\"\n [disabled]=\"Disabled || !Conversation\"\n (click)=\"Toggle($event)\">\n <i class=\"fa-solid fa-robot\"></i>\n <span class=\"mj-cv-agent-picker__label\">{{ CurrentAgentLabel }}</span>\n <i class=\"fa-solid fa-caret-down mj-cv-agent-picker__caret\"></i>\n </button>\n @if (IsOpen) {\n <div class=\"mj-cv-agent-picker__menu\" (click)=\"$event.stopPropagation()\">\n <div class=\"mj-cv-agent-picker__menu-header\">Default agent for this conversation</div>\n <button\n type=\"button\"\n class=\"mj-cv-agent-picker__item\"\n [class.mj-cv-agent-picker__item--selected]=\"!Conversation?.DefaultAgentID\"\n (click)=\"PickAgent(null)\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Auto (use default)</span>\n </button>\n @if (EligibleAgents.length === 0) {\n <div class=\"mj-cv-agent-picker__empty\">No agents available</div>\n } @else {\n @for (agent of EligibleAgents; track agent.ID) {\n <button\n type=\"button\"\n class=\"mj-cv-agent-picker__item\"\n [class.mj-cv-agent-picker__item--selected]=\"IsSelected(agent)\"\n [title]=\"agent.Description || agent.Name\"\n (click)=\"PickAgent(agent)\">\n <i [class]=\"IconClassFor(agent)\"></i>\n <span>{{ agent.Name }}</span>\n </button>\n }\n }\n </div>\n }\n </div>\n `,\n styles: [`\n /* Match mjButton size=\"sm\" so the trigger lines up with neighboring\n Export / Share buttons: min-height 32px, 6px/12px padding,\n 0.8125rem font. Same border-radius as the other chrome buttons. */\n .mj-cv-agent-picker { position: relative; display: inline-flex; align-items: center; }\n .mj-cv-agent-picker__trigger {\n display: inline-flex; align-items: center; gap: 6px;\n padding: 6px 12px; min-height: 32px; box-sizing: border-box;\n background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default);\n border-radius: 4px; cursor: pointer;\n color: var(--mj-text-primary); font-size: 0.8125rem; line-height: 1.5;\n transition: background 120ms, border-color 120ms;\n }\n .mj-cv-agent-picker__trigger:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover); border-color: var(--mj-border-strong);\n }\n .mj-cv-agent-picker__trigger:disabled { opacity: 0.5; cursor: not-allowed; }\n .mj-cv-agent-picker--open .mj-cv-agent-picker__trigger { border-color: var(--mj-border-focus); }\n .mj-cv-agent-picker__label { max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .mj-cv-agent-picker__caret { font-size: 10px; opacity: 0.7; }\n .mj-cv-agent-picker__menu {\n position: absolute; top: calc(100% + 4px); right: 0; z-index: 50;\n min-width: 220px; max-height: 320px; overflow-y: auto;\n background: var(--mj-bg-surface-elevated); border: 1px solid var(--mj-border-default);\n border-radius: 6px; box-shadow: 0 4px 16px rgba(0,0,0,0.12);\n padding: 4px 0;\n }\n .mj-cv-agent-picker__menu-header {\n padding: 6px 12px 4px; font-size: 11px; text-transform: uppercase;\n letter-spacing: 0.04em; color: var(--mj-text-muted);\n }\n .mj-cv-agent-picker__item {\n display: flex; align-items: center; gap: 8px; width: 100%;\n padding: 6px 12px; background: transparent; border: none; cursor: pointer;\n color: var(--mj-text-primary); font-size: 13px; text-align: left;\n }\n .mj-cv-agent-picker__item i { width: 14px; text-align: center; color: var(--mj-text-secondary); }\n .mj-cv-agent-picker__item:hover { background: var(--mj-bg-surface-hover); }\n .mj-cv-agent-picker__item--selected { background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent); }\n .mj-cv-agent-picker__item--selected i { color: var(--mj-brand-primary); }\n .mj-cv-agent-picker__empty { padding: 8px 12px; font-size: 12px; color: var(--mj-text-muted); }\n `]\n})\nexport class ConversationAgentPickerComponent implements OnInit {\n /** The conversation whose `DefaultAgentID` this widget edits. */\n @Input() Conversation: MJConversationEntity | null = null;\n\n /** Required for the Save() audit context. */\n @Input() CurrentUser: UserInfo | null = null;\n\n /** Disable the picker (e.g. read-only conversation). */\n @Input() Disabled: boolean = false;\n\n /**\n * The agents the chat allows (the chat area's `AllowedAgentIDs`). Only these can be pinned.\n * Null (the default) offers every eligible agent.\n */\n @Input()\n set AllowedAgentIDs(value: readonly string[] | null) {\n this._allowedAgentIDs = value ?? null;\n this.applyAllowedAgents();\n }\n get AllowedAgentIDs(): readonly string[] | null {\n return this._allowedAgentIDs;\n }\n\n /** Emitted after a successful save with the new (or null) agent ID. */\n @Output() AgentChanged = new EventEmitter<string | null>();\n\n public IsOpen = false;\n public EligibleAgents: MJAIAgentEntityExtended[] = [];\n\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly notifications = inject(MJNotificationService);\n private _allowedAgentIDs: readonly string[] | null = null;\n /** Every top-level, active agent, before the allowed list narrows it. */\n private catalogAgents: MJAIAgentEntityExtended[] = [];\n\n public async ngOnInit(): Promise<void> {\n try {\n // AIEngineBase is the live, cached agent catalog. Ensure it's\n // loaded — most app shells warm it up at boot, but the picker\n // could mount before that completes.\n await AIEngineBase.Instance.Config(false);\n this.catalogAgents = (AIEngineBase.Instance.ReadableAgents ?? [])\n .filter(a =>\n !a.ParentID &&\n a.Status === 'Active' &&\n a.InvocationMode !== 'Sub-Agent'\n )\n .sort((a, b) => (a.Name ?? '').localeCompare(b.Name ?? ''));\n this.applyAllowedAgents();\n } catch (err) {\n LogError(`ConversationAgentPicker.ngOnInit: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n /** Narrows the catalog to the allowed agents. */\n private applyAllowedAgents(): void {\n this.EligibleAgents = this.catalogAgents.filter(a => IsAgentAllowed(a.ID, this._allowedAgentIDs));\n this.cdr.markForCheck();\n }\n\n public get CurrentAgentLabel(): string {\n const id = this.Conversation?.DefaultAgentID;\n if (!id) return 'Auto';\n const match = this.EligibleAgents.find(a => UUIDsEqual(a.ID, id));\n // If the pinned agent is no longer eligible (deactivated, demoted to\n // sub-agent), still surface its name from the cache so the user can\n // see what was pinned even though they can't re-pin it.\n const fromCache = match\n ?? (AIEngineBase.Instance.ReadableAgents ?? []).find(a => UUIDsEqual(a.ID, id));\n return fromCache?.Name ?? 'Pinned agent';\n }\n\n public get ButtonTitle(): string {\n return this.Conversation?.DefaultAgentID\n ? `This conversation routes to ${this.CurrentAgentLabel}. Click to change.`\n : 'No agent pinned — messages route via the standard rules. Click to pin an agent.';\n }\n\n public IconClassFor(agent: MJAIAgentEntityExtended): string {\n return agent.IconClass?.trim() || 'fa-solid fa-robot';\n }\n\n public IsSelected(agent: MJAIAgentEntityExtended): boolean {\n return !!this.Conversation?.DefaultAgentID\n && UUIDsEqual(agent.ID, this.Conversation.DefaultAgentID);\n }\n\n public Toggle(event: MouseEvent): void {\n event.stopPropagation();\n if (this.Disabled || !this.Conversation) return;\n this.IsOpen = !this.IsOpen;\n this.cdr.markForCheck();\n }\n\n public async PickAgent(agent: MJAIAgentEntityExtended | null): Promise<void> {\n this.IsOpen = false;\n const conv = this.Conversation;\n if (!conv) return;\n const newId = agent?.ID ?? null;\n if (conv.DefaultAgentID === newId) {\n this.cdr.markForCheck();\n return;\n }\n const prev = conv.DefaultAgentID;\n conv.DefaultAgentID = newId;\n try {\n const saved = await conv.Save();\n if (!saved) {\n conv.DefaultAgentID = prev;\n this.notifications.CreateSimpleNotification(\n conv.LatestResult?.CompleteMessage ?? 'Failed to update conversation default agent.',\n 'error', 4500);\n return;\n }\n this.AgentChanged.emit(newId);\n } catch (err) {\n conv.DefaultAgentID = prev;\n LogError(`ConversationAgentPicker.PickAgent: ${err instanceof Error ? err.message : String(err)}`);\n } finally {\n this.cdr.markForCheck();\n }\n }\n\n /** Close the menu when the user clicks outside the picker. */\n @HostListener('document:click', ['$event'])\n public OnDocumentClick(_event: MouseEvent): void {\n if (this.IsOpen) {\n this.IsOpen = false;\n this.cdr.markForCheck();\n }\n }\n}\n"]}
@@ -2,7 +2,7 @@ import { EventEmitter, OnInit, OnDestroy, ChangeDetectorRef, TemplateRef, AfterV
2
2
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
3
3
  import { UserInfo, CompositeKey, DataSnapshot } from '@memberjunction/core';
4
4
  import { MJConversationEntity, MJConversationDetailEntity, MJAIAgentRunEntity, MJArtifactEntity, MJTaskEntity, RatingJSON, type ConversationScope, type ForkKind, type ForkSummary } from '@memberjunction/core-entities';
5
- import { MJAIAgentRunEntityExtended } from "@memberjunction/ai-core-plus";
5
+ import { MJAIAgentRunEntityExtended, OpenResourceCommand, type TaskGraphSpec } from "@memberjunction/ai-core-plus";
6
6
  import { UICommandHandlerService } from '../../services/ui-command-handler.service';
7
7
  import { AgentStateService } from '../../services/agent-state.service';
8
8
  import { ConversationLivenessDomService } from '../../services/conversation-liveness-dom.service';
@@ -176,6 +176,24 @@ export declare class ConversationChatAreaComponent extends BaseAngularComponent
176
176
  set allowRealtime(value: ConversationChatAreaComponent['AllowRealtime']);
177
177
  /** @deprecated Use {@link AllowRealtime}. */
178
178
  get allowRealtime(): ConversationChatAreaComponent['AllowRealtime'];
179
+ /**
180
+ * Host-level cap for starting conversation forks: Fork from here, and Edit or
181
+ * Regenerate as a fork. Defaults true (current behavior). Hosts with no forking
182
+ * experience set false; Edit and Regenerate then change the latest turn in place,
183
+ * as for a person without the `Conversations: Fork` authorization. UI only: deny
184
+ * that authorization to a role to stop the server creating forks as well.
185
+ */
186
+ AllowForking: boolean;
187
+ /**
188
+ * Host-level cap for stopping and continuing agent runs: the composer's Stop and Stop all, the
189
+ * Stop pill on an in-progress reply, the Continue button on a stopped reply, and the "Continue,
190
+ * or tell {agent} what to do differently" placeholder. Defaults true (current behavior). Hosts
191
+ * with no stop experience (a review surface, a space whose runs are managed elsewhere) set false
192
+ * without making the conversation read-only. UI only: a run stopped from another client still
193
+ * shows as stopped, and the next message still continues it. The composer's status line
194
+ * ({@link StatusText}) is not part of the cap: it reports that a reply is in flight either way.
195
+ */
196
+ AllowStopRun: boolean;
179
197
  /**
180
198
  * Whether the message list renders its built-in "No messages yet" filler
181
199
  * when a conversation has zero messages. Defaults true. Hosts that render
@@ -696,12 +714,6 @@ export declare class ConversationChatAreaComponent extends BaseAngularComponent
696
714
  */
697
715
  afterToolInvoked: EventEmitter<AfterToolInvokedEventArgs>;
698
716
  /** Cancelable — fired BEFORE a response form's submitted values are sent. */
699
- /**
700
- * Whether people may stop an in-progress agent run from its reply. Default true. A host can
701
- * turn it off for a surface (a view-only review, a space whose runs are managed elsewhere)
702
- * without making the conversation read-only.
703
- */
704
- AllowStopRun: boolean;
705
717
  BeforeResponseFormSubmitted: EventEmitter<BeforeResponseFormSubmittedEventArgs>;
706
718
  /**
707
719
  * @deprecated Use {@link BeforeResponseFormSubmitted}.
@@ -1028,6 +1040,14 @@ export declare class ConversationChatAreaComponent extends BaseAngularComponent
1028
1040
  /** Gap kept between the pane's top edge and the turn's first message. */
1029
1041
  private static readonly TURN_TOP_GAP_PX;
1030
1042
  private lastLoadedConversationId;
1043
+ /**
1044
+ * The conversation whose artifacts are currently held in {@link ArtifactsByDetailId}.
1045
+ * Unlike {@link lastLoadedConversationId} (which {@link resetComponentState} zeroes on every
1046
+ * message send / agent response to force {@link loadPeripheralData} to re-run), this stays set
1047
+ * to the owning conversation until {@link ArtifactsByDetailId} is actually cleared or rebuilt
1048
+ * for another conversation.
1049
+ */
1050
+ private artifactMapConversationId;
1031
1051
  private currentlyLoadingConversationId;
1032
1052
  private conversationLoadToken;
1033
1053
  /** The conversation whose load has ended; null while a load runs and before the first one. */
@@ -1119,6 +1139,10 @@ export declare class ConversationChatAreaComponent extends BaseAngularComponent
1119
1139
  /** @deprecated Use {@link ShowProjectSelector}. */
1120
1140
  set showProjectSelector(value: boolean);
1121
1141
  ShowArtifactPanel: boolean;
1142
+ SelectedTaskGraphPanel: {
1143
+ parentTaskId: string;
1144
+ workflowTitle: string;
1145
+ } | null;
1122
1146
  /** @deprecated Use {@link ShowArtifactPanel}. */
1123
1147
  get showArtifactPanel(): boolean;
1124
1148
  /** @deprecated Use {@link ShowArtifactPanel}. */
@@ -1263,6 +1287,8 @@ export declare class ConversationChatAreaComponent extends BaseAngularComponent
1263
1287
  get InProgressMessageIds(): string[];
1264
1288
  set InProgressMessageIds(value: string[]);
1265
1289
  private _inProgressMessageIds;
1290
+ /** Tracks the ID each in-progress reply entity was last registered under so adopting the server's row ID drops the local placeholder UUID. */
1291
+ private inProgressIdByEntity?;
1266
1292
  /** Replies the person asked to stop that have not left In-Progress yet. */
1267
1293
  StoppingDetailIds: Set<string>;
1268
1294
  private _stopFallbackTimers;
@@ -1277,9 +1303,15 @@ export declare class ConversationChatAreaComponent extends BaseAngularComponent
1277
1303
  get StopCount(): number;
1278
1304
  /** The slot's tooltip and accessible name: "Stop {agent}", or "Stop all N runs". */
1279
1305
  get StopLabel(): string;
1280
- /** The composer's status line: who is working, or what is being stopped. Null when the slot is Send. */
1306
+ /**
1307
+ * The composer's status line: who is working, or what is being stopped. Null with nothing in
1308
+ * flight. It is information, not a control, so it shows whenever a reply is in flight, whether
1309
+ * or not the viewer may stop it (a read-only viewer, or a host with {@link AllowStopRun} off);
1310
+ * only the send slot is gated. The stopping text likewise reads the stopping state itself, not
1311
+ * the slot's mode.
1312
+ */
1281
1313
  get StatusText(): string | null;
1282
- /** The elapsed time after the status line, for a single run that is working. */
1314
+ /** The elapsed time after the status line, for a single run that is working (not one being stopped). */
1283
1315
  get StatusElapsed(): string | null;
1284
1316
  /**
1285
1317
  * The composer's stop control. Every in-flight reply is stopped through the same path as the
@@ -1680,10 +1712,13 @@ export declare class ConversationChatAreaComponent extends BaseAngularComponent
1680
1712
  private resetConversationScopedViewState;
1681
1713
  private resetArtifactPaneSizing;
1682
1714
  private onConversationChanged;
1715
+ private _cachedInputsArray;
1716
+ private _cachedInputsKey;
1683
1717
  /**
1684
- * Returns array of cached message-input metadata for rendering
1718
+ * Returns array of cached message-input metadata for rendering.
1685
1719
  * This allows multiple message-input components to exist simultaneously (hidden)
1686
- * preserving their state when switching conversations
1720
+ * preserving their state when switching conversations.
1721
+ * Memoized on cache contents so template `@for` loops receive a stable array reference across CD ticks.
1687
1722
  */
1688
1723
  GetCachedInputs(): Array<{
1689
1724
  conversationId: string;
@@ -2363,11 +2398,13 @@ export declare class ConversationChatAreaComponent extends BaseAngularComponent
2363
2398
  get HasSystemArtifacts(): boolean;
2364
2399
  /** @deprecated Use {@link HasSystemArtifacts}. */
2365
2400
  get hasSystemArtifacts(): boolean;
2401
+ private _artifactsArrayCache;
2402
+ private _artifactsArrayKey;
2366
2403
  /**
2367
- * Get unique artifacts grouped by artifact ID (not by conversation detail)
2368
- * Returns the latest version info for each unique artifact with all versions
2369
- * Works with LazyArtifactInfo - uses display data without loading full entities
2370
- * Respects showSystemArtifacts toggle
2404
+ * Get unique artifacts grouped by artifact ID (not by conversation detail).
2405
+ * Returns the latest version info for each unique artifact with all versions.
2406
+ * Works with LazyArtifactInfo - uses display data without loading full entities.
2407
+ * Respects showSystemArtifacts toggle and memoizes the result across CD passes.
2371
2408
  */
2372
2409
  GetArtifactsArray(): Array<{
2373
2410
  artifactId: string;
@@ -2445,9 +2482,10 @@ export declare class ConversationChatAreaComponent extends BaseAngularComponent
2445
2482
  /** Read-only for any reason: the host said so, or the conversation is shared with View access. */
2446
2483
  get EffectiveReadOnly(): boolean;
2447
2484
  /**
2448
- * True when this person may start forks in the open conversation: holds `Conversations: Fork`, has not
2449
- * switched forking off in My Profile, and may write. When false, no fork action is offered and Edit and
2450
- * Regenerate change the latest turn in place.
2485
+ * True when this person may start forks in the open conversation: the host allows forking
2486
+ * ({@link AllowForking}), the person holds `Conversations: Fork`, has not switched forking off in My
2487
+ * Profile, and may write. When false, no fork action is offered and Edit and Regenerate change the
2488
+ * latest turn in place.
2451
2489
  */
2452
2490
  get CanFork(): boolean;
2453
2491
  /** The person's stored forking setting; undefined when there is none or the settings cannot be read. */
@@ -2579,6 +2617,20 @@ export declare class ConversationChatAreaComponent extends BaseAngularComponent
2579
2617
  artifactId: string;
2580
2618
  versionId?: string;
2581
2619
  }): Promise<void>;
2620
+ OnTaskGraphPanelRequested(data: {
2621
+ parentTaskId: string;
2622
+ workflowTitle?: string;
2623
+ workflowName?: string;
2624
+ isRunning?: boolean;
2625
+ }): void;
2626
+ IsSavingTaskGraphWorkflow: boolean;
2627
+ OnCloseTaskGraphPanel(): void;
2628
+ /**
2629
+ * Persists the currently displayed Task Graph in the chat side-panel as a reusable
2630
+ * Draft Flow Agent workflow via {@link WorkflowSaveOperation} and opens the new
2631
+ * `MJ: AI Agents` record.
2632
+ */
2633
+ OnSaveTaskGraphAsWorkflow(spec: TaskGraphSpec | null): Promise<void>;
2582
2634
  OnArtifactCreated(data: {
2583
2635
  conversationId: string;
2584
2636
  conversationDetailId: string;
@@ -2664,7 +2716,7 @@ export declare class ConversationChatAreaComponent extends BaseAngularComponent
2664
2716
  private onResizeTouchMove;
2665
2717
  private onResizeTouchEnd;
2666
2718
  /**
2667
- * LocalStorage persistence methods for artifact pane
2719
+ * UserInfoEngine persistence methods for artifact pane width
2668
2720
  */
2669
2721
  private loadArtifactPaneWidth;
2670
2722
  private saveArtifactPaneWidth;
@@ -2701,6 +2753,22 @@ export declare class ConversationChatAreaComponent extends BaseAngularComponent
2701
2753
  entityName: string;
2702
2754
  compositeKey: CompositeKey;
2703
2755
  }): void;
2756
+ /**
2757
+ * Returns true when an `open:resource` command refers to a conversation artifact or generated file
2758
+ * (either explicitly via `resourceType: 'Artifact' | 'File'` or via `resourceType: 'Record'` with
2759
+ * an artifact/file entity name).
2760
+ */
2761
+ private isConversationArtifactCommand;
2762
+ /**
2763
+ * Opens the matching (or most recent) artifact in the current conversation's artifact viewer panel.
2764
+ * Returns true if a conversation artifact was found and opened.
2765
+ */
2766
+ OpenConversationArtifactForCommand(command: OpenResourceCommand): boolean;
2767
+ /**
2768
+ * Handles non-Record `open:resource` commands when rendered inside the floating chat overlay
2769
+ * (`OverlayMode === true`), where `ChatConversationsResource` is not mounted.
2770
+ */
2771
+ private handleOverlayOpenResourceCommand;
2704
2772
  /** Record `open:resource` buttons → same openEntityRecord chain as agent-run links. */
2705
2773
  private emitOpenResourceRecord;
2706
2774
  OnNavigationRequest(event: NavigationRequest): void;
@@ -3126,6 +3194,6 @@ export declare class ConversationChatAreaComponent extends BaseAngularComponent
3126
3194
  conversationId: string;
3127
3195
  }): void;
3128
3196
  static ɵfac: i0.ɵɵFactoryDeclaration<ConversationChatAreaComponent, never>;
3129
- static ɵcmp: i0.ɵɵComponentDeclaration<ConversationChatAreaComponent, "mj-conversation-chat-area", never, { "EnvironmentId": { "alias": "EnvironmentId"; "required": false; }; "environmentId": { "alias": "environmentId"; "required": false; }; "CurrentUser": { "alias": "CurrentUser"; "required": false; }; "currentUser": { "alias": "currentUser"; "required": false; }; "ConversationId": { "alias": "ConversationId"; "required": false; }; "conversationId": { "alias": "conversationId"; "required": false; }; "Conversation": { "alias": "Conversation"; "required": false; }; "conversation": { "alias": "conversation"; "required": false; }; "SuppressNewConversationEmptyState": { "alias": "SuppressNewConversationEmptyState"; "required": false; }; "suppressNewConversationEmptyState": { "alias": "suppressNewConversationEmptyState"; "required": false; }; "AllowMentions": { "alias": "AllowMentions"; "required": false; }; "allowMentions": { "alias": "allowMentions"; "required": false; }; "AllowAgentMentions": { "alias": "AllowAgentMentions"; "required": false; }; "allowAgentMentions": { "alias": "allowAgentMentions"; "required": false; }; "AllowEntityMentions": { "alias": "AllowEntityMentions"; "required": false; }; "allowEntityMentions": { "alias": "allowEntityMentions"; "required": false; }; "AllowSkillCommands": { "alias": "AllowSkillCommands"; "required": false; }; "allowSkillCommands": { "alias": "allowSkillCommands"; "required": false; }; "AllowAttachments": { "alias": "AllowAttachments"; "required": false; }; "allowAttachments": { "alias": "allowAttachments"; "required": false; }; "AllowPlanMode": { "alias": "AllowPlanMode"; "required": false; }; "allowPlanMode": { "alias": "allowPlanMode"; "required": false; }; "AllowRealtime": { "alias": "AllowRealtime"; "required": false; }; "allowRealtime": { "alias": "allowRealtime"; "required": false; }; "ShowEmptyFill": { "alias": "ShowEmptyFill"; "required": false; }; "showEmptyFill": { "alias": "showEmptyFill"; "required": false; }; "ShowLoadingState": { "alias": "ShowLoadingState"; "required": false; }; "showLoadingState": { "alias": "showLoadingState"; "required": false; }; "ReadReplyFromTop": { "alias": "ReadReplyFromTop"; "required": false; }; "readReplyFromTop": { "alias": "readReplyFromTop"; "required": false; }; "ShowAgentRunDetails": { "alias": "ShowAgentRunDetails"; "required": false; }; "showAgentRunDetails": { "alias": "showAgentRunDetails"; "required": false; }; "ShowReactions": { "alias": "ShowReactions"; "required": false; }; "showReactions": { "alias": "showReactions"; "required": false; }; "ShowMessageRating": { "alias": "ShowMessageRating"; "required": false; }; "showMessageRating": { "alias": "showMessageRating"; "required": false; }; "AllowPinning": { "alias": "AllowPinning"; "required": false; }; "allowPinning": { "alias": "allowPinning"; "required": false; }; "AllowMessageEdit": { "alias": "AllowMessageEdit"; "required": false; }; "allowMessageEdit": { "alias": "allowMessageEdit"; "required": false; }; "AllowMessageDelete": { "alias": "AllowMessageDelete"; "required": false; }; "allowMessageDelete": { "alias": "allowMessageDelete"; "required": false; }; "ReadOnly": { "alias": "ReadOnly"; "required": false; }; "ReadOnlyMessage": { "alias": "ReadOnlyMessage"; "required": false; }; "ShowSuggestedPrompts": { "alias": "ShowSuggestedPrompts"; "required": false; }; "showSuggestedPrompts": { "alias": "showSuggestedPrompts"; "required": false; }; "ShowDateNavigation": { "alias": "ShowDateNavigation"; "required": false; }; "showDateNavigation": { "alias": "showDateNavigation"; "required": false; }; "AssistantDisplayName": { "alias": "AssistantDisplayName"; "required": false; }; "assistantDisplayName": { "alias": "assistantDisplayName"; "required": false; }; "AssistantAvatarUrl": { "alias": "AssistantAvatarUrl"; "required": false; }; "assistantAvatarUrl": { "alias": "assistantAvatarUrl"; "required": false; }; "IsNewConversation": { "alias": "IsNewConversation"; "required": false; }; "isNewConversation": { "alias": "isNewConversation"; "required": false; }; "PendingMessage": { "alias": "PendingMessage"; "required": false; }; "pendingMessage": { "alias": "pendingMessage"; "required": false; }; "PendingMessageConversationId": { "alias": "PendingMessageConversationId"; "required": false; }; "pendingMessageConversationId": { "alias": "pendingMessageConversationId"; "required": false; }; "PendingAttachments": { "alias": "PendingAttachments"; "required": false; }; "pendingAttachments": { "alias": "pendingAttachments"; "required": false; }; "PendingArtifactId": { "alias": "PendingArtifactId"; "required": false; }; "pendingArtifactId": { "alias": "pendingArtifactId"; "required": false; }; "PendingArtifactVersionNumber": { "alias": "PendingArtifactVersionNumber"; "required": false; }; "pendingArtifactVersionNumber": { "alias": "pendingArtifactVersionNumber"; "required": false; }; "PendingArtifactConversationId": { "alias": "PendingArtifactConversationId"; "required": false; }; "pendingArtifactConversationId": { "alias": "pendingArtifactConversationId"; "required": false; }; "OverlayMode": { "alias": "OverlayMode"; "required": false; }; "overlayMode": { "alias": "overlayMode"; "required": false; }; "ShowExportButton": { "alias": "ShowExportButton"; "required": false; }; "showExportButton": { "alias": "showExportButton"; "required": false; }; "ExportButtonLabel": { "alias": "ExportButtonLabel"; "required": false; }; "exportButtonLabel": { "alias": "exportButtonLabel"; "required": false; }; "ExportButtonIcon": { "alias": "ExportButtonIcon"; "required": false; }; "exportButtonIcon": { "alias": "exportButtonIcon"; "required": false; }; "ExportBranding": { "alias": "ExportBranding"; "required": false; }; "exportBranding": { "alias": "exportBranding"; "required": false; }; "ShowShareButton": { "alias": "ShowShareButton"; "required": false; }; "showShareButton": { "alias": "showShareButton"; "required": false; }; "ShowArtifactIndicator": { "alias": "ShowArtifactIndicator"; "required": false; }; "showArtifactIndicator": { "alias": "showArtifactIndicator"; "required": false; }; "AppContext": { "alias": "AppContext"; "required": false; }; "appContext": { "alias": "appContext"; "required": false; }; "DefaultAgentId": { "alias": "DefaultAgentId"; "required": false; }; "defaultAgentId": { "alias": "defaultAgentId"; "required": false; }; "AgentReplyMode": { "alias": "AgentReplyMode"; "required": false; }; "AllowedAgentIDs": { "alias": "AllowedAgentIDs"; "required": false; }; "MentionPeople": { "alias": "MentionPeople"; "required": false; }; "AgentHistoryFrom": { "alias": "AgentHistoryFrom"; "required": false; }; "AgentTurnHandler": { "alias": "AgentTurnHandler"; "required": false; }; "AutoNameConversation": { "alias": "AutoNameConversation"; "required": false; }; "EnableDecisionRouting": { "alias": "EnableDecisionRouting"; "required": false; }; "ApplicationScope": { "alias": "ApplicationScope"; "required": false; }; "applicationScope": { "alias": "applicationScope"; "required": false; }; "ApplicationId": { "alias": "ApplicationId"; "required": false; }; "applicationId": { "alias": "applicationId"; "required": false; }; "LinkedEntityId": { "alias": "LinkedEntityId"; "required": false; }; "linkedEntityId": { "alias": "linkedEntityId"; "required": false; }; "LinkedRecordId": { "alias": "LinkedRecordId"; "required": false; }; "linkedRecordId": { "alias": "linkedRecordId"; "required": false; }; "ShowAgentPicker": { "alias": "ShowAgentPicker"; "required": false; }; "showAgentPicker": { "alias": "showAgentPicker"; "required": false; }; "ShowAgentModePicker": { "alias": "ShowAgentModePicker"; "required": false; }; "showAgentModePicker": { "alias": "showAgentModePicker"; "required": false; }; "EmptyStateGreeting": { "alias": "EmptyStateGreeting"; "required": false; }; "emptyStateGreeting": { "alias": "emptyStateGreeting"; "required": false; }; "ShowSidebarToggle": { "alias": "ShowSidebarToggle"; "required": false; }; "showSidebarToggle": { "alias": "showSidebarToggle"; "required": false; }; "ShowAgentCharacter": { "alias": "ShowAgentCharacter"; "required": false; }; "showAgentCharacter": { "alias": "showAgentCharacter"; "required": false; }; "AgentCharacterConfig": { "alias": "AgentCharacterConfig"; "required": false; }; "agentCharacterConfig": { "alias": "agentCharacterConfig"; "required": false; }; "EmptyStateConfig": { "alias": "EmptyStateConfig"; "required": false; }; "emptyStateConfig": { "alias": "emptyStateConfig"; "required": false; }; "ShowDemonstrationSurface": { "alias": "ShowDemonstrationSurface"; "required": false; }; "showDemonstrationSurface": { "alias": "showDemonstrationSurface"; "required": false; }; "DemonstrationSurfaceContent": { "alias": "DemonstrationSurfaceContent"; "required": false; }; "demonstrationSurfaceContent": { "alias": "demonstrationSurfaceContent"; "required": false; }; "AllowStopRun": { "alias": "AllowStopRun"; "required": false; }; "ComposerDraft": { "alias": "ComposerDraft"; "required": false; }; "composerDraft": { "alias": "composerDraft"; "required": false; }; "ComposerAgentMention": { "alias": "ComposerAgentMention"; "required": false; }; "composerAgentMention": { "alias": "composerAgentMention"; "required": false; }; }, { "BeforeAgentTurn": "BeforeAgentTurn"; "beforeAgentTurn": "beforeAgentTurn"; "AfterAgentTurn": "AfterAgentTurn"; "afterAgentTurn": "afterAgentTurn"; "BeforeToolInvoked": "BeforeToolInvoked"; "beforeToolInvoked": "beforeToolInvoked"; "AfterToolInvoked": "AfterToolInvoked"; "afterToolInvoked": "afterToolInvoked"; "BeforeResponseFormSubmitted": "BeforeResponseFormSubmitted"; "beforeResponseFormSubmitted": "beforeResponseFormSubmitted"; "AfterResponseFormSubmitted": "AfterResponseFormSubmitted"; "afterResponseFormSubmitted": "afterResponseFormSubmitted"; "BeforeStopClicked": "BeforeStopClicked"; "AfterStopClicked": "AfterStopClicked"; "SessionStarted": "SessionStarted"; "sessionStarted": "sessionStarted"; "SessionChannelStateChanged": "SessionChannelStateChanged"; "sessionChannelStateChanged": "sessionChannelStateChanged"; "SessionEnded": "SessionEnded"; "sessionEnded": "sessionEnded"; "ConversationRenamed": "ConversationRenamed"; "conversationRenamed": "conversationRenamed"; "OpenEntityRecord": "OpenEntityRecord"; "openEntityRecord": "openEntityRecord"; "RealtimeConversationReady": "RealtimeConversationReady"; "realtimeConversationReady": "realtimeConversationReady"; "navigationRequest": "navigationRequest"; "TaskClicked": "TaskClicked"; "taskClicked": "taskClicked"; "ArtifactLinkClicked": "ArtifactLinkClicked"; "artifactLinkClicked": "artifactLinkClicked"; "SidebarToggleClicked": "SidebarToggleClicked"; "sidebarToggleClicked": "sidebarToggleClicked"; "ConversationCreated": "ConversationCreated"; "conversationCreated": "conversationCreated"; "PendingArtifactConsumed": "PendingArtifactConsumed"; "pendingArtifactConsumed": "pendingArtifactConsumed"; "PendingMessageConsumed": "PendingMessageConsumed"; "pendingMessageConsumed": "pendingMessageConsumed"; "PendingMessageRequested": "PendingMessageRequested"; "pendingMessageRequested": "pendingMessageRequested"; "ComposerDraftConsumed": "ComposerDraftConsumed"; "composerDraftConsumed": "composerDraftConsumed"; "ComposerAgentMentionConsumed": "ComposerAgentMentionConsumed"; "composerAgentMentionConsumed": "composerAgentMentionConsumed"; }, ["chatSlotChildren"], never, false, never>;
3197
+ static ɵcmp: i0.ɵɵComponentDeclaration<ConversationChatAreaComponent, "mj-conversation-chat-area", never, { "EnvironmentId": { "alias": "EnvironmentId"; "required": false; }; "environmentId": { "alias": "environmentId"; "required": false; }; "CurrentUser": { "alias": "CurrentUser"; "required": false; }; "currentUser": { "alias": "currentUser"; "required": false; }; "ConversationId": { "alias": "ConversationId"; "required": false; }; "conversationId": { "alias": "conversationId"; "required": false; }; "Conversation": { "alias": "Conversation"; "required": false; }; "conversation": { "alias": "conversation"; "required": false; }; "SuppressNewConversationEmptyState": { "alias": "SuppressNewConversationEmptyState"; "required": false; }; "suppressNewConversationEmptyState": { "alias": "suppressNewConversationEmptyState"; "required": false; }; "AllowMentions": { "alias": "AllowMentions"; "required": false; }; "allowMentions": { "alias": "allowMentions"; "required": false; }; "AllowAgentMentions": { "alias": "AllowAgentMentions"; "required": false; }; "allowAgentMentions": { "alias": "allowAgentMentions"; "required": false; }; "AllowEntityMentions": { "alias": "AllowEntityMentions"; "required": false; }; "allowEntityMentions": { "alias": "allowEntityMentions"; "required": false; }; "AllowSkillCommands": { "alias": "AllowSkillCommands"; "required": false; }; "allowSkillCommands": { "alias": "allowSkillCommands"; "required": false; }; "AllowAttachments": { "alias": "AllowAttachments"; "required": false; }; "allowAttachments": { "alias": "allowAttachments"; "required": false; }; "AllowPlanMode": { "alias": "AllowPlanMode"; "required": false; }; "allowPlanMode": { "alias": "allowPlanMode"; "required": false; }; "AllowRealtime": { "alias": "AllowRealtime"; "required": false; }; "allowRealtime": { "alias": "allowRealtime"; "required": false; }; "AllowForking": { "alias": "AllowForking"; "required": false; }; "AllowStopRun": { "alias": "AllowStopRun"; "required": false; }; "ShowEmptyFill": { "alias": "ShowEmptyFill"; "required": false; }; "showEmptyFill": { "alias": "showEmptyFill"; "required": false; }; "ShowLoadingState": { "alias": "ShowLoadingState"; "required": false; }; "showLoadingState": { "alias": "showLoadingState"; "required": false; }; "ReadReplyFromTop": { "alias": "ReadReplyFromTop"; "required": false; }; "readReplyFromTop": { "alias": "readReplyFromTop"; "required": false; }; "ShowAgentRunDetails": { "alias": "ShowAgentRunDetails"; "required": false; }; "showAgentRunDetails": { "alias": "showAgentRunDetails"; "required": false; }; "ShowReactions": { "alias": "ShowReactions"; "required": false; }; "showReactions": { "alias": "showReactions"; "required": false; }; "ShowMessageRating": { "alias": "ShowMessageRating"; "required": false; }; "showMessageRating": { "alias": "showMessageRating"; "required": false; }; "AllowPinning": { "alias": "AllowPinning"; "required": false; }; "allowPinning": { "alias": "allowPinning"; "required": false; }; "AllowMessageEdit": { "alias": "AllowMessageEdit"; "required": false; }; "allowMessageEdit": { "alias": "allowMessageEdit"; "required": false; }; "AllowMessageDelete": { "alias": "AllowMessageDelete"; "required": false; }; "allowMessageDelete": { "alias": "allowMessageDelete"; "required": false; }; "ReadOnly": { "alias": "ReadOnly"; "required": false; }; "ReadOnlyMessage": { "alias": "ReadOnlyMessage"; "required": false; }; "ShowSuggestedPrompts": { "alias": "ShowSuggestedPrompts"; "required": false; }; "showSuggestedPrompts": { "alias": "showSuggestedPrompts"; "required": false; }; "ShowDateNavigation": { "alias": "ShowDateNavigation"; "required": false; }; "showDateNavigation": { "alias": "showDateNavigation"; "required": false; }; "AssistantDisplayName": { "alias": "AssistantDisplayName"; "required": false; }; "assistantDisplayName": { "alias": "assistantDisplayName"; "required": false; }; "AssistantAvatarUrl": { "alias": "AssistantAvatarUrl"; "required": false; }; "assistantAvatarUrl": { "alias": "assistantAvatarUrl"; "required": false; }; "IsNewConversation": { "alias": "IsNewConversation"; "required": false; }; "isNewConversation": { "alias": "isNewConversation"; "required": false; }; "PendingMessage": { "alias": "PendingMessage"; "required": false; }; "pendingMessage": { "alias": "pendingMessage"; "required": false; }; "PendingMessageConversationId": { "alias": "PendingMessageConversationId"; "required": false; }; "pendingMessageConversationId": { "alias": "pendingMessageConversationId"; "required": false; }; "PendingAttachments": { "alias": "PendingAttachments"; "required": false; }; "pendingAttachments": { "alias": "pendingAttachments"; "required": false; }; "PendingArtifactId": { "alias": "PendingArtifactId"; "required": false; }; "pendingArtifactId": { "alias": "pendingArtifactId"; "required": false; }; "PendingArtifactVersionNumber": { "alias": "PendingArtifactVersionNumber"; "required": false; }; "pendingArtifactVersionNumber": { "alias": "pendingArtifactVersionNumber"; "required": false; }; "PendingArtifactConversationId": { "alias": "PendingArtifactConversationId"; "required": false; }; "pendingArtifactConversationId": { "alias": "pendingArtifactConversationId"; "required": false; }; "OverlayMode": { "alias": "OverlayMode"; "required": false; }; "overlayMode": { "alias": "overlayMode"; "required": false; }; "ShowExportButton": { "alias": "ShowExportButton"; "required": false; }; "showExportButton": { "alias": "showExportButton"; "required": false; }; "ExportButtonLabel": { "alias": "ExportButtonLabel"; "required": false; }; "exportButtonLabel": { "alias": "exportButtonLabel"; "required": false; }; "ExportButtonIcon": { "alias": "ExportButtonIcon"; "required": false; }; "exportButtonIcon": { "alias": "exportButtonIcon"; "required": false; }; "ExportBranding": { "alias": "ExportBranding"; "required": false; }; "exportBranding": { "alias": "exportBranding"; "required": false; }; "ShowShareButton": { "alias": "ShowShareButton"; "required": false; }; "showShareButton": { "alias": "showShareButton"; "required": false; }; "ShowArtifactIndicator": { "alias": "ShowArtifactIndicator"; "required": false; }; "showArtifactIndicator": { "alias": "showArtifactIndicator"; "required": false; }; "AppContext": { "alias": "AppContext"; "required": false; }; "appContext": { "alias": "appContext"; "required": false; }; "DefaultAgentId": { "alias": "DefaultAgentId"; "required": false; }; "defaultAgentId": { "alias": "defaultAgentId"; "required": false; }; "AgentReplyMode": { "alias": "AgentReplyMode"; "required": false; }; "AllowedAgentIDs": { "alias": "AllowedAgentIDs"; "required": false; }; "MentionPeople": { "alias": "MentionPeople"; "required": false; }; "AgentHistoryFrom": { "alias": "AgentHistoryFrom"; "required": false; }; "AgentTurnHandler": { "alias": "AgentTurnHandler"; "required": false; }; "AutoNameConversation": { "alias": "AutoNameConversation"; "required": false; }; "EnableDecisionRouting": { "alias": "EnableDecisionRouting"; "required": false; }; "ApplicationScope": { "alias": "ApplicationScope"; "required": false; }; "applicationScope": { "alias": "applicationScope"; "required": false; }; "ApplicationId": { "alias": "ApplicationId"; "required": false; }; "applicationId": { "alias": "applicationId"; "required": false; }; "LinkedEntityId": { "alias": "LinkedEntityId"; "required": false; }; "linkedEntityId": { "alias": "linkedEntityId"; "required": false; }; "LinkedRecordId": { "alias": "LinkedRecordId"; "required": false; }; "linkedRecordId": { "alias": "linkedRecordId"; "required": false; }; "ShowAgentPicker": { "alias": "ShowAgentPicker"; "required": false; }; "showAgentPicker": { "alias": "showAgentPicker"; "required": false; }; "ShowAgentModePicker": { "alias": "ShowAgentModePicker"; "required": false; }; "showAgentModePicker": { "alias": "showAgentModePicker"; "required": false; }; "EmptyStateGreeting": { "alias": "EmptyStateGreeting"; "required": false; }; "emptyStateGreeting": { "alias": "emptyStateGreeting"; "required": false; }; "ShowSidebarToggle": { "alias": "ShowSidebarToggle"; "required": false; }; "showSidebarToggle": { "alias": "showSidebarToggle"; "required": false; }; "ShowAgentCharacter": { "alias": "ShowAgentCharacter"; "required": false; }; "showAgentCharacter": { "alias": "showAgentCharacter"; "required": false; }; "AgentCharacterConfig": { "alias": "AgentCharacterConfig"; "required": false; }; "agentCharacterConfig": { "alias": "agentCharacterConfig"; "required": false; }; "EmptyStateConfig": { "alias": "EmptyStateConfig"; "required": false; }; "emptyStateConfig": { "alias": "emptyStateConfig"; "required": false; }; "ShowDemonstrationSurface": { "alias": "ShowDemonstrationSurface"; "required": false; }; "showDemonstrationSurface": { "alias": "showDemonstrationSurface"; "required": false; }; "DemonstrationSurfaceContent": { "alias": "DemonstrationSurfaceContent"; "required": false; }; "demonstrationSurfaceContent": { "alias": "demonstrationSurfaceContent"; "required": false; }; "ComposerDraft": { "alias": "ComposerDraft"; "required": false; }; "composerDraft": { "alias": "composerDraft"; "required": false; }; "ComposerAgentMention": { "alias": "ComposerAgentMention"; "required": false; }; "composerAgentMention": { "alias": "composerAgentMention"; "required": false; }; }, { "BeforeAgentTurn": "BeforeAgentTurn"; "beforeAgentTurn": "beforeAgentTurn"; "AfterAgentTurn": "AfterAgentTurn"; "afterAgentTurn": "afterAgentTurn"; "BeforeToolInvoked": "BeforeToolInvoked"; "beforeToolInvoked": "beforeToolInvoked"; "AfterToolInvoked": "AfterToolInvoked"; "afterToolInvoked": "afterToolInvoked"; "BeforeResponseFormSubmitted": "BeforeResponseFormSubmitted"; "beforeResponseFormSubmitted": "beforeResponseFormSubmitted"; "AfterResponseFormSubmitted": "AfterResponseFormSubmitted"; "afterResponseFormSubmitted": "afterResponseFormSubmitted"; "BeforeStopClicked": "BeforeStopClicked"; "AfterStopClicked": "AfterStopClicked"; "SessionStarted": "SessionStarted"; "sessionStarted": "sessionStarted"; "SessionChannelStateChanged": "SessionChannelStateChanged"; "sessionChannelStateChanged": "sessionChannelStateChanged"; "SessionEnded": "SessionEnded"; "sessionEnded": "sessionEnded"; "ConversationRenamed": "ConversationRenamed"; "conversationRenamed": "conversationRenamed"; "OpenEntityRecord": "OpenEntityRecord"; "openEntityRecord": "openEntityRecord"; "RealtimeConversationReady": "RealtimeConversationReady"; "realtimeConversationReady": "realtimeConversationReady"; "navigationRequest": "navigationRequest"; "TaskClicked": "TaskClicked"; "taskClicked": "taskClicked"; "ArtifactLinkClicked": "ArtifactLinkClicked"; "artifactLinkClicked": "artifactLinkClicked"; "SidebarToggleClicked": "SidebarToggleClicked"; "sidebarToggleClicked": "sidebarToggleClicked"; "ConversationCreated": "ConversationCreated"; "conversationCreated": "conversationCreated"; "PendingArtifactConsumed": "PendingArtifactConsumed"; "pendingArtifactConsumed": "pendingArtifactConsumed"; "PendingMessageConsumed": "PendingMessageConsumed"; "pendingMessageConsumed": "pendingMessageConsumed"; "PendingMessageRequested": "PendingMessageRequested"; "pendingMessageRequested": "pendingMessageRequested"; "ComposerDraftConsumed": "ComposerDraftConsumed"; "composerDraftConsumed": "composerDraftConsumed"; "ComposerAgentMentionConsumed": "ComposerAgentMentionConsumed"; "composerAgentMentionConsumed": "composerAgentMentionConsumed"; }, ["chatSlotChildren"], never, false, never>;
3130
3198
  }
3131
3199
  //# sourceMappingURL=conversation-chat-area.component.d.ts.map