@memberjunction/ng-conversations 5.22.0 → 5.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/dist/lib/components/artifact/artifact-share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/artifact/artifact-share-modal.component.js +58 -60
- package/dist/lib/components/artifact/artifact-share-modal.component.js.map +1 -1
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.js +31 -32
- package/dist/lib/components/collection/artifact-collection-picker-modal.component.js.map +1 -1
- package/dist/lib/components/collection/artifact-create-modal.component.d.ts +1 -0
- package/dist/lib/components/collection/artifact-create-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/artifact-create-modal.component.js +81 -63
- package/dist/lib/components/collection/artifact-create-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-artifact-card.component.js +7 -6
- package/dist/lib/components/collection/collection-artifact-card.component.js.map +1 -1
- package/dist/lib/components/collection/collection-form-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-form-modal.component.js +22 -22
- package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.js +65 -67
- package/dist/lib/components/collection/collection-share-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-view.component.js +71 -59
- package/dist/lib/components/collection/collection-view.component.js.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.js +7 -8
- package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +25 -28
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +478 -572
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.d.ts +7 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.js +101 -52
- package/dist/lib/components/conversation/conversation-empty-state.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.d.ts +3 -3
- package/dist/lib/components/conversation/conversation-list.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.js +44 -30
- package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
- package/dist/lib/components/dialogs/input-dialog.component.d.ts +0 -3
- package/dist/lib/components/dialogs/input-dialog.component.d.ts.map +1 -1
- package/dist/lib/components/dialogs/input-dialog.component.js +12 -17
- package/dist/lib/components/dialogs/input-dialog.component.js.map +1 -1
- package/dist/lib/components/export/export-modal.component.d.ts.map +1 -1
- package/dist/lib/components/export/export-modal.component.js +23 -23
- package/dist/lib/components/export/export-modal.component.js.map +1 -1
- package/dist/lib/components/members/members-modal.component.d.ts.map +1 -1
- package/dist/lib/components/members/members-modal.component.js +96 -85
- package/dist/lib/components/members/members-modal.component.js.map +1 -1
- package/dist/lib/components/message/actionable-commands.component.d.ts +2 -2
- package/dist/lib/components/message/actionable-commands.component.d.ts.map +1 -1
- package/dist/lib/components/message/actionable-commands.component.js +9 -10
- package/dist/lib/components/message/actionable-commands.component.js.map +1 -1
- package/dist/lib/components/message/conversation-message-rating.component.d.ts +1 -1
- package/dist/lib/components/message/conversation-message-rating.component.d.ts.map +1 -1
- package/dist/lib/components/message/conversation-message-rating.component.js +1 -1
- package/dist/lib/components/message/conversation-message-rating.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +23 -5
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +72 -29
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +14 -2
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +31 -28
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +1 -2
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +1 -1
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.d.ts +157 -0
- package/dist/lib/components/overlay/chat-overlay.component.d.ts.map +1 -0
- package/dist/lib/components/overlay/chat-overlay.component.js +462 -0
- package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -0
- package/dist/lib/components/project/project-form-modal.component.d.ts +2 -2
- package/dist/lib/components/project/project-form-modal.component.d.ts.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.js +24 -28
- package/dist/lib/components/project/project-form-modal.component.js.map +1 -1
- package/dist/lib/components/project/project-selector.component.d.ts +4 -3
- package/dist/lib/components/project/project-selector.component.d.ts.map +1 -1
- package/dist/lib/components/project/project-selector.component.js +78 -115
- package/dist/lib/components/project/project-selector.component.js.map +1 -1
- package/dist/lib/components/search/search-panel.component.js +84 -84
- package/dist/lib/components/search/search-panel.component.js.map +1 -1
- package/dist/lib/components/share/share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/share/share-modal.component.js +77 -68
- package/dist/lib/components/share/share-modal.component.js.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +2 -3
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +29 -32
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/conversations.module.d.ts +19 -26
- package/dist/lib/conversations.module.d.ts.map +1 -1
- package/dist/lib/conversations.module.js +20 -43
- package/dist/lib/conversations.module.js.map +1 -1
- package/dist/lib/services/active-tasks.service.d.ts +1 -3
- package/dist/lib/services/active-tasks.service.d.ts.map +1 -1
- package/dist/lib/services/active-tasks.service.js +6 -9
- package/dist/lib/services/active-tasks.service.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts +9 -4
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +83 -61
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/dialog.service.d.ts +6 -6
- package/dist/lib/services/dialog.service.d.ts.map +1 -1
- package/dist/lib/services/dialog.service.js +26 -23
- package/dist/lib/services/dialog.service.js.map +1 -1
- package/dist/public-api.d.ts +1 -2
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -2
- package/dist/public-api.js.map +1 -1
- package/package.json +21 -27
- package/dist/lib/models/conversation-complete-query.model.d.ts +0 -95
- package/dist/lib/models/conversation-complete-query.model.d.ts.map +0 -1
- package/dist/lib/models/conversation-complete-query.model.js +0 -22
- package/dist/lib/models/conversation-complete-query.model.js.map +0 -1
- package/dist/lib/services/conversation-data.service.d.ts +0 -134
- package/dist/lib/services/conversation-data.service.d.ts.map +0 -1
- package/dist/lib/services/conversation-data.service.js +0 -287
- package/dist/lib/services/conversation-data.service.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-message-rating.component.js","sourceRoot":"","sources":["../../../../src/lib/components/message/conversation-message-rating.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, OnInit, ChangeDetectorRef } from '@angular/core';\nimport { Metadata, RunView, UserInfo } from '@memberjunction/core';\nimport { MJConversationDetailRatingEntity } from '@memberjunction/core-entities';\nimport { RatingJSON } from '../../models/conversation-complete-query.model';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/**\n * Component for displaying and managing multi-user ratings on conversation messages.\n * Shows aggregate ratings and allows users to provide their own rating.\n * Uses optimistic updates — UI reflects the change immediately while DB saves in background.\n */\n@Component({\n standalone: false,\n selector: 'mj-conversation-message-rating',\n template: `\n <div class=\"rating-container\">\n @if (totalRatings > 0) {\n <div class=\"aggregate-rating\" [title]=\"getRatingsTooltip()\">\n <span class=\"thumbs-up\" [class.has-votes]=\"thumbsUpCount > 0\">\n 👍 {{ thumbsUpCount }}\n </span>\n <span class=\"thumbs-down\" [class.has-votes]=\"thumbsDownCount > 0\">\n 👎 {{ thumbsDownCount }}\n </span>\n <span class=\"total-count\">({{ totalRatings }} {{ totalRatings === 1 ? 'rating' : 'ratings' }})</span>\n </div>\n }\n\n <div class=\"user-rating\" [class.has-rated]=\"currentUserRating != null\">\n <button\n class=\"rating-button thumbs-up-btn\"\n [class.active]=\"currentUserRating != null && currentUserRating >= 8\"\n [disabled]=\"isSaving\"\n (click)=\"RateThumbsUp()\"\n title=\"This was helpful\"\n type=\"button\">\n 👍\n </button>\n <button\n class=\"rating-button thumbs-down-btn\"\n [class.active]=\"currentUserRating != null && currentUserRating <= 3\"\n [disabled]=\"isSaving\"\n (click)=\"RateThumbsDown()\"\n title=\"This was not helpful\"\n type=\"button\">\n 👎\n </button>\n </div>\n </div>\n `,\n styles: [`\n .rating-container {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 4px 0;\n }\n\n .aggregate-rating {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n color: var(--mj-text-muted);\n }\n\n .thumbs-up, .thumbs-down {\n opacity: 0.5;\n }\n\n .thumbs-up.has-votes, .thumbs-down.has-votes {\n opacity: 1;\n }\n\n .total-count {\n font-size: 12px;\n color: var(--mj-text-disabled);\n }\n\n .user-rating {\n display: flex;\n gap: 4px;\n margin-left: auto;\n }\n\n .rating-button {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n padding: 6px 10px;\n cursor: pointer;\n font-size: 16px;\n opacity: 0.6;\n transition: all 0.2s;\n min-width: 36px;\n }\n\n .rating-button:hover:not(:disabled) {\n opacity: 1;\n border-color: var(--mj-text-muted);\n }\n\n .rating-button:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n }\n\n .rating-button.active {\n opacity: 1;\n }\n\n .thumbs-up-btn {\n color: var(--mj-status-success);\n }\n\n .thumbs-up-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n }\n\n .thumbs-up-btn.active {\n border-color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n }\n\n .thumbs-down-btn {\n color: var(--mj-status-error);\n }\n\n .thumbs-down-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n }\n\n .thumbs-down-btn.active {\n border-color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n }\n `]\n})\nexport class ConversationMessageRatingComponent implements OnInit {\n @Input() conversationDetailId!: string;\n @Input() currentUser!: UserInfo;\n @Input() ratingsData?: RatingJSON[];\n\n thumbsUpCount = 0;\n thumbsDownCount = 0;\n totalRatings = 0;\n currentUserRating: number | null = null;\n isSaving = false;\n\n private allRatings: RatingJSON[] = [];\n private currentUserRatingId: string | null = null;\n\n private get currentUserId(): string {\n return this.currentUser?.ID || '';\n }\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n async ngOnInit() {\n if (this.ratingsData) {\n this.processRatings(this.ratingsData);\n } else {\n await this.loadRatings();\n }\n }\n\n private processRatings(ratings: RatingJSON[] | MJConversationDetailRatingEntity[]): void {\n this.allRatings = ratings as RatingJSON[];\n this.thumbsUpCount = ratings.filter(r => r.Rating != null && r.Rating >= 8).length;\n this.thumbsDownCount = ratings.filter(r => r.Rating != null && r.Rating <= 3).length;\n this.totalRatings = ratings.length;\n\n const mine = ratings.find(r => UUIDsEqual(r.UserID, this.currentUserId));\n this.currentUserRating = mine?.Rating ?? null;\n this.currentUserRatingId = mine ? (mine as RatingJSON).ID ?? null : null;\n }\n\n getRatingsTooltip(): string {\n if (this.allRatings.length === 0) return '';\n\n const upUsers = this.allRatings\n .filter(r => r.Rating != null && r.Rating >= 8)\n .map(r => (r as RatingJSON).UserName || 'Unknown')\n .join(', ');\n\n const downUsers = this.allRatings\n .filter(r => r.Rating != null && r.Rating <= 3)\n .map(r => (r as RatingJSON).UserName || 'Unknown')\n .join(', ');\n\n const parts: string[] = [];\n if (upUsers) parts.push(`👍 ${upUsers}`);\n if (downUsers) parts.push(`👎 ${downUsers}`);\n return parts.join('\\n');\n }\n\n async RateThumbsUp(): Promise<void> {\n await this.saveRating(10);\n }\n\n async RateThumbsDown(): Promise<void> {\n await this.saveRating(1);\n }\n\n private async loadRatings(): Promise<void> {\n try {\n const rv = new RunView();\n const result = await rv.RunView<MJConversationDetailRatingEntity>({\n EntityName: 'MJ: Conversation Detail Ratings',\n ExtraFilter: `ConversationDetailID='${this.conversationDetailId}'`,\n ResultType: 'entity_object'\n });\n if (result.Success && result.Results) {\n this.processRatings(result.Results);\n this.cdr.detectChanges();\n }\n } catch (error) {\n console.error('Failed to load ratings:', error);\n }\n }\n\n private applyOptimisticUpdate(rating: number): void {\n const wasThumbsUp = this.currentUserRating != null && this.currentUserRating >= 8;\n const wasThumbsDown = this.currentUserRating != null && this.currentUserRating <= 3;\n\n // Adjust counts when switching from an existing rating\n if (wasThumbsUp) this.thumbsUpCount--;\n if (wasThumbsDown) this.thumbsDownCount--;\n if (!wasThumbsUp && !wasThumbsDown) this.totalRatings++;\n\n this.currentUserRating = rating;\n if (rating >= 8) this.thumbsUpCount++;\n else this.thumbsDownCount++;\n }\n\n private async saveRating(rating: number): Promise<void> {\n if (this.isSaving) return;\n\n // Ignore if user clicks the same rating they already have\n if (this.currentUserRating === rating) return;\n\n // Snapshot for rollback\n const prevRating = this.currentUserRating;\n const prevRatingId = this.currentUserRatingId;\n const prevThumbsUp = this.thumbsUpCount;\n const prevThumbsDown = this.thumbsDownCount;\n const prevTotal = this.totalRatings;\n\n // Optimistic update — UI reflects change instantly\n this.isSaving = true;\n this.applyOptimisticUpdate(rating);\n this.cdr.detectChanges();\n\n try {\n await this.persistRating(rating, prevRatingId);\n } catch (error) {\n // Roll back to previous state on failure\n console.error('Failed to save rating:', error);\n this.currentUserRating = prevRating;\n this.currentUserRatingId = prevRatingId;\n this.thumbsUpCount = prevThumbsUp;\n this.thumbsDownCount = prevThumbsDown;\n this.totalRatings = prevTotal;\n this.cdr.detectChanges();\n } finally {\n this.isSaving = false;\n this.cdr.detectChanges();\n }\n }\n\n private async persistRating(rating: number, prevRatingId: string | null): Promise<void> {\n if (prevRatingId) {\n // Update existing rating (switch thumbs up ↔ down)\n const md = new Metadata();\n const entity = await md.GetEntityObject<MJConversationDetailRatingEntity>('MJ: Conversation Detail Ratings');\n const loaded = await entity.Load(prevRatingId);\n if (loaded) {\n entity.Rating = rating;\n await entity.Save();\n }\n } else {\n // Create new rating\n const md = new Metadata();\n const entity = await md.GetEntityObject<MJConversationDetailRatingEntity>('MJ: Conversation Detail Ratings');\n entity.ConversationDetailID = this.conversationDetailId;\n entity.UserID = this.currentUserId;\n entity.Rating = rating;\n await entity.Save();\n this.currentUserRatingId = entity.ID;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"conversation-message-rating.component.js","sourceRoot":"","sources":["../../../../src/lib/components/message/conversation-message-rating.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, OnInit, ChangeDetectorRef } from '@angular/core';\nimport { Metadata, RunView, UserInfo } from '@memberjunction/core';\nimport { MJConversationDetailRatingEntity, RatingJSON } from '@memberjunction/core-entities';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/**\n * Component for displaying and managing multi-user ratings on conversation messages.\n * Shows aggregate ratings and allows users to provide their own rating.\n * Uses optimistic updates — UI reflects the change immediately while DB saves in background.\n */\n@Component({\n standalone: false,\n selector: 'mj-conversation-message-rating',\n template: `\n <div class=\"rating-container\">\n @if (totalRatings > 0) {\n <div class=\"aggregate-rating\" [title]=\"getRatingsTooltip()\">\n <span class=\"thumbs-up\" [class.has-votes]=\"thumbsUpCount > 0\">\n 👍 {{ thumbsUpCount }}\n </span>\n <span class=\"thumbs-down\" [class.has-votes]=\"thumbsDownCount > 0\">\n 👎 {{ thumbsDownCount }}\n </span>\n <span class=\"total-count\">({{ totalRatings }} {{ totalRatings === 1 ? 'rating' : 'ratings' }})</span>\n </div>\n }\n\n <div class=\"user-rating\" [class.has-rated]=\"currentUserRating != null\">\n <button\n class=\"rating-button thumbs-up-btn\"\n [class.active]=\"currentUserRating != null && currentUserRating >= 8\"\n [disabled]=\"isSaving\"\n (click)=\"RateThumbsUp()\"\n title=\"This was helpful\"\n type=\"button\">\n 👍\n </button>\n <button\n class=\"rating-button thumbs-down-btn\"\n [class.active]=\"currentUserRating != null && currentUserRating <= 3\"\n [disabled]=\"isSaving\"\n (click)=\"RateThumbsDown()\"\n title=\"This was not helpful\"\n type=\"button\">\n 👎\n </button>\n </div>\n </div>\n `,\n styles: [`\n .rating-container {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 4px 0;\n }\n\n .aggregate-rating {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n color: var(--mj-text-muted);\n }\n\n .thumbs-up, .thumbs-down {\n opacity: 0.5;\n }\n\n .thumbs-up.has-votes, .thumbs-down.has-votes {\n opacity: 1;\n }\n\n .total-count {\n font-size: 12px;\n color: var(--mj-text-disabled);\n }\n\n .user-rating {\n display: flex;\n gap: 4px;\n margin-left: auto;\n }\n\n .rating-button {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n padding: 6px 10px;\n cursor: pointer;\n font-size: 16px;\n opacity: 0.6;\n transition: all 0.2s;\n min-width: 36px;\n }\n\n .rating-button:hover:not(:disabled) {\n opacity: 1;\n border-color: var(--mj-text-muted);\n }\n\n .rating-button:disabled {\n cursor: not-allowed;\n opacity: 0.4;\n }\n\n .rating-button.active {\n opacity: 1;\n }\n\n .thumbs-up-btn {\n color: var(--mj-status-success);\n }\n\n .thumbs-up-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-success) 8%, var(--mj-bg-surface));\n }\n\n .thumbs-up-btn.active {\n border-color: var(--mj-status-success);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n }\n\n .thumbs-down-btn {\n color: var(--mj-status-error);\n }\n\n .thumbs-down-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n }\n\n .thumbs-down-btn.active {\n border-color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n }\n `]\n})\nexport class ConversationMessageRatingComponent implements OnInit {\n @Input() conversationDetailId!: string;\n @Input() currentUser!: UserInfo;\n @Input() ratingsData?: RatingJSON[];\n\n thumbsUpCount = 0;\n thumbsDownCount = 0;\n totalRatings = 0;\n currentUserRating: number | null = null;\n isSaving = false;\n\n private allRatings: RatingJSON[] = [];\n private currentUserRatingId: string | null = null;\n\n private get currentUserId(): string {\n return this.currentUser?.ID || '';\n }\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n async ngOnInit() {\n if (this.ratingsData) {\n this.processRatings(this.ratingsData);\n } else {\n await this.loadRatings();\n }\n }\n\n private processRatings(ratings: RatingJSON[] | MJConversationDetailRatingEntity[]): void {\n this.allRatings = ratings as RatingJSON[];\n this.thumbsUpCount = ratings.filter(r => r.Rating != null && r.Rating >= 8).length;\n this.thumbsDownCount = ratings.filter(r => r.Rating != null && r.Rating <= 3).length;\n this.totalRatings = ratings.length;\n\n const mine = ratings.find(r => UUIDsEqual(r.UserID, this.currentUserId));\n this.currentUserRating = mine?.Rating ?? null;\n this.currentUserRatingId = mine ? (mine as RatingJSON).ID ?? null : null;\n }\n\n getRatingsTooltip(): string {\n if (this.allRatings.length === 0) return '';\n\n const upUsers = this.allRatings\n .filter(r => r.Rating != null && r.Rating >= 8)\n .map(r => (r as RatingJSON).UserName || 'Unknown')\n .join(', ');\n\n const downUsers = this.allRatings\n .filter(r => r.Rating != null && r.Rating <= 3)\n .map(r => (r as RatingJSON).UserName || 'Unknown')\n .join(', ');\n\n const parts: string[] = [];\n if (upUsers) parts.push(`👍 ${upUsers}`);\n if (downUsers) parts.push(`👎 ${downUsers}`);\n return parts.join('\\n');\n }\n\n async RateThumbsUp(): Promise<void> {\n await this.saveRating(10);\n }\n\n async RateThumbsDown(): Promise<void> {\n await this.saveRating(1);\n }\n\n private async loadRatings(): Promise<void> {\n try {\n const rv = new RunView();\n const result = await rv.RunView<MJConversationDetailRatingEntity>({\n EntityName: 'MJ: Conversation Detail Ratings',\n ExtraFilter: `ConversationDetailID='${this.conversationDetailId}'`,\n ResultType: 'entity_object'\n });\n if (result.Success && result.Results) {\n this.processRatings(result.Results);\n this.cdr.detectChanges();\n }\n } catch (error) {\n console.error('Failed to load ratings:', error);\n }\n }\n\n private applyOptimisticUpdate(rating: number): void {\n const wasThumbsUp = this.currentUserRating != null && this.currentUserRating >= 8;\n const wasThumbsDown = this.currentUserRating != null && this.currentUserRating <= 3;\n\n // Adjust counts when switching from an existing rating\n if (wasThumbsUp) this.thumbsUpCount--;\n if (wasThumbsDown) this.thumbsDownCount--;\n if (!wasThumbsUp && !wasThumbsDown) this.totalRatings++;\n\n this.currentUserRating = rating;\n if (rating >= 8) this.thumbsUpCount++;\n else this.thumbsDownCount++;\n }\n\n private async saveRating(rating: number): Promise<void> {\n if (this.isSaving) return;\n\n // Ignore if user clicks the same rating they already have\n if (this.currentUserRating === rating) return;\n\n // Snapshot for rollback\n const prevRating = this.currentUserRating;\n const prevRatingId = this.currentUserRatingId;\n const prevThumbsUp = this.thumbsUpCount;\n const prevThumbsDown = this.thumbsDownCount;\n const prevTotal = this.totalRatings;\n\n // Optimistic update — UI reflects change instantly\n this.isSaving = true;\n this.applyOptimisticUpdate(rating);\n this.cdr.detectChanges();\n\n try {\n await this.persistRating(rating, prevRatingId);\n } catch (error) {\n // Roll back to previous state on failure\n console.error('Failed to save rating:', error);\n this.currentUserRating = prevRating;\n this.currentUserRatingId = prevRatingId;\n this.thumbsUpCount = prevThumbsUp;\n this.thumbsDownCount = prevThumbsDown;\n this.totalRatings = prevTotal;\n this.cdr.detectChanges();\n } finally {\n this.isSaving = false;\n this.cdr.detectChanges();\n }\n }\n\n private async persistRating(rating: number, prevRatingId: string | null): Promise<void> {\n if (prevRatingId) {\n // Update existing rating (switch thumbs up ↔ down)\n const md = new Metadata();\n const entity = await md.GetEntityObject<MJConversationDetailRatingEntity>('MJ: Conversation Detail Ratings');\n const loaded = await entity.Load(prevRatingId);\n if (loaded) {\n entity.Rating = rating;\n await entity.Save();\n }\n } else {\n // Create new rating\n const md = new Metadata();\n const entity = await md.GetEntityObject<MJConversationDetailRatingEntity>('MJ: Conversation Detail Ratings');\n entity.ConversationDetailID = this.conversationDetailId;\n entity.UserID = this.currentUserId;\n entity.Rating = rating;\n await entity.Save();\n this.currentUserRatingId = entity.ID;\n }\n }\n}\n"]}
|
|
@@ -5,7 +5,6 @@ import { MJAIAgentEntityExtended, MJAIAgentRunEntityExtended } from "@memberjunc
|
|
|
5
5
|
import { DialogService } from '../../services/dialog.service';
|
|
6
6
|
import { ToastService } from '../../services/toast.service';
|
|
7
7
|
import { ConversationAgentService } from '../../services/conversation-agent.service';
|
|
8
|
-
import { ConversationDataService } from '../../services/conversation-data.service';
|
|
9
8
|
import { DataCacheService } from '../../services/data-cache.service';
|
|
10
9
|
import { ActiveTasksService } from '../../services/active-tasks.service';
|
|
11
10
|
import { ConversationStreamingService } from '../../services/conversation-streaming.service';
|
|
@@ -15,19 +14,20 @@ import { MentionParserService } from '../../services/mention-parser.service';
|
|
|
15
14
|
import { ConversationAttachmentService } from '../../services/conversation-attachment.service';
|
|
16
15
|
import { PendingAttachment } from '../mention/mention-editor.component';
|
|
17
16
|
import { LazyArtifactInfo } from '../../models/lazy-artifact-info';
|
|
17
|
+
import { ConversationBridgeService } from '../../services/conversation-bridge.service';
|
|
18
18
|
import { MessageInputBoxComponent } from './message-input-box.component';
|
|
19
19
|
import * as i0 from "@angular/core";
|
|
20
20
|
export declare class MessageInputComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit {
|
|
21
21
|
private dialogService;
|
|
22
22
|
private toastService;
|
|
23
23
|
private agentService;
|
|
24
|
-
private conversationData;
|
|
25
24
|
private dataCache;
|
|
26
25
|
private activeTasks;
|
|
27
26
|
private streamingService;
|
|
28
27
|
private mentionParser;
|
|
29
28
|
private mentionAutocomplete;
|
|
30
29
|
private attachmentService;
|
|
30
|
+
private bridge;
|
|
31
31
|
private readonly JSON_ARTIFACT_TYPE_ID;
|
|
32
32
|
conversationId: string;
|
|
33
33
|
conversationName?: string | null;
|
|
@@ -43,6 +43,7 @@ export declare class MessageInputComponent implements OnInit, OnDestroy, OnChang
|
|
|
43
43
|
systemArtifactsByDetailId?: Map<string, LazyArtifactInfo[]>;
|
|
44
44
|
agentRunsByDetailId?: Map<string, MJAIAgentRunEntityExtended>;
|
|
45
45
|
emptyStateMode: boolean;
|
|
46
|
+
appContext: Record<string, unknown> | null;
|
|
46
47
|
private _initialMessage;
|
|
47
48
|
private _initialAttachments;
|
|
48
49
|
private _isComponentReady;
|
|
@@ -107,7 +108,8 @@ export declare class MessageInputComponent implements OnInit, OnDestroy, OnChang
|
|
|
107
108
|
private completionTimestamps;
|
|
108
109
|
private registeredCallbacks;
|
|
109
110
|
private pendingAttachments;
|
|
110
|
-
|
|
111
|
+
private engine;
|
|
112
|
+
constructor(dialogService: DialogService, toastService: ToastService, agentService: ConversationAgentService, dataCache: DataCacheService, activeTasks: ActiveTasksService, streamingService: ConversationStreamingService, mentionParser: MentionParserService, mentionAutocomplete: MentionAutocompleteService, attachmentService: ConversationAttachmentService, bridge: ConversationBridgeService);
|
|
111
113
|
ngOnInit(): Promise<void>;
|
|
112
114
|
ngOnChanges(changes: SimpleChanges): void;
|
|
113
115
|
ngAfterViewInit(): void;
|
|
@@ -186,7 +188,23 @@ export declare class MessageInputComponent implements OnInit, OnDestroy, OnChang
|
|
|
186
188
|
*/
|
|
187
189
|
private handleDirectMention;
|
|
188
190
|
/**
|
|
189
|
-
* Handles routing when there's a previous agent
|
|
191
|
+
* Handles routing when there's a previous non-Sage agent in the conversation.
|
|
192
|
+
*
|
|
193
|
+
* LATENCY OPTIMIZATION (PR #2309 / plans/agent-latency-optimization.md — Opt #1):
|
|
194
|
+
* Previously, this method made a separate LLM call via checkContinuityIntent() to decide
|
|
195
|
+
* whether the user's new message was still directed at the previous agent or should be
|
|
196
|
+
* routed to Sage. That call added ~300ms of latency on every message in a conversation
|
|
197
|
+
* with an active agent — the single largest source of non-inference overhead on the client.
|
|
198
|
+
*
|
|
199
|
+
* The heuristic replacement is simple: if a previous non-Sage agent exists, always continue
|
|
200
|
+
* with it. The user can @mention a different agent (or Sage) to explicitly switch. This is
|
|
201
|
+
* more predictable and eliminates a common source of confusion where the intent check
|
|
202
|
+
* incorrectly rerouted messages away from the active agent.
|
|
203
|
+
*
|
|
204
|
+
* The checkContinuityIntent() method and the underlying checkAgentContinuityIntent() service
|
|
205
|
+
* method are preserved (not deleted) so we can reintroduce intent checking in the future
|
|
206
|
+
* when browser-local inference is fast enough (~20-50ms) to do this without blocking the
|
|
207
|
+
* user. See PR #2309 for the full discussion.
|
|
190
208
|
*/
|
|
191
209
|
private handleAgentContinuity;
|
|
192
210
|
/**
|
|
@@ -302,6 +320,6 @@ export declare class MessageInputComponent implements OnInit, OnDestroy, OnChang
|
|
|
302
320
|
*/
|
|
303
321
|
private cleanupCompletionTimestamp;
|
|
304
322
|
static ɵfac: i0.ɵɵFactoryDeclaration<MessageInputComponent, never>;
|
|
305
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<MessageInputComponent, "mj-message-input", never, { "conversationId": { "alias": "conversationId"; "required": false; }; "conversationName": { "alias": "conversationName"; "required": false; }; "currentUser": { "alias": "currentUser"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "parentMessageId": { "alias": "parentMessageId"; "required": false; }; "enableAttachments": { "alias": "enableAttachments"; "required": false; }; "maxAttachments": { "alias": "maxAttachments"; "required": false; }; "maxAttachmentSizeBytes": { "alias": "maxAttachmentSizeBytes"; "required": false; }; "acceptedFileTypes": { "alias": "acceptedFileTypes"; "required": false; }; "artifactsByDetailId": { "alias": "artifactsByDetailId"; "required": false; }; "systemArtifactsByDetailId": { "alias": "systemArtifactsByDetailId"; "required": false; }; "agentRunsByDetailId": { "alias": "agentRunsByDetailId"; "required": false; }; "emptyStateMode": { "alias": "emptyStateMode"; "required": false; }; "initialMessage": { "alias": "initialMessage"; "required": false; }; "initialAttachments": { "alias": "initialAttachments"; "required": false; }; "conversationHistory": { "alias": "conversationHistory"; "required": false; }; "inProgressMessageIds": { "alias": "inProgressMessageIds"; "required": false; }; }, { "messageSent": "messageSent"; "agentResponse": "agentResponse"; "agentRunDetected": "agentRunDetected"; "agentRunUpdate": "agentRunUpdate"; "messageComplete": "messageComplete"; "artifactCreated": "artifactCreated"; "conversationRenamed": "conversationRenamed"; "intentCheckStarted": "intentCheckStarted"; "intentCheckCompleted": "intentCheckCompleted"; "emptyStateSubmit": "emptyStateSubmit"; "uploadStateChanged": "uploadStateChanged"; }, never, never, false, never>;
|
|
323
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MessageInputComponent, "mj-message-input", never, { "conversationId": { "alias": "conversationId"; "required": false; }; "conversationName": { "alias": "conversationName"; "required": false; }; "currentUser": { "alias": "currentUser"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "parentMessageId": { "alias": "parentMessageId"; "required": false; }; "enableAttachments": { "alias": "enableAttachments"; "required": false; }; "maxAttachments": { "alias": "maxAttachments"; "required": false; }; "maxAttachmentSizeBytes": { "alias": "maxAttachmentSizeBytes"; "required": false; }; "acceptedFileTypes": { "alias": "acceptedFileTypes"; "required": false; }; "artifactsByDetailId": { "alias": "artifactsByDetailId"; "required": false; }; "systemArtifactsByDetailId": { "alias": "systemArtifactsByDetailId"; "required": false; }; "agentRunsByDetailId": { "alias": "agentRunsByDetailId"; "required": false; }; "emptyStateMode": { "alias": "emptyStateMode"; "required": false; }; "appContext": { "alias": "appContext"; "required": false; }; "initialMessage": { "alias": "initialMessage"; "required": false; }; "initialAttachments": { "alias": "initialAttachments"; "required": false; }; "conversationHistory": { "alias": "conversationHistory"; "required": false; }; "inProgressMessageIds": { "alias": "inProgressMessageIds"; "required": false; }; }, { "messageSent": "messageSent"; "agentResponse": "agentResponse"; "agentRunDetected": "agentRunDetected"; "agentRunUpdate": "agentRunUpdate"; "messageComplete": "messageComplete"; "artifactCreated": "artifactCreated"; "conversationRenamed": "conversationRenamed"; "intentCheckStarted": "intentCheckStarted"; "intentCheckCompleted": "intentCheckCompleted"; "emptyStateSubmit": "emptyStateSubmit"; "uploadStateChanged": "uploadStateChanged"; }, never, never, false, never>;
|
|
306
324
|
}
|
|
307
325
|
//# sourceMappingURL=message-input.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-input.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/message/message-input.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAa,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9I,OAAO,EAAE,QAAQ,EAAY,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,0BAA0B,
|
|
1
|
+
{"version":3,"file":"message-input.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/message/message-input.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
|
|
2
2
|
import { Metadata } from '@memberjunction/core';
|
|
3
|
-
import { MJEnvironmentEntityExtended } from '@memberjunction/core-entities';
|
|
3
|
+
import { MJEnvironmentEntityExtended, ConversationEngine } from '@memberjunction/core-entities';
|
|
4
4
|
import { GraphQLDataProvider, GraphQLAIClient } from '@memberjunction/graphql-dataprovider';
|
|
5
5
|
import { AIEngineBase } from '@memberjunction/ai-engine-base';
|
|
6
6
|
import { ConversationUtility } from '@memberjunction/ai-core-plus';
|
|
7
7
|
import { MJNotificationService } from '@memberjunction/ng-notifications';
|
|
8
|
-
import { UUIDsEqual } from '@memberjunction/global';
|
|
8
|
+
import { UUIDsEqual, CleanAndParseJSON } from '@memberjunction/global';
|
|
9
9
|
import * as i0 from "@angular/core";
|
|
10
10
|
import * as i1 from "../../services/dialog.service";
|
|
11
11
|
import * as i2 from "../../services/toast.service";
|
|
12
12
|
import * as i3 from "../../services/conversation-agent.service";
|
|
13
|
-
import * as i4 from "../../services/
|
|
14
|
-
import * as i5 from "../../services/
|
|
15
|
-
import * as i6 from "../../services/
|
|
16
|
-
import * as i7 from "../../services/
|
|
17
|
-
import * as i8 from "../../services/mention-
|
|
18
|
-
import * as i9 from "../../services/
|
|
19
|
-
import * as i10 from "../../services/conversation-
|
|
13
|
+
import * as i4 from "../../services/data-cache.service";
|
|
14
|
+
import * as i5 from "../../services/active-tasks.service";
|
|
15
|
+
import * as i6 from "../../services/conversation-streaming.service";
|
|
16
|
+
import * as i7 from "../../services/mention-parser.service";
|
|
17
|
+
import * as i8 from "../../services/mention-autocomplete.service";
|
|
18
|
+
import * as i9 from "../../services/conversation-attachment.service";
|
|
19
|
+
import * as i10 from "../../services/conversation-bridge.service";
|
|
20
20
|
import * as i11 from "./message-input-box.component";
|
|
21
21
|
const _c0 = ["inputBox"];
|
|
22
22
|
function MessageInputComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -34,13 +34,13 @@ export class MessageInputComponent {
|
|
|
34
34
|
dialogService;
|
|
35
35
|
toastService;
|
|
36
36
|
agentService;
|
|
37
|
-
conversationData;
|
|
38
37
|
dataCache;
|
|
39
38
|
activeTasks;
|
|
40
39
|
streamingService;
|
|
41
40
|
mentionParser;
|
|
42
41
|
mentionAutocomplete;
|
|
43
42
|
attachmentService;
|
|
43
|
+
bridge;
|
|
44
44
|
// Default artifact type ID for JSON (when agent doesn't specify DefaultArtifactTypeID)
|
|
45
45
|
JSON_ARTIFACT_TYPE_ID = 'ae674c7e-ea0d-49ea-89e4-0649f5eb20d4';
|
|
46
46
|
conversationId;
|
|
@@ -57,6 +57,7 @@ export class MessageInputComponent {
|
|
|
57
57
|
systemArtifactsByDetailId; // Pre-loaded system artifact data (Visibility='System Only')
|
|
58
58
|
agentRunsByDetailId; // Pre-loaded agent run data for performance
|
|
59
59
|
emptyStateMode = false; // When true, emits emptyStateSubmit instead of creating messages directly
|
|
60
|
+
appContext = null; // Application context for AI agent awareness
|
|
60
61
|
// Initial message to send automatically - using getter/setter for precise control
|
|
61
62
|
_initialMessage = null;
|
|
62
63
|
_initialAttachments = null;
|
|
@@ -130,17 +131,18 @@ export class MessageInputComponent {
|
|
|
130
131
|
registeredCallbacks = new Map();
|
|
131
132
|
// Track pending attachments from the input box
|
|
132
133
|
pendingAttachments = [];
|
|
133
|
-
|
|
134
|
+
engine = ConversationEngine.Instance;
|
|
135
|
+
constructor(dialogService, toastService, agentService, dataCache, activeTasks, streamingService, mentionParser, mentionAutocomplete, attachmentService, bridge) {
|
|
134
136
|
this.dialogService = dialogService;
|
|
135
137
|
this.toastService = toastService;
|
|
136
138
|
this.agentService = agentService;
|
|
137
|
-
this.conversationData = conversationData;
|
|
138
139
|
this.dataCache = dataCache;
|
|
139
140
|
this.activeTasks = activeTasks;
|
|
140
141
|
this.streamingService = streamingService;
|
|
141
142
|
this.mentionParser = mentionParser;
|
|
142
143
|
this.mentionAutocomplete = mentionAutocomplete;
|
|
143
144
|
this.attachmentService = attachmentService;
|
|
145
|
+
this.bridge = bridge;
|
|
144
146
|
}
|
|
145
147
|
async ngOnInit() {
|
|
146
148
|
this.converationManagerAgent = await this.agentService.getConversationManagerAgent();
|
|
@@ -539,16 +541,49 @@ export class MessageInputComponent {
|
|
|
539
541
|
await this.executeRouteWithNaming(() => this.invokeAgentDirectly(messageDetail, agentMention, this.conversationId), messageDetail.Message, isFirstMessage);
|
|
540
542
|
}
|
|
541
543
|
/**
|
|
542
|
-
* Handles routing when there's a previous agent
|
|
544
|
+
* Handles routing when there's a previous non-Sage agent in the conversation.
|
|
545
|
+
*
|
|
546
|
+
* LATENCY OPTIMIZATION (PR #2309 / plans/agent-latency-optimization.md — Opt #1):
|
|
547
|
+
* Previously, this method made a separate LLM call via checkContinuityIntent() to decide
|
|
548
|
+
* whether the user's new message was still directed at the previous agent or should be
|
|
549
|
+
* routed to Sage. That call added ~300ms of latency on every message in a conversation
|
|
550
|
+
* with an active agent — the single largest source of non-inference overhead on the client.
|
|
551
|
+
*
|
|
552
|
+
* The heuristic replacement is simple: if a previous non-Sage agent exists, always continue
|
|
553
|
+
* with it. The user can @mention a different agent (or Sage) to explicitly switch. This is
|
|
554
|
+
* more predictable and eliminates a common source of confusion where the intent check
|
|
555
|
+
* incorrectly rerouted messages away from the active agent.
|
|
556
|
+
*
|
|
557
|
+
* The checkContinuityIntent() method and the underlying checkAgentContinuityIntent() service
|
|
558
|
+
* method are preserved (not deleted) so we can reintroduce intent checking in the future
|
|
559
|
+
* when browser-local inference is fast enough (~20-50ms) to do this without blocking the
|
|
560
|
+
* user. See PR #2309 for the full discussion.
|
|
543
561
|
*/
|
|
544
562
|
async handleAgentContinuity(messageDetail, lastAgentId, mentionResult, isFirstMessage) {
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
563
|
+
// COMMENTED OUT — LLM intent check removed for latency optimization (see JSDoc above).
|
|
564
|
+
// const intentResult = await this.checkContinuityIntent(lastAgentId, messageDetail.Message);
|
|
565
|
+
//
|
|
566
|
+
// if (intentResult.decision === 'YES') {
|
|
567
|
+
// await this.executeRouteWithNaming(
|
|
568
|
+
// () => this.continueWithAgent(
|
|
569
|
+
// messageDetail,
|
|
570
|
+
// lastAgentId,
|
|
571
|
+
// this.conversationId,
|
|
572
|
+
// intentResult.targetArtifactVersionId
|
|
573
|
+
// ),
|
|
574
|
+
// messageDetail.Message,
|
|
575
|
+
// isFirstMessage
|
|
576
|
+
// );
|
|
577
|
+
// } else {
|
|
578
|
+
// await this.executeRouteWithNaming(
|
|
579
|
+
// () => this.processMessageThroughAgent(messageDetail, mentionResult),
|
|
580
|
+
// messageDetail.Message,
|
|
581
|
+
// isFirstMessage
|
|
582
|
+
// );
|
|
583
|
+
// }
|
|
584
|
+
// Always continue with the previous agent — user can @mention another agent to switch.
|
|
585
|
+
await this.executeRouteWithNaming(() => this.continueWithAgent(messageDetail, lastAgentId, this.conversationId, undefined // artifact version targeting unavailable without intent check
|
|
586
|
+
), messageDetail.Message, isFirstMessage);
|
|
552
587
|
}
|
|
553
588
|
/**
|
|
554
589
|
* Handles routing when there's no previous agent context
|
|
@@ -752,7 +787,7 @@ export class MessageInputComponent {
|
|
|
752
787
|
conversationId: this.conversationId,
|
|
753
788
|
conversationName: this.conversationName
|
|
754
789
|
});
|
|
755
|
-
const result = await this.agentService.processMessage(conversationId, userMessage, this.conversationHistory, conversationManagerMessage.ID, this.createProgressCallback(conversationManagerMessage, 'Sage'));
|
|
790
|
+
const result = await this.agentService.processMessage(conversationId, userMessage, this.conversationHistory, conversationManagerMessage.ID, this.createProgressCallback(conversationManagerMessage, 'Sage'), this.appContext);
|
|
756
791
|
// Task will be removed automatically in markMessageComplete()
|
|
757
792
|
// DO NOT remove here - agent may still be streaming/processing
|
|
758
793
|
taskId = null; // Clear reference but don't remove from service
|
|
@@ -1747,14 +1782,15 @@ export class MessageInputComponent {
|
|
|
1747
1782
|
timeoutPromise
|
|
1748
1783
|
]);
|
|
1749
1784
|
if (result && result.success && (result.parsedResult || result.output)) {
|
|
1750
|
-
// Use parsedResult if available, otherwise parse output
|
|
1785
|
+
// Use parsedResult if available, otherwise clean and parse output
|
|
1786
|
+
// (CleanAndParseJSON handles markdown code blocks like ```json ... ```)
|
|
1751
1787
|
const parsed = result.parsedResult ||
|
|
1752
|
-
(result.output ?
|
|
1788
|
+
(result.output ? CleanAndParseJSON(result.output) : null);
|
|
1753
1789
|
if (parsed) {
|
|
1754
1790
|
const { name, description } = parsed;
|
|
1755
1791
|
if (name) {
|
|
1756
1792
|
// Update the conversation name and description in database AND state immediately
|
|
1757
|
-
await this.
|
|
1793
|
+
await this.engine.SaveConversation(this.conversationId, { Name: name, Description: description || '' }, this.currentUser);
|
|
1758
1794
|
// Emit event for animation in conversation list
|
|
1759
1795
|
this.conversationRenamed.emit({
|
|
1760
1796
|
conversationId: this.conversationId,
|
|
@@ -1804,8 +1840,13 @@ export class MessageInputComponent {
|
|
|
1804
1840
|
conversationName: task.conversationName
|
|
1805
1841
|
});
|
|
1806
1842
|
this.activeTasks.remove(task.id);
|
|
1807
|
-
// Show
|
|
1808
|
-
|
|
1843
|
+
// Show toast only if the user isn't currently viewing this conversation.
|
|
1844
|
+
// If they're watching, the inline completion is sufficient.
|
|
1845
|
+
const isConvoVisible = UUIDsEqual(this.bridge.ActiveConversationID$.value, task.conversationId)
|
|
1846
|
+
&& (this.bridge.OverlayActive$.value || this.bridge.WorkspaceActive$.value);
|
|
1847
|
+
if (!isConvoVisible) {
|
|
1848
|
+
MJNotificationService.Instance?.CreateSimpleNotification(`${task.agentName} completed in ${task.conversationName || 'conversation'}`, 'success', 3000);
|
|
1849
|
+
}
|
|
1809
1850
|
}
|
|
1810
1851
|
else {
|
|
1811
1852
|
console.warn(`⚠️ No task found for completed message ${conversationDetail.ID} - task may have been removed prematurely or not added`);
|
|
@@ -1825,13 +1866,13 @@ export class MessageInputComponent {
|
|
|
1825
1866
|
this.completionTimestamps.delete(conversationDetailId);
|
|
1826
1867
|
}, 5000); // 5 seconds should be more than enough
|
|
1827
1868
|
}
|
|
1828
|
-
static ɵfac = function MessageInputComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MessageInputComponent)(i0.ɵɵdirectiveInject(i1.DialogService), i0.ɵɵdirectiveInject(i2.ToastService), i0.ɵɵdirectiveInject(i3.ConversationAgentService), i0.ɵɵdirectiveInject(i4.
|
|
1869
|
+
static ɵfac = function MessageInputComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MessageInputComponent)(i0.ɵɵdirectiveInject(i1.DialogService), i0.ɵɵdirectiveInject(i2.ToastService), i0.ɵɵdirectiveInject(i3.ConversationAgentService), i0.ɵɵdirectiveInject(i4.DataCacheService), i0.ɵɵdirectiveInject(i5.ActiveTasksService), i0.ɵɵdirectiveInject(i6.ConversationStreamingService), i0.ɵɵdirectiveInject(i7.MentionParserService), i0.ɵɵdirectiveInject(i8.MentionAutocompleteService), i0.ɵɵdirectiveInject(i9.ConversationAttachmentService), i0.ɵɵdirectiveInject(i10.ConversationBridgeService)); };
|
|
1829
1870
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MessageInputComponent, selectors: [["mj-message-input"]], viewQuery: function MessageInputComponent_Query(rf, ctx) { if (rf & 1) {
|
|
1830
1871
|
i0.ɵɵviewQuery(_c0, 5);
|
|
1831
1872
|
} if (rf & 2) {
|
|
1832
1873
|
let _t;
|
|
1833
1874
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.inputBox = _t.first);
|
|
1834
|
-
} }, inputs: { conversationId: "conversationId", conversationName: "conversationName", currentUser: "currentUser", disabled: "disabled", placeholder: "placeholder", parentMessageId: "parentMessageId", enableAttachments: "enableAttachments", maxAttachments: "maxAttachments", maxAttachmentSizeBytes: "maxAttachmentSizeBytes", acceptedFileTypes: "acceptedFileTypes", artifactsByDetailId: "artifactsByDetailId", systemArtifactsByDetailId: "systemArtifactsByDetailId", agentRunsByDetailId: "agentRunsByDetailId", emptyStateMode: "emptyStateMode", initialMessage: "initialMessage", initialAttachments: "initialAttachments", conversationHistory: "conversationHistory", inProgressMessageIds: "inProgressMessageIds" }, outputs: { messageSent: "messageSent", agentResponse: "agentResponse", agentRunDetected: "agentRunDetected", agentRunUpdate: "agentRunUpdate", messageComplete: "messageComplete", artifactCreated: "artifactCreated", conversationRenamed: "conversationRenamed", intentCheckStarted: "intentCheckStarted", intentCheckCompleted: "intentCheckCompleted", emptyStateSubmit: "emptyStateSubmit", uploadStateChanged: "uploadStateChanged" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 4, vars: 12, consts: [["inputBox", ""], [1, "message-input-wrapper"], [1, "processing-indicator"], [3, "valueChange", "textSubmitted", "attachmentsChanged", "attachmentError", "placeholder", "disabled", "showCharacterCount", "enableMentions", "enableAttachments", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "currentUser", "rows", "value"], [1, "fas", "fa-circle-notch", "fa-spin"]], template: function MessageInputComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1875
|
+
} }, inputs: { conversationId: "conversationId", conversationName: "conversationName", currentUser: "currentUser", disabled: "disabled", placeholder: "placeholder", parentMessageId: "parentMessageId", enableAttachments: "enableAttachments", maxAttachments: "maxAttachments", maxAttachmentSizeBytes: "maxAttachmentSizeBytes", acceptedFileTypes: "acceptedFileTypes", artifactsByDetailId: "artifactsByDetailId", systemArtifactsByDetailId: "systemArtifactsByDetailId", agentRunsByDetailId: "agentRunsByDetailId", emptyStateMode: "emptyStateMode", appContext: "appContext", initialMessage: "initialMessage", initialAttachments: "initialAttachments", conversationHistory: "conversationHistory", inProgressMessageIds: "inProgressMessageIds" }, outputs: { messageSent: "messageSent", agentResponse: "agentResponse", agentRunDetected: "agentRunDetected", agentRunUpdate: "agentRunUpdate", messageComplete: "messageComplete", artifactCreated: "artifactCreated", conversationRenamed: "conversationRenamed", intentCheckStarted: "intentCheckStarted", intentCheckCompleted: "intentCheckCompleted", emptyStateSubmit: "emptyStateSubmit", uploadStateChanged: "uploadStateChanged" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 4, vars: 12, consts: [["inputBox", ""], [1, "message-input-wrapper"], [1, "processing-indicator"], [3, "valueChange", "textSubmitted", "attachmentsChanged", "attachmentError", "placeholder", "disabled", "showCharacterCount", "enableMentions", "enableAttachments", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "currentUser", "rows", "value"], [1, "fas", "fa-circle-notch", "fa-spin"]], template: function MessageInputComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1835
1876
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
1836
1877
|
i0.ɵɵelementStart(0, "div", 1);
|
|
1837
1878
|
i0.ɵɵconditionalCreate(1, MessageInputComponent_Conditional_1_Template, 4, 1, "div", 2);
|
|
@@ -1850,7 +1891,7 @@ export class MessageInputComponent {
|
|
|
1850
1891
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MessageInputComponent, [{
|
|
1851
1892
|
type: Component,
|
|
1852
1893
|
args: [{ standalone: false, selector: 'mj-message-input', template: "<div class=\"message-input-wrapper\">\n <!-- Processing Indicator Overlay -->\n @if (isProcessing) {\n <div class=\"processing-indicator\">\n <i class=\"fas fa-circle-notch fa-spin\"></i>\n <span>{{ processingMessage }}</span>\n </div>\n }\n\n <!-- Message Input Box -->\n <mj-message-input-box\n #inputBox\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled || isProcessing\"\n [showCharacterCount]=\"false\"\n [enableMentions]=\"true\"\n [enableAttachments]=\"enableAttachments\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n [currentUser]=\"currentUser\"\n [rows]=\"3\"\n [(value)]=\"messageText\"\n (textSubmitted)=\"onTextSubmitted($event)\"\n (attachmentsChanged)=\"onAttachmentsChanged($event)\"\n (attachmentError)=\"onAttachmentError($event)\">\n </mj-message-input-box>\n</div>", styles: [".message-input-wrapper {\n position: relative;\n width: 100%;\n}\n\n.processing-indicator {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.25rem;\n background: color-mix(in srgb, var(--mj-bg-surface-card) 95%, transparent);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n pointer-events: none;\n}\n.processing-indicator i {\n color: var(--mj-brand-primary);\n}\n.processing-indicator span {\n font-size: 0.9rem;\n color: var(--mj-text-primary);\n}\n"] }]
|
|
1853
|
-
}], () => [{ type: i1.DialogService }, { type: i2.ToastService }, { type: i3.ConversationAgentService }, { type: i4.
|
|
1894
|
+
}], () => [{ type: i1.DialogService }, { type: i2.ToastService }, { type: i3.ConversationAgentService }, { type: i4.DataCacheService }, { type: i5.ActiveTasksService }, { type: i6.ConversationStreamingService }, { type: i7.MentionParserService }, { type: i8.MentionAutocompleteService }, { type: i9.ConversationAttachmentService }, { type: i10.ConversationBridgeService }], { conversationId: [{
|
|
1854
1895
|
type: Input
|
|
1855
1896
|
}], conversationName: [{
|
|
1856
1897
|
type: Input
|
|
@@ -1878,6 +1919,8 @@ export class MessageInputComponent {
|
|
|
1878
1919
|
type: Input
|
|
1879
1920
|
}], emptyStateMode: [{
|
|
1880
1921
|
type: Input
|
|
1922
|
+
}], appContext: [{
|
|
1923
|
+
type: Input
|
|
1881
1924
|
}], initialMessage: [{
|
|
1882
1925
|
type: Input
|
|
1883
1926
|
}], initialAttachments: [{
|