@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.
- package/README.md +29 -0
- package/dist/lib/components/attachment/image-viewer.component.d.ts +3 -1
- package/dist/lib/components/attachment/image-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/attachment/image-viewer.component.js +5 -1
- package/dist/lib/components/attachment/image-viewer.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-agent-picker.component.d.ts +1 -1
- package/dist/lib/components/conversation/conversation-agent-picker.component.js +3 -3
- package/dist/lib/components/conversation/conversation-agent-picker.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +88 -20
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +785 -387
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +60 -20
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +290 -389
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +153 -17
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +1400 -299
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +25 -2
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +79 -40
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.d.ts +19 -0
- package/dist/lib/components/overlay/chat-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.js +125 -13
- package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.js +2 -2
- package/dist/lib/components/project/project-form-modal.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +6 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.js +110 -82
- package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-call-failure-notice.d.ts +13 -0
- package/dist/lib/components/realtime/realtime-call-failure-notice.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-call-failure-notice.js +21 -0
- package/dist/lib/components/realtime/realtime-call-failure-notice.js.map +1 -0
- package/dist/lib/components/realtime/realtime-composer.component.js +114 -102
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +21 -2
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +113 -76
- package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +7 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
- package/dist/lib/components/sidebar/routines-section.component.js +1 -1
- package/dist/lib/components/sidebar/routines-section.component.js.map +1 -1
- package/dist/lib/components/task/tasks-full-view.component.d.ts +152 -31
- package/dist/lib/components/task/tasks-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/task/tasks-full-view.component.js +2227 -214
- package/dist/lib/components/task/tasks-full-view.component.js.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.js +4 -4
- package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +11 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +25 -28
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/services/agent-state.service.d.ts.map +1 -1
- package/dist/lib/services/agent-state.service.js +8 -8
- package/dist/lib/services/agent-state.service.js.map +1 -1
- package/dist/lib/services/browser-realtime-media-host.d.ts +7 -7
- package/dist/lib/services/browser-realtime-media-host.js +8 -78
- package/dist/lib/services/browser-realtime-media-host.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts +53 -20
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +108 -54
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-detail-window.store.d.ts +5 -0
- package/dist/lib/services/conversation-detail-window.store.d.ts.map +1 -1
- package/dist/lib/services/conversation-detail-window.store.js +52 -5
- package/dist/lib/services/conversation-detail-window.store.js.map +1 -1
- package/dist/lib/services/conversation-naming.d.ts.map +1 -1
- package/dist/lib/services/conversation-naming.js +9 -2
- package/dist/lib/services/conversation-naming.js.map +1 -1
- package/dist/lib/services/conversation-tasks-filter.d.ts +15 -0
- package/dist/lib/services/conversation-tasks-filter.d.ts.map +1 -0
- package/dist/lib/services/conversation-tasks-filter.js +69 -0
- package/dist/lib/services/conversation-tasks-filter.js.map +1 -0
- package/dist/lib/services/realtime-audio-recorder.d.ts +94 -86
- package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -1
- package/dist/lib/services/realtime-audio-recorder.js +222 -195
- package/dist/lib/services/realtime-audio-recorder.js.map +1 -1
- package/dist/lib/services/realtime-session.service.d.ts +30 -2
- package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session.service.js +35 -7
- package/dist/lib/services/realtime-session.service.js.map +1 -1
- package/dist/lib/services/recording/libopus-wasm-binary.d.ts +3 -0
- package/dist/lib/services/recording/libopus-wasm-binary.d.ts.map +1 -0
- package/dist/lib/services/recording/libopus-wasm-binary.js +489 -0
- package/dist/lib/services/recording/libopus-wasm-binary.js.map +1 -0
- package/dist/lib/services/recording/libopus-worker-source.d.ts +48 -0
- package/dist/lib/services/recording/libopus-worker-source.d.ts.map +1 -0
- package/dist/lib/services/recording/libopus-worker-source.js +170 -0
- package/dist/lib/services/recording/libopus-worker-source.js.map +1 -0
- package/dist/lib/services/recording/linear-resampler.d.ts +45 -0
- package/dist/lib/services/recording/linear-resampler.d.ts.map +1 -0
- package/dist/lib/services/recording/linear-resampler.js +85 -0
- package/dist/lib/services/recording/linear-resampler.js.map +1 -0
- package/dist/lib/services/recording/opus-packet-encoder.d.ts +50 -0
- package/dist/lib/services/recording/opus-packet-encoder.d.ts.map +1 -0
- package/dist/lib/services/recording/opus-packet-encoder.js +41 -0
- package/dist/lib/services/recording/opus-packet-encoder.js.map +1 -0
- package/dist/lib/services/recording/wasm-opus-encoder.d.ts +86 -0
- package/dist/lib/services/recording/wasm-opus-encoder.d.ts.map +1 -0
- package/dist/lib/services/recording/wasm-opus-encoder.js +232 -0
- package/dist/lib/services/recording/wasm-opus-encoder.js.map +1 -0
- package/dist/lib/services/recording/webcodecs-opus-encoder.d.ts +39 -0
- package/dist/lib/services/recording/webcodecs-opus-encoder.d.ts.map +1 -0
- package/dist/lib/services/recording/webcodecs-opus-encoder.js +101 -0
- package/dist/lib/services/recording/webcodecs-opus-encoder.js.map +1 -0
- package/dist/lib/services/search.service.d.ts.map +1 -1
- package/dist/lib/services/search.service.js +3 -16
- package/dist/lib/services/search.service.js.map +1 -1
- package/dist/lib/utils/agent-failure-display.d.ts +14 -0
- package/dist/lib/utils/agent-failure-display.d.ts.map +1 -0
- package/dist/lib/utils/agent-failure-display.js +26 -0
- package/dist/lib/utils/agent-failure-display.js.map +1 -0
- package/dist/lib/utils/distinct-artifacts.d.ts +9 -3
- package/dist/lib/utils/distinct-artifacts.d.ts.map +1 -1
- package/dist/lib/utils/distinct-artifacts.js +24 -5
- package/dist/lib/utils/distinct-artifacts.js.map +1 -1
- package/dist/lib/utils/message-list-order.d.ts +13 -0
- package/dist/lib/utils/message-list-order.d.ts.map +1 -0
- package/dist/lib/utils/message-list-order.js +31 -0
- package/dist/lib/utils/message-list-order.js.map +1 -0
- package/dist/lib/utils/pin-state.d.ts +11 -0
- package/dist/lib/utils/pin-state.d.ts.map +1 -0
- package/dist/lib/utils/pin-state.js +9 -0
- package/dist/lib/utils/pin-state.js.map +1 -0
- package/dist/public-api.d.ts +1 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +36 -36
- package/dist/lib/services/browser-recording-unload-guard.d.ts +0 -30
- package/dist/lib/services/browser-recording-unload-guard.d.ts.map +0 -1
- package/dist/lib/services/browser-recording-unload-guard.js +0 -43
- package/dist/lib/services/browser-recording-unload-guard.js.map +0 -1
- package/dist/lib/services/realtime-pcm-wav.d.ts +0 -79
- package/dist/lib/services/realtime-pcm-wav.d.ts.map +0 -1
- package/dist/lib/services/realtime-pcm-wav.js +0 -213
- 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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
/**
|
|
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:
|
|
2449
|
-
*
|
|
2450
|
-
*
|
|
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
|
-
*
|
|
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
|