@memberjunction/ng-conversations 2.112.0 → 2.113.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/dist/lib/components/agent/active-agent-indicator.component.d.ts +1 -1
- package/dist/lib/components/agent/active-agent-indicator.component.d.ts.map +1 -1
- package/dist/lib/components/agent/active-agent-indicator.component.js +13 -15
- package/dist/lib/components/agent/active-agent-indicator.component.js.map +1 -1
- package/dist/lib/components/agent/agent-process-panel.component.d.ts +1 -1
- package/dist/lib/components/agent/agent-process-panel.component.d.ts.map +1 -1
- package/dist/lib/components/agent/agent-process-panel.component.js +14 -18
- package/dist/lib/components/agent/agent-process-panel.component.js.map +1 -1
- package/dist/lib/components/artifact/artifact-share-modal.component.d.ts +1 -1
- package/dist/lib/components/artifact/artifact-share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/artifact/artifact-share-modal.component.js +11 -11
- 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 +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 +30 -24
- 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 -1
- package/dist/lib/components/collection/artifact-create-modal.component.d.ts.map +1 -1
- package/dist/lib/components/collection/artifact-create-modal.component.js +10 -8
- package/dist/lib/components/collection/artifact-create-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-artifact-card.component.d.ts +9 -8
- package/dist/lib/components/collection/collection-artifact-card.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-artifact-card.component.js +51 -35
- package/dist/lib/components/collection/collection-artifact-card.component.js.map +1 -1
- package/dist/lib/components/collection/collection-form-modal.component.d.ts +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 +6 -5
- package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-share-modal.component.d.ts +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 +12 -12
- package/dist/lib/components/collection/collection-share-modal.component.js.map +1 -1
- package/dist/lib/components/collection/collection-tree.component.d.ts +1 -1
- package/dist/lib/components/collection/collection-tree.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-tree.component.js +11 -11
- package/dist/lib/components/collection/collection-tree.component.js.map +1 -1
- package/dist/lib/components/collection/collection-view.component.d.ts +29 -10
- package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collection-view.component.js +128 -62
- package/dist/lib/components/collection/collection-view.component.js.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.d.ts +19 -7
- package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/collection/collections-full-view.component.js +99 -69
- package/dist/lib/components/collection/collections-full-view.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +38 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +303 -181
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-empty-state.component.d.ts +1 -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 +21 -21
- package/dist/lib/components/conversation/conversation-empty-state.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.d.ts +11 -4
- package/dist/lib/components/conversation/conversation-list.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-list.component.js +122 -81
- package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
- package/dist/lib/components/export/export-modal.component.d.ts +1 -1
- package/dist/lib/components/export/export-modal.component.d.ts.map +1 -1
- package/dist/lib/components/export/export-modal.component.js +11 -9
- package/dist/lib/components/export/export-modal.component.js.map +1 -1
- package/dist/lib/components/global-tasks/global-tasks-panel.component.d.ts +25 -0
- package/dist/lib/components/global-tasks/global-tasks-panel.component.d.ts.map +1 -0
- package/dist/lib/components/global-tasks/global-tasks-panel.component.js +206 -0
- package/dist/lib/components/global-tasks/global-tasks-panel.component.js.map +1 -0
- package/dist/lib/components/library/library-full-view.component.d.ts +1 -1
- package/dist/lib/components/library/library-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/library/library-full-view.component.js +6 -5
- package/dist/lib/components/library/library-full-view.component.js.map +1 -1
- package/dist/lib/components/members/members-modal.component.d.ts +1 -1
- package/dist/lib/components/members/members-modal.component.d.ts.map +1 -1
- package/dist/lib/components/members/members-modal.component.js +8 -8
- package/dist/lib/components/members/members-modal.component.js.map +1 -1
- package/dist/lib/components/message/conversation-message-rating.component.d.ts +47 -0
- package/dist/lib/components/message/conversation-message-rating.component.d.ts.map +1 -0
- package/dist/lib/components/message/conversation-message-rating.component.js +224 -0
- package/dist/lib/components/message/conversation-message-rating.component.js.map +1 -0
- package/dist/lib/components/message/message-input-box.component.d.ts +1 -1
- package/dist/lib/components/message/message-input-box.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input-box.component.js +4 -14
- package/dist/lib/components/message/message-input-box.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +18 -3
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +288 -297
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +32 -2
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +253 -129
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +4 -2
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +35 -18
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/navigation/conversation-navigation.component.d.ts +7 -1
- package/dist/lib/components/navigation/conversation-navigation.component.d.ts.map +1 -1
- package/dist/lib/components/navigation/conversation-navigation.component.js +24 -14
- package/dist/lib/components/navigation/conversation-navigation.component.js.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.d.ts +1 -1
- package/dist/lib/components/project/project-form-modal.component.d.ts.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.js +7 -7
- package/dist/lib/components/project/project-form-modal.component.js.map +1 -1
- package/dist/lib/components/project/project-selector.component.d.ts +1 -1
- package/dist/lib/components/project/project-selector.component.d.ts.map +1 -1
- package/dist/lib/components/project/project-selector.component.js +10 -10
- package/dist/lib/components/project/project-selector.component.js.map +1 -1
- package/dist/lib/components/search/search-panel.component.d.ts +1 -1
- package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
- package/dist/lib/components/search/search-panel.component.js +16 -8
- package/dist/lib/components/search/search-panel.component.js.map +1 -1
- package/dist/lib/components/share/share-modal.component.d.ts +1 -1
- package/dist/lib/components/share/share-modal.component.d.ts.map +1 -1
- package/dist/lib/components/share/share-modal.component.js +12 -12
- package/dist/lib/components/share/share-modal.component.js.map +1 -1
- package/dist/lib/components/shared/user-picker.component.d.ts +1 -1
- package/dist/lib/components/shared/user-picker.component.d.ts.map +1 -1
- package/dist/lib/components/shared/user-picker.component.js +7 -7
- package/dist/lib/components/shared/user-picker.component.js.map +1 -1
- package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts +1 -1
- package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts.map +1 -1
- package/dist/lib/components/sidebar/conversation-sidebar.component.js +1 -1
- package/dist/lib/components/sidebar/conversation-sidebar.component.js.map +1 -1
- package/dist/lib/components/task/tasks-full-view.component.d.ts +1 -1
- package/dist/lib/components/task/tasks-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/task/tasks-full-view.component.js +20 -18
- package/dist/lib/components/task/tasks-full-view.component.js.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts +18 -29
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.js +178 -218
- package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
- package/dist/lib/components/thread/thread-panel.component.d.ts +1 -1
- package/dist/lib/components/thread/thread-panel.component.d.ts.map +1 -1
- package/dist/lib/components/thread/thread-panel.component.js +2 -2
- package/dist/lib/components/thread/thread-panel.component.js.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +15 -9
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +126 -79
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/conversations.module.d.ts +54 -52
- package/dist/lib/conversations.module.d.ts.map +1 -1
- package/dist/lib/conversations.module.js +11 -3
- package/dist/lib/conversations.module.js.map +1 -1
- package/dist/lib/models/conversation-complete-query.model.d.ts +31 -22
- package/dist/lib/models/conversation-complete-query.model.d.ts.map +1 -1
- package/dist/lib/models/conversation-complete-query.model.js +5 -2
- package/dist/lib/models/conversation-complete-query.model.js.map +1 -1
- package/dist/lib/models/lazy-artifact-info.d.ts +4 -1
- package/dist/lib/models/lazy-artifact-info.d.ts.map +1 -1
- package/dist/lib/models/lazy-artifact-info.js +12 -4
- package/dist/lib/models/lazy-artifact-info.js.map +1 -1
- package/dist/lib/services/active-tasks.service.d.ts +18 -0
- package/dist/lib/services/active-tasks.service.d.ts.map +1 -1
- package/dist/lib/services/active-tasks.service.js +53 -3
- package/dist/lib/services/active-tasks.service.js.map +1 -1
- package/dist/lib/services/agent-state.service.d.ts +1 -1
- package/dist/lib/services/agent-state.service.d.ts.map +1 -1
- package/dist/lib/services/agent-state.service.js +11 -11
- package/dist/lib/services/agent-state.service.js.map +1 -1
- package/dist/lib/services/artifact-permission.service.d.ts +1 -1
- package/dist/lib/services/artifact-permission.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-permission.service.js +15 -13
- package/dist/lib/services/artifact-permission.service.js.map +1 -1
- package/dist/lib/services/artifact-state.service.d.ts +23 -6
- package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
- package/dist/lib/services/artifact-state.service.js +129 -38
- package/dist/lib/services/artifact-state.service.js.map +1 -1
- package/dist/lib/services/artifact-use-tracking.service.d.ts +35 -0
- package/dist/lib/services/artifact-use-tracking.service.d.ts.map +1 -0
- package/dist/lib/services/artifact-use-tracking.service.js +76 -0
- package/dist/lib/services/artifact-use-tracking.service.js.map +1 -0
- package/dist/lib/services/collection-permission.service.d.ts +1 -1
- package/dist/lib/services/collection-permission.service.d.ts.map +1 -1
- package/dist/lib/services/collection-permission.service.js +13 -13
- package/dist/lib/services/collection-permission.service.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts +30 -3
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +127 -34
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-state.service.d.ts +14 -1
- package/dist/lib/services/conversation-state.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-state.service.js +36 -9
- package/dist/lib/services/conversation-state.service.js.map +1 -1
- package/dist/lib/services/data-cache.service.d.ts +1 -1
- package/dist/lib/services/data-cache.service.d.ts.map +1 -1
- package/dist/lib/services/data-cache.service.js +13 -13
- package/dist/lib/services/data-cache.service.js.map +1 -1
- package/dist/lib/services/export.service.d.ts +1 -1
- package/dist/lib/services/export.service.d.ts.map +1 -1
- package/dist/lib/services/export.service.js +13 -15
- package/dist/lib/services/export.service.js.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.d.ts +1 -1
- package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
- package/dist/lib/services/mention-autocomplete.service.js +5 -5
- package/dist/lib/services/mention-autocomplete.service.js.map +1 -1
- package/dist/lib/services/mention-parser.service.d.ts +1 -1
- package/dist/lib/services/mention-parser.service.d.ts.map +1 -1
- package/dist/lib/services/mention-parser.service.js +16 -13
- package/dist/lib/services/mention-parser.service.js.map +1 -1
- package/dist/lib/services/search.service.d.ts +1 -1
- package/dist/lib/services/search.service.d.ts.map +1 -1
- package/dist/lib/services/search.service.js +32 -26
- package/dist/lib/services/search.service.js.map +1 -1
- package/dist/public-api.d.ts +3 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +3 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +14 -13
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Component, Input, Output, EventEmitter, ViewChild
|
|
2
|
-
import { Metadata
|
|
1
|
+
import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core';
|
|
2
|
+
import { Metadata } from '@memberjunction/core';
|
|
3
3
|
import { GraphQLDataProvider, GraphQLAIClient } from '@memberjunction/graphql-dataprovider';
|
|
4
4
|
import { AIEngineBase } from '@memberjunction/ai-engine-base';
|
|
5
|
+
import { MJNotificationService } from '@memberjunction/ng-notifications';
|
|
5
6
|
import * as i0 from "@angular/core";
|
|
6
7
|
import * as i1 from "../../services/dialog.service";
|
|
7
8
|
import * as i2 from "../../services/toast.service";
|
|
@@ -37,12 +38,16 @@ export class MessageInputComponent {
|
|
|
37
38
|
// Default artifact type ID for JSON (when agent doesn't specify DefaultArtifactTypeID)
|
|
38
39
|
JSON_ARTIFACT_TYPE_ID = 'ae674c7e-ea0d-49ea-89e4-0649f5eb20d4';
|
|
39
40
|
conversationId;
|
|
41
|
+
conversationName; // For task tracking display
|
|
40
42
|
currentUser;
|
|
41
43
|
disabled = false;
|
|
42
44
|
placeholder = 'Type a message... (Ctrl+Enter to send)';
|
|
43
45
|
parentMessageId; // Optional: for replying in threads
|
|
44
46
|
conversationHistory = []; // For agent context
|
|
45
47
|
initialMessage = null; // Message to send automatically when component initializes
|
|
48
|
+
artifactsByDetailId; // Pre-loaded artifact data for performance
|
|
49
|
+
agentRunsByDetailId; // Pre-loaded agent run data for performance
|
|
50
|
+
inProgressMessageIds; // Message IDs that are in-progress and need streaming reconnection
|
|
46
51
|
messageSent = new EventEmitter();
|
|
47
52
|
agentResponse = new EventEmitter();
|
|
48
53
|
agentRunDetected = new EventEmitter();
|
|
@@ -80,12 +85,18 @@ export class MessageInputComponent {
|
|
|
80
85
|
await this.mentionAutocomplete.initialize(this.currentUser);
|
|
81
86
|
// Subscribe to PubSub for task progress updates
|
|
82
87
|
this.subscribeToPushStatus();
|
|
88
|
+
// Reconnect to any in-progress messages for streaming updates
|
|
89
|
+
this.reconnectInProgressMessages();
|
|
83
90
|
}
|
|
84
91
|
ngOnChanges(changes) {
|
|
85
92
|
// When conversation changes, focus the input
|
|
86
93
|
if (changes['conversationId'] && !changes['conversationId'].firstChange) {
|
|
87
94
|
this.focusInput();
|
|
88
95
|
}
|
|
96
|
+
// When in-progress message IDs change (switching conversations), reconnect
|
|
97
|
+
if (changes['inProgressMessageIds']) {
|
|
98
|
+
this.reconnectInProgressMessages();
|
|
99
|
+
}
|
|
89
100
|
}
|
|
90
101
|
ngAfterViewInit() {
|
|
91
102
|
// Focus input on initial load
|
|
@@ -115,6 +126,24 @@ export class MessageInputComponent {
|
|
|
115
126
|
}
|
|
116
127
|
}, 100);
|
|
117
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Reconnect to in-progress messages for streaming updates
|
|
131
|
+
* This is called when:
|
|
132
|
+
* 1. Component initializes (ngOnInit)
|
|
133
|
+
* 2. Conversation changes (ngOnChanges)
|
|
134
|
+
* 3. User returns to a conversation with in-progress messages
|
|
135
|
+
*/
|
|
136
|
+
reconnectInProgressMessages() {
|
|
137
|
+
if (!this.inProgressMessageIds || this.inProgressMessageIds.length === 0) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
console.log(`🔌 Reconnecting to ${this.inProgressMessageIds.length} in-progress messages for streaming updates`);
|
|
141
|
+
// Register all in-progress message IDs to receive PubSub updates
|
|
142
|
+
for (const messageId of this.inProgressMessageIds) {
|
|
143
|
+
this.activeTaskExecutionMessageIds.add(messageId);
|
|
144
|
+
}
|
|
145
|
+
console.log(`✅ Registered ${this.activeTaskExecutionMessageIds.size} messages for streaming updates`);
|
|
146
|
+
}
|
|
118
147
|
/**
|
|
119
148
|
* Subscribe to PubSub for real-time task orchestration progress updates
|
|
120
149
|
*/
|
|
@@ -366,13 +395,18 @@ export class MessageInputComponent {
|
|
|
366
395
|
*/
|
|
367
396
|
async handleAgentContinuity(messageDetail, lastAgentId, mentionResult, isFirstMessage) {
|
|
368
397
|
console.log('🔍 Previous agent found, checking continuity intent...');
|
|
369
|
-
const
|
|
370
|
-
if (
|
|
371
|
-
console.log('✅ Intent check: YES - continuing with previous agent'
|
|
372
|
-
|
|
398
|
+
const intentResult = await this.checkContinuityIntent(lastAgentId, messageDetail.Message);
|
|
399
|
+
if (intentResult.decision === 'YES') {
|
|
400
|
+
console.log('✅ Intent check: YES - continuing with previous agent', {
|
|
401
|
+
reasoning: intentResult.reasoning,
|
|
402
|
+
targetArtifactVersionId: intentResult.targetArtifactVersionId
|
|
403
|
+
});
|
|
404
|
+
await this.executeRouteWithNaming(() => this.continueWithAgent(messageDetail, lastAgentId, this.conversationId, intentResult.targetArtifactVersionId), messageDetail.Message, isFirstMessage);
|
|
373
405
|
}
|
|
374
406
|
else {
|
|
375
|
-
console.log(`🤖 Intent check: ${
|
|
407
|
+
console.log(`🤖 Intent check: ${intentResult.decision} - routing through Sage for evaluation`, {
|
|
408
|
+
reasoning: intentResult.reasoning
|
|
409
|
+
});
|
|
376
410
|
await this.executeRouteWithNaming(() => this.processMessageThroughAgent(messageDetail, mentionResult), messageDetail.Message, isFirstMessage);
|
|
377
411
|
}
|
|
378
412
|
}
|
|
@@ -390,7 +424,9 @@ export class MessageInputComponent {
|
|
|
390
424
|
const lastAIMessage = this.conversationHistory
|
|
391
425
|
.slice()
|
|
392
426
|
.reverse()
|
|
393
|
-
.find(
|
|
427
|
+
.find(msg => msg.Role === 'AI' &&
|
|
428
|
+
msg.AgentID &&
|
|
429
|
+
msg.AgentID !== this.converationManagerAgent?.ID);
|
|
394
430
|
return lastAIMessage?.AgentID || null;
|
|
395
431
|
}
|
|
396
432
|
/**
|
|
@@ -401,12 +437,20 @@ export class MessageInputComponent {
|
|
|
401
437
|
// Emit event to show temporary "Analyzing intent..." message in conversation
|
|
402
438
|
this.intentCheckStarted.emit();
|
|
403
439
|
try {
|
|
404
|
-
|
|
440
|
+
// Build context from pre-loaded maps (if available)
|
|
441
|
+
if (!this.artifactsByDetailId || !this.agentRunsByDetailId) {
|
|
442
|
+
console.warn('⚠️ Artifact/agent run context not available for intent check');
|
|
443
|
+
return { decision: 'UNSURE', reasoning: 'Context not available' };
|
|
444
|
+
}
|
|
445
|
+
const intent = await this.agentService.checkAgentContinuityIntent(agentId, message, this.conversationHistory, {
|
|
446
|
+
artifactsByDetailId: this.artifactsByDetailId,
|
|
447
|
+
agentRunsByDetailId: this.agentRunsByDetailId
|
|
448
|
+
});
|
|
405
449
|
return intent;
|
|
406
450
|
}
|
|
407
451
|
catch (error) {
|
|
408
452
|
console.error('❌ Intent check failed, defaulting to UNSURE:', error);
|
|
409
|
-
return 'UNSURE';
|
|
453
|
+
return { decision: 'UNSURE', reasoning: 'Intent check failed with error' };
|
|
410
454
|
}
|
|
411
455
|
finally {
|
|
412
456
|
// Emit event to remove temporary intent checking message
|
|
@@ -418,7 +462,10 @@ export class MessageInputComponent {
|
|
|
418
462
|
*/
|
|
419
463
|
async executeRouteWithNaming(routeFunction, userMessage, isFirstMessage) {
|
|
420
464
|
if (isFirstMessage) {
|
|
421
|
-
await Promise.all([
|
|
465
|
+
await Promise.all([
|
|
466
|
+
routeFunction(),
|
|
467
|
+
this.nameConversation(userMessage)
|
|
468
|
+
]);
|
|
422
469
|
}
|
|
423
470
|
else {
|
|
424
471
|
await routeFunction();
|
|
@@ -476,12 +523,6 @@ export class MessageInputComponent {
|
|
|
476
523
|
return async (progress) => {
|
|
477
524
|
let progressAgentRun = progress.metadata?.agentRun;
|
|
478
525
|
const progressAgentRunId = progressAgentRun?.ID || progress.metadata?.agentRunId;
|
|
479
|
-
// if (!progressAgentRun && progressAgentRunId) {
|
|
480
|
-
// // load the full agent run object from the database if we only have the ID
|
|
481
|
-
// const md = new Metadata();
|
|
482
|
-
// progressAgentRun = await md.GetEntityObject<AIAgentRunEntity>("MJ: AI Agent Runs");
|
|
483
|
-
// await progressAgentRun.Load(progressAgentRunId);
|
|
484
|
-
// }
|
|
485
526
|
// Capture the agent run ID from the first progress message
|
|
486
527
|
if (!capturedAgentRunId && progressAgentRunId) {
|
|
487
528
|
capturedAgentRunId = progressAgentRunId;
|
|
@@ -514,7 +555,7 @@ export class MessageInputComponent {
|
|
|
514
555
|
this.agentRunUpdate.emit({
|
|
515
556
|
conversationDetailId: conversationDetail.ID,
|
|
516
557
|
agentRun: progressAgentRun,
|
|
517
|
-
agentRunId: progressAgentRunId
|
|
558
|
+
agentRunId: progressAgentRunId
|
|
518
559
|
});
|
|
519
560
|
}
|
|
520
561
|
else if (progressAgentRunId && !capturedAgentRunId) {
|
|
@@ -522,7 +563,7 @@ export class MessageInputComponent {
|
|
|
522
563
|
// This will trigger a database query to load the agent run
|
|
523
564
|
this.agentRunDetected.emit({
|
|
524
565
|
conversationDetailId: conversationDetail.ID,
|
|
525
|
-
agentRunId: progressAgentRunId
|
|
566
|
+
agentRunId: progressAgentRunId
|
|
526
567
|
});
|
|
527
568
|
}
|
|
528
569
|
if (conversationDetail.Status === 'In-Progress') {
|
|
@@ -541,7 +582,7 @@ export class MessageInputComponent {
|
|
|
541
582
|
}
|
|
542
583
|
console.log(`[${agentName}] Progress: ${progress.step} - ${progress.message} (${progress.percentage}%)`, {
|
|
543
584
|
agentRunId: progressAgentRunId,
|
|
544
|
-
conversationDetailId: conversationDetail.ID
|
|
585
|
+
conversationDetailId: conversationDetail.ID
|
|
545
586
|
});
|
|
546
587
|
};
|
|
547
588
|
}
|
|
@@ -577,24 +618,19 @@ export class MessageInputComponent {
|
|
|
577
618
|
status: 'Evaluating message...',
|
|
578
619
|
relatedMessageId: userMessage.ID,
|
|
579
620
|
conversationDetailId: conversationManagerMessage.ID,
|
|
621
|
+
conversationId: this.conversationId,
|
|
622
|
+
conversationName: this.conversationName
|
|
580
623
|
});
|
|
581
624
|
const result = await this.agentService.processMessage(conversationId, userMessage, this.conversationHistory, conversationManagerMessage.ID, this.createProgressCallback(conversationManagerMessage, 'Sage'));
|
|
582
|
-
//
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
taskId = null;
|
|
586
|
-
}
|
|
625
|
+
// Task will be removed automatically in markMessageComplete()
|
|
626
|
+
// DO NOT remove here - agent may still be streaming/processing
|
|
627
|
+
taskId = null; // Clear reference but don't remove from service
|
|
587
628
|
if (!result || !result.success) {
|
|
588
|
-
// Evaluation failed -
|
|
589
|
-
|
|
590
|
-
conversationManagerMessage.
|
|
591
|
-
conversationManagerMessage
|
|
592
|
-
|
|
593
|
-
await conversationManagerMessage.Save();
|
|
594
|
-
this.messageSent.emit(conversationManagerMessage);
|
|
595
|
-
userMessage.Status = 'Complete';
|
|
596
|
-
await userMessage.Save();
|
|
597
|
-
this.messageSent.emit(userMessage);
|
|
629
|
+
// Evaluation failed - use updateConversationDetail to ensure task cleanup
|
|
630
|
+
const errorMsg = result?.agentRun?.ErrorMessage || 'Agent evaluation failed';
|
|
631
|
+
conversationManagerMessage.Error = errorMsg;
|
|
632
|
+
await this.updateConversationDetail(conversationManagerMessage, `❌ Evaluation failed`, 'Error');
|
|
633
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
598
634
|
console.warn('⚠️ Sage failed:', result?.agentRun?.ErrorMessage);
|
|
599
635
|
// Clean up completion timestamp
|
|
600
636
|
this.cleanupCompletionTimestamp(conversationManagerMessage.ID);
|
|
@@ -606,7 +642,7 @@ export class MessageInputComponent {
|
|
|
606
642
|
hasMessage: !!result.agentRun.Message,
|
|
607
643
|
payloadKeys: result.payload ? Object.keys(result.payload) : [],
|
|
608
644
|
payload: result.payload, // Full payload for debugging,
|
|
609
|
-
suggestedResponses: result.suggestedResponses
|
|
645
|
+
suggestedResponses: result.suggestedResponses
|
|
610
646
|
});
|
|
611
647
|
// Stage 2: Check for task graph (multi-step orchestration)
|
|
612
648
|
if (result.payload?.taskGraph) {
|
|
@@ -614,7 +650,7 @@ export class MessageInputComponent {
|
|
|
614
650
|
await this.handleTaskGraphExecution(userMessage, result, this.conversationId, conversationManagerMessage);
|
|
615
651
|
// Remove CM from active tasks
|
|
616
652
|
if (taskId) {
|
|
617
|
-
this.activeTasks.remove(taskId);
|
|
653
|
+
// Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
|
|
618
654
|
}
|
|
619
655
|
}
|
|
620
656
|
// Stage 3: Check for sub-agent invocation (single-step delegation)
|
|
@@ -623,7 +659,7 @@ export class MessageInputComponent {
|
|
|
623
659
|
await this.handleSubAgentInvocation(userMessage, result, this.conversationId, conversationManagerMessage);
|
|
624
660
|
// Remove CM from active tasks
|
|
625
661
|
if (taskId) {
|
|
626
|
-
this.activeTasks.remove(taskId);
|
|
662
|
+
// Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
|
|
627
663
|
}
|
|
628
664
|
}
|
|
629
665
|
// Stage 4: Direct chat response from Sage
|
|
@@ -641,17 +677,15 @@ export class MessageInputComponent {
|
|
|
641
677
|
versionId: '',
|
|
642
678
|
versionNumber: 0,
|
|
643
679
|
conversationDetailId: conversationManagerMessage.ID,
|
|
644
|
-
name: ''
|
|
680
|
+
name: ''
|
|
645
681
|
});
|
|
646
682
|
console.log('🎨 Server created artifact, UI will reload to show it');
|
|
647
683
|
this.messageSent.emit(conversationManagerMessage);
|
|
648
684
|
}
|
|
649
|
-
userMessage.
|
|
650
|
-
await userMessage.Save();
|
|
651
|
-
this.messageSent.emit(userMessage);
|
|
685
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
652
686
|
// Remove CM from active tasks
|
|
653
687
|
if (taskId) {
|
|
654
|
-
this.activeTasks.remove(taskId);
|
|
688
|
+
// Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
|
|
655
689
|
}
|
|
656
690
|
// Clean up completion timestamp after delay
|
|
657
691
|
this.cleanupCompletionTimestamp(conversationManagerMessage.ID);
|
|
@@ -685,7 +719,7 @@ export class MessageInputComponent {
|
|
|
685
719
|
}
|
|
686
720
|
// Remove CM from active tasks
|
|
687
721
|
if (taskId) {
|
|
688
|
-
this.activeTasks.remove(taskId);
|
|
722
|
+
// Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
|
|
689
723
|
}
|
|
690
724
|
}
|
|
691
725
|
}
|
|
@@ -693,23 +727,17 @@ export class MessageInputComponent {
|
|
|
693
727
|
console.error('❌ Error processing message through agents:', error);
|
|
694
728
|
// Update conversationManagerMessage status to Error
|
|
695
729
|
if (conversationManagerMessage && conversationManagerMessage.ID) {
|
|
696
|
-
//
|
|
697
|
-
this.markMessageComplete(conversationManagerMessage);
|
|
698
|
-
conversationManagerMessage.Status = 'Error';
|
|
699
|
-
conversationManagerMessage.Message = `❌ Error: ${String(error)}`;
|
|
730
|
+
// Use updateConversationDetail to ensure task cleanup
|
|
700
731
|
conversationManagerMessage.Error = String(error);
|
|
701
|
-
await
|
|
702
|
-
this.messageSent.emit(conversationManagerMessage);
|
|
732
|
+
await this.updateConversationDetail(conversationManagerMessage, `❌ Error: ${String(error)}`, 'Error');
|
|
703
733
|
// Clean up completion timestamp
|
|
704
734
|
this.cleanupCompletionTimestamp(conversationManagerMessage.ID);
|
|
705
735
|
}
|
|
706
736
|
// Mark user message as complete
|
|
707
|
-
userMessage.
|
|
708
|
-
await userMessage.Save();
|
|
709
|
-
this.messageSent.emit(userMessage);
|
|
737
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
710
738
|
// Clean up active task
|
|
711
739
|
if (taskId) {
|
|
712
|
-
this.activeTasks.remove(taskId);
|
|
740
|
+
// Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
|
|
713
741
|
}
|
|
714
742
|
}
|
|
715
743
|
}
|
|
@@ -724,9 +752,8 @@ export class MessageInputComponent {
|
|
|
724
752
|
const taskCount = taskGraph.tasks?.length || 0;
|
|
725
753
|
console.log(`📋 Task graph execution requested: ${workflowName}`, {
|
|
726
754
|
reasoning,
|
|
727
|
-
taskCount
|
|
755
|
+
taskCount
|
|
728
756
|
});
|
|
729
|
-
const md = new Metadata();
|
|
730
757
|
// Deduplicate tasks by tempId (LLM sometimes returns duplicates)
|
|
731
758
|
const seenTempIds = new Set();
|
|
732
759
|
const uniqueTasks = taskGraph.tasks.filter((task) => {
|
|
@@ -800,31 +827,27 @@ export class MessageInputComponent {
|
|
|
800
827
|
conversationDetailId: taskExecutionMessage.ID, // Link tasks to execution message, not CM message
|
|
801
828
|
environmentId: environmentId,
|
|
802
829
|
sessionId: sessionId,
|
|
803
|
-
createNotifications: true
|
|
830
|
+
createNotifications: true
|
|
804
831
|
};
|
|
805
832
|
const result = await GraphQLDataProvider.Instance.ExecuteGQL(mutation, variables);
|
|
806
833
|
console.log('📊 ExecuteTaskGraph result:', {
|
|
807
834
|
hasExecuteTaskGraph: !!result?.ExecuteTaskGraph,
|
|
808
835
|
success: result?.ExecuteTaskGraph?.success,
|
|
809
836
|
resultsCount: result?.ExecuteTaskGraph?.results?.length,
|
|
810
|
-
result: result
|
|
837
|
+
result: result
|
|
811
838
|
});
|
|
812
839
|
// Step 4: Update task execution message with results
|
|
813
840
|
// ExecuteGQL returns data directly (not wrapped in {data, errors})
|
|
814
841
|
if (result?.ExecuteTaskGraph?.success) {
|
|
815
842
|
console.log('✅ Task graph execution completed successfully');
|
|
816
|
-
taskExecutionMessage
|
|
817
|
-
taskExecutionMessage.Status = 'Complete';
|
|
843
|
+
await this.updateConversationDetail(taskExecutionMessage, `✅ **${workflowName}** completed successfully`, 'Complete');
|
|
818
844
|
}
|
|
819
845
|
else {
|
|
820
846
|
const errorMsg = result?.ExecuteTaskGraph?.errorMessage || 'Unknown error';
|
|
821
847
|
console.error('❌ Task graph execution failed:', errorMsg);
|
|
822
|
-
taskExecutionMessage.Message = `❌ **${workflowName}** failed: ${errorMsg}`;
|
|
823
|
-
taskExecutionMessage.Status = 'Error';
|
|
824
848
|
taskExecutionMessage.Error = errorMsg;
|
|
849
|
+
await this.updateConversationDetail(taskExecutionMessage, `❌ **${workflowName}** failed: ${errorMsg}`, 'Error');
|
|
825
850
|
}
|
|
826
|
-
await taskExecutionMessage.Save();
|
|
827
|
-
this.messageSent.emit(taskExecutionMessage);
|
|
828
851
|
// Trigger artifact reload for this message
|
|
829
852
|
// Artifacts were created on server during task execution and linked to this message
|
|
830
853
|
// This event triggers the parent component to reload artifacts from the database
|
|
@@ -833,45 +856,46 @@ export class MessageInputComponent {
|
|
|
833
856
|
versionId: '',
|
|
834
857
|
versionNumber: 1,
|
|
835
858
|
conversationDetailId: taskExecutionMessage.ID,
|
|
836
|
-
name: ''
|
|
859
|
+
name: ''
|
|
837
860
|
});
|
|
838
861
|
// Unregister from real-time updates (task complete)
|
|
839
862
|
this.activeTaskExecutionMessageIds.delete(taskExecutionMessage.ID);
|
|
863
|
+
// Mark agent response message as complete (removes task from active tasks)
|
|
864
|
+
await this.updateConversationDetail(conversationManagerMessage, conversationManagerMessage.Message, 'Complete');
|
|
840
865
|
// Mark user message as complete
|
|
841
|
-
userMessage.
|
|
842
|
-
await userMessage.Save();
|
|
843
|
-
this.messageSent.emit(userMessage);
|
|
866
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
844
867
|
}
|
|
845
868
|
catch (error) {
|
|
846
869
|
console.error('❌ Error executing task graph:', error);
|
|
847
|
-
taskExecutionMessage.Message = `❌ **${workflowName}** - Error: ${String(error)}`;
|
|
848
|
-
taskExecutionMessage.Status = 'Error';
|
|
849
870
|
taskExecutionMessage.Error = String(error);
|
|
850
|
-
await
|
|
851
|
-
this.messageSent.emit(taskExecutionMessage);
|
|
871
|
+
await this.updateConversationDetail(taskExecutionMessage, `❌ **${workflowName}** - Error: ${String(error)}`, 'Error');
|
|
852
872
|
// Trigger artifact reload even on error - partial artifacts may have been created
|
|
853
873
|
this.artifactCreated.emit({
|
|
854
874
|
artifactId: '',
|
|
855
875
|
versionId: '',
|
|
856
876
|
versionNumber: 1,
|
|
857
877
|
conversationDetailId: taskExecutionMessage.ID,
|
|
858
|
-
name: ''
|
|
878
|
+
name: ''
|
|
859
879
|
});
|
|
860
880
|
// Unregister from real-time updates (task failed)
|
|
861
881
|
this.activeTaskExecutionMessageIds.delete(taskExecutionMessage.ID);
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
this.
|
|
882
|
+
// Mark agent response message as complete (removes task from active tasks)
|
|
883
|
+
conversationManagerMessage.Error = String(error);
|
|
884
|
+
await this.updateConversationDetail(conversationManagerMessage, conversationManagerMessage.Message, 'Error');
|
|
885
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
865
886
|
}
|
|
866
887
|
}
|
|
867
888
|
async updateConversationDetail(convoDetail, message, status, suggestedResponses) {
|
|
868
|
-
if
|
|
869
|
-
|
|
870
|
-
}
|
|
871
|
-
// Mark as completing BEFORE updating if status is Complete or Error
|
|
889
|
+
// Mark as completing FIRST if status is Complete or Error
|
|
890
|
+
// This ensures task cleanup happens even if we return early due to guard clause
|
|
872
891
|
if (status === 'Complete' || status === 'Error') {
|
|
873
892
|
this.markMessageComplete(convoDetail);
|
|
874
893
|
}
|
|
894
|
+
// Guard clause: Don't re-save if already complete/errored (prevents duplicate saves)
|
|
895
|
+
// Task has already been removed by markMessageComplete() above
|
|
896
|
+
if (convoDetail.Status === 'Complete' || convoDetail.Status === 'Error') {
|
|
897
|
+
return; // Already complete, no need to save again
|
|
898
|
+
}
|
|
875
899
|
const maxAttempts = 2;
|
|
876
900
|
let attempts = 0, done = false;
|
|
877
901
|
while (attempts < maxAttempts && !done) {
|
|
@@ -903,7 +927,7 @@ export class MessageInputComponent {
|
|
|
903
927
|
agentName, conversationId, conversationManagerMessage) {
|
|
904
928
|
try {
|
|
905
929
|
// Look up the agent
|
|
906
|
-
const agent = AIEngineBase.Instance.Agents.find(
|
|
930
|
+
const agent = AIEngineBase.Instance.Agents.find(a => a.Name === agentName);
|
|
907
931
|
if (!agent) {
|
|
908
932
|
throw new Error(`Agent not found: ${agentName}`);
|
|
909
933
|
}
|
|
@@ -924,15 +948,17 @@ export class MessageInputComponent {
|
|
|
924
948
|
status: 'Starting...',
|
|
925
949
|
relatedMessageId: userMessage.ID,
|
|
926
950
|
conversationDetailId: agentResponseMessage.ID,
|
|
951
|
+
conversationId: this.conversationId,
|
|
952
|
+
conversationName: this.conversationName
|
|
927
953
|
});
|
|
928
954
|
// Invoke agent with task's input payload
|
|
929
955
|
const agentResult = await this.agentService.invokeSubAgent(agentName, conversationId, userMessage, this.conversationHistory, task.description || task.name, agentResponseMessage.ID, task.inputPayload, // Pass the task's input payload
|
|
930
956
|
this.createProgressCallback(agentResponseMessage, agentName));
|
|
931
|
-
//
|
|
932
|
-
|
|
957
|
+
// Task will be removed automatically in markMessageComplete() when status changes to Complete/Error
|
|
958
|
+
// DO NOT remove here - allows UI to show task during entire execution
|
|
933
959
|
if (agentResult && agentResult.success) {
|
|
934
960
|
// Update message with result
|
|
935
|
-
await this.updateConversationDetail(agentResponseMessage, agentResult.agentRun?.Message || `✅ **${agentName}** completed`, 'Complete');
|
|
961
|
+
await this.updateConversationDetail(agentResponseMessage, agentResult.agentRun?.Message || `✅ **${agentName}** completed`, 'Complete', agentResult.suggestedResponses);
|
|
936
962
|
// Server created artifacts - emit event to trigger UI reload
|
|
937
963
|
if (agentResult.payload && Object.keys(agentResult.payload).length > 0) {
|
|
938
964
|
this.artifactCreated.emit({
|
|
@@ -940,7 +966,7 @@ export class MessageInputComponent {
|
|
|
940
966
|
versionId: '',
|
|
941
967
|
versionNumber: 0,
|
|
942
968
|
conversationDetailId: agentResponseMessage.ID,
|
|
943
|
-
name: ''
|
|
969
|
+
name: ''
|
|
944
970
|
});
|
|
945
971
|
console.log('🎨 Server created artifact from single task execution');
|
|
946
972
|
this.messageSent.emit(agentResponseMessage);
|
|
@@ -949,22 +975,15 @@ export class MessageInputComponent {
|
|
|
949
975
|
else {
|
|
950
976
|
// Handle failure
|
|
951
977
|
const errorMsg = agentResult?.agentRun?.ErrorMessage || 'Agent execution failed';
|
|
952
|
-
agentResponseMessage.Message = `❌ **${agentName}** failed: ${errorMsg}`;
|
|
953
|
-
agentResponseMessage.Status = 'Error';
|
|
954
978
|
agentResponseMessage.Error = errorMsg;
|
|
955
|
-
await
|
|
956
|
-
this.messageSent.emit(agentResponseMessage);
|
|
979
|
+
await this.updateConversationDetail(agentResponseMessage, `❌ **${agentName}** failed: ${errorMsg}`, 'Error');
|
|
957
980
|
}
|
|
958
981
|
// Mark user message as complete
|
|
959
|
-
userMessage.
|
|
960
|
-
await userMessage.Save();
|
|
961
|
-
this.messageSent.emit(userMessage);
|
|
982
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
962
983
|
}
|
|
963
984
|
catch (error) {
|
|
964
985
|
console.error('❌ Error in single task execution:', error);
|
|
965
|
-
userMessage.
|
|
966
|
-
await userMessage.Save();
|
|
967
|
-
this.messageSent.emit(userMessage);
|
|
986
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
968
987
|
}
|
|
969
988
|
}
|
|
970
989
|
/**
|
|
@@ -978,7 +997,7 @@ export class MessageInputComponent {
|
|
|
978
997
|
// Now create a NEW message for the sub-agent execution
|
|
979
998
|
try {
|
|
980
999
|
// Look up the agent to get its ID
|
|
981
|
-
const agent = AIEngineBase.Instance.Agents.find(
|
|
1000
|
+
const agent = AIEngineBase.Instance.Agents.find(a => a.Name === agentName);
|
|
982
1001
|
// Create AI response message BEFORE invoking agent (for duration tracking)
|
|
983
1002
|
const agentResponseMessage = await this.dataCache.createConversationDetail(this.currentUser);
|
|
984
1003
|
agentResponseMessage.ConversationID = conversationId;
|
|
@@ -1000,19 +1019,21 @@ export class MessageInputComponent {
|
|
|
1000
1019
|
status: 'Starting...',
|
|
1001
1020
|
relatedMessageId: userMessage.ID,
|
|
1002
1021
|
conversationDetailId: agentResponseMessage.ID,
|
|
1022
|
+
conversationId: this.conversationId,
|
|
1023
|
+
conversationName: this.conversationName
|
|
1003
1024
|
});
|
|
1004
1025
|
// Invoke the sub-agent with progress callback
|
|
1005
1026
|
const subResult = await this.agentService.invokeSubAgent(agentName, conversationId, userMessage, this.conversationHistory, reasoning, agentResponseMessage.ID, undefined, // no payload for initial invocation
|
|
1006
1027
|
this.createProgressCallback(agentResponseMessage, agentName));
|
|
1007
|
-
//
|
|
1008
|
-
|
|
1028
|
+
// Task will be removed automatically in markMessageComplete() when status changes to Complete/Error
|
|
1029
|
+
// DO NOT remove here - allows UI to show task during entire execution
|
|
1009
1030
|
if (subResult && subResult.success) {
|
|
1010
1031
|
// Update the response message with agent result
|
|
1011
1032
|
// Store the agent ID for display
|
|
1012
1033
|
if (subResult.agentRun.AgentID) {
|
|
1013
1034
|
agentResponseMessage.AgentID = subResult.agentRun.AgentID;
|
|
1014
1035
|
}
|
|
1015
|
-
await this.updateConversationDetail(agentResponseMessage, subResult.agentRun?.Message || `✅ **${agentName}** completed`, 'Complete');
|
|
1036
|
+
await this.updateConversationDetail(agentResponseMessage, subResult.agentRun?.Message || `✅ **${agentName}** completed`, 'Complete', subResult.suggestedResponses);
|
|
1016
1037
|
// Server created artifacts - emit event to trigger UI reload
|
|
1017
1038
|
if (subResult.payload && Object.keys(subResult.payload).length > 0) {
|
|
1018
1039
|
this.artifactCreated.emit({
|
|
@@ -1020,23 +1041,21 @@ export class MessageInputComponent {
|
|
|
1020
1041
|
versionId: '',
|
|
1021
1042
|
versionNumber: 0,
|
|
1022
1043
|
conversationDetailId: agentResponseMessage.ID,
|
|
1023
|
-
name: ''
|
|
1044
|
+
name: ''
|
|
1024
1045
|
});
|
|
1025
1046
|
console.log('🎨 Server created artifact for sub-agent message:', agentResponseMessage.ID);
|
|
1026
1047
|
// Re-emit to trigger artifact display
|
|
1027
1048
|
this.messageSent.emit(agentResponseMessage);
|
|
1028
1049
|
}
|
|
1029
1050
|
// Mark user message as complete
|
|
1030
|
-
userMessage.
|
|
1031
|
-
await userMessage.Save();
|
|
1032
|
-
this.messageSent.emit(userMessage);
|
|
1051
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
1033
1052
|
}
|
|
1034
1053
|
else {
|
|
1035
1054
|
// Sub-agent failed - attempt auto-retry once
|
|
1036
1055
|
console.log(`⚠️ ${agentName} failed, attempting auto-retry...`);
|
|
1037
1056
|
await this.updateConversationDetail(conversationManagerMessage, `👉 **${agentName}** will handle this request...\n\n⚠️ First attempt failed, retrying...`, conversationManagerMessage.Status);
|
|
1038
1057
|
// Update the existing agentResponseMessage to show retry status
|
|
1039
|
-
await this.updateConversationDetail(agentResponseMessage,
|
|
1058
|
+
await this.updateConversationDetail(agentResponseMessage, "Retrying...", agentResponseMessage.Status);
|
|
1040
1059
|
// Retry the sub-agent
|
|
1041
1060
|
const retryResult = await this.agentService.invokeSubAgent(agentName, conversationId, userMessage, this.conversationHistory, reasoning, agentResponseMessage.ID, undefined, // no payload for retry
|
|
1042
1061
|
this.createProgressCallback(agentResponseMessage, `${agentName} (retry)`));
|
|
@@ -1053,37 +1072,25 @@ export class MessageInputComponent {
|
|
|
1053
1072
|
versionId: '',
|
|
1054
1073
|
versionNumber: 0,
|
|
1055
1074
|
conversationDetailId: agentResponseMessage.ID,
|
|
1056
|
-
name: ''
|
|
1075
|
+
name: ''
|
|
1057
1076
|
});
|
|
1058
1077
|
this.messageSent.emit(agentResponseMessage);
|
|
1059
1078
|
}
|
|
1060
|
-
userMessage.
|
|
1061
|
-
await userMessage.Save();
|
|
1062
|
-
this.messageSent.emit(userMessage);
|
|
1079
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
1063
1080
|
}
|
|
1064
1081
|
else {
|
|
1065
1082
|
// Retry also failed - show error with manual retry option
|
|
1066
|
-
conversationManagerMessage.Status = 'Error';
|
|
1067
|
-
conversationManagerMessage.Message = `❌ **${agentName}** failed after retry\n\n${retryResult?.agentRun?.ErrorMessage || 'Unknown error'}`;
|
|
1068
1083
|
conversationManagerMessage.Error = retryResult?.agentRun?.ErrorMessage || null;
|
|
1069
|
-
await
|
|
1070
|
-
this.
|
|
1071
|
-
userMessage.Status = 'Complete'; // Don't mark user message as error
|
|
1072
|
-
await userMessage.Save();
|
|
1073
|
-
this.messageSent.emit(userMessage);
|
|
1084
|
+
await this.updateConversationDetail(conversationManagerMessage, `❌ **${agentName}** failed after retry\n\n${retryResult?.agentRun?.ErrorMessage || 'Unknown error'}`, 'Error');
|
|
1085
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
1074
1086
|
}
|
|
1075
1087
|
}
|
|
1076
1088
|
}
|
|
1077
1089
|
catch (error) {
|
|
1078
1090
|
console.error(`❌ Error invoking sub-agent ${agentName}:`, error);
|
|
1079
|
-
conversationManagerMessage.Status = 'Error';
|
|
1080
|
-
conversationManagerMessage.Message = `❌ **${agentName}** encountered an error\n\n${String(error)}`;
|
|
1081
1091
|
conversationManagerMessage.Error = String(error);
|
|
1082
|
-
await
|
|
1083
|
-
this.
|
|
1084
|
-
userMessage.Status = 'Complete'; // Don't mark user message as error
|
|
1085
|
-
await userMessage.Save();
|
|
1086
|
-
this.messageSent.emit(userMessage);
|
|
1092
|
+
await this.updateConversationDetail(conversationManagerMessage, `❌ **${agentName}** encountered an error\n\n${String(error)}`, 'Error');
|
|
1093
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
1087
1094
|
}
|
|
1088
1095
|
}
|
|
1089
1096
|
/**
|
|
@@ -1095,63 +1102,46 @@ export class MessageInputComponent {
|
|
|
1095
1102
|
const lastAIMessage = this.conversationHistory
|
|
1096
1103
|
.slice()
|
|
1097
1104
|
.reverse()
|
|
1098
|
-
.find(
|
|
1105
|
+
.find(msg => msg.Role === 'AI' &&
|
|
1106
|
+
msg.AgentID &&
|
|
1107
|
+
msg.AgentID !== this.converationManagerAgent?.ID);
|
|
1099
1108
|
if (!lastAIMessage || !lastAIMessage.AgentID) {
|
|
1100
1109
|
// No previous specialist agent - just mark user message as complete
|
|
1101
1110
|
console.log('🔇 No previous specialist agent found - marking complete');
|
|
1102
|
-
userMessage.
|
|
1103
|
-
await userMessage.Save();
|
|
1104
|
-
this.messageSent.emit(userMessage);
|
|
1111
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
1105
1112
|
return;
|
|
1106
1113
|
}
|
|
1107
1114
|
// Load the agent entity to get its name
|
|
1108
|
-
const
|
|
1109
|
-
|
|
1110
|
-
EntityName: 'AI Agents',
|
|
1111
|
-
ExtraFilter: `ID='${lastAIMessage.AgentID}'`,
|
|
1112
|
-
ResultType: 'entity_object',
|
|
1113
|
-
}, this.currentUser);
|
|
1114
|
-
if (!agentResult.Success || !agentResult.Results || agentResult.Results.length === 0) {
|
|
1115
|
+
const previousAgent = AIEngineBase.Instance.Agents.find(a => a.ID === lastAIMessage.AgentID);
|
|
1116
|
+
if (!previousAgent) {
|
|
1115
1117
|
console.warn('⚠️ Could not load previous agent - marking complete');
|
|
1116
|
-
userMessage.
|
|
1117
|
-
await userMessage.Save();
|
|
1118
|
-
this.messageSent.emit(userMessage);
|
|
1118
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
1119
1119
|
return;
|
|
1120
1120
|
}
|
|
1121
|
-
const previousAgent = agentResult.Results[0];
|
|
1122
1121
|
const agentName = previousAgent.Name || 'Agent';
|
|
1123
1122
|
console.log(`🔄 Agent continuity: Continuing with ${agentName} (AgentID: ${lastAIMessage.AgentID})`);
|
|
1124
|
-
// Load the OUTPUT artifact from the last agent message
|
|
1125
|
-
const artifactResult = await rv.RunView({
|
|
1126
|
-
EntityName: 'MJ: Conversation Detail Artifacts',
|
|
1127
|
-
ExtraFilter: `ConversationDetailID='${lastAIMessage.ID}' AND Direction='Output'`,
|
|
1128
|
-
ResultType: 'entity_object',
|
|
1129
|
-
}, this.currentUser);
|
|
1130
1123
|
let previousPayload = null;
|
|
1131
1124
|
let previousArtifactInfo = null;
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
const
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
const version = versionResult.Results[0];
|
|
1142
|
-
if (version.Content) {
|
|
1143
|
-
try {
|
|
1125
|
+
// Use pre-loaded artifact data (no DB queries!)
|
|
1126
|
+
if (this.artifactsByDetailId) {
|
|
1127
|
+
const artifacts = this.artifactsByDetailId.get(lastAIMessage.ID);
|
|
1128
|
+
if (artifacts && artifacts.length > 0) {
|
|
1129
|
+
try {
|
|
1130
|
+
// Use the first artifact (should only be one OUTPUT per message)
|
|
1131
|
+
const artifact = artifacts[0];
|
|
1132
|
+
const version = await artifact.getVersion();
|
|
1133
|
+
if (version.Content) {
|
|
1144
1134
|
previousPayload = JSON.parse(version.Content);
|
|
1145
1135
|
previousArtifactInfo = {
|
|
1146
|
-
artifactId:
|
|
1147
|
-
versionId:
|
|
1148
|
-
versionNumber:
|
|
1136
|
+
artifactId: artifact.artifactId,
|
|
1137
|
+
versionId: artifact.artifactVersionId,
|
|
1138
|
+
versionNumber: artifact.versionNumber
|
|
1149
1139
|
};
|
|
1150
1140
|
console.log('📦 Loaded previous OUTPUT artifact as payload for continuity', previousArtifactInfo);
|
|
1151
1141
|
}
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1142
|
+
}
|
|
1143
|
+
catch (error) {
|
|
1144
|
+
console.warn('⚠️ Could not parse previous artifact content:', error);
|
|
1155
1145
|
}
|
|
1156
1146
|
}
|
|
1157
1147
|
}
|
|
@@ -1172,12 +1162,14 @@ export class MessageInputComponent {
|
|
|
1172
1162
|
status: 'Processing refinement...',
|
|
1173
1163
|
relatedMessageId: userMessage.ID,
|
|
1174
1164
|
conversationDetailId: statusMessage.ID,
|
|
1165
|
+
conversationId: this.conversationId,
|
|
1166
|
+
conversationName: this.conversationName
|
|
1175
1167
|
});
|
|
1176
1168
|
try {
|
|
1177
1169
|
// Invoke the agent with the previous payload
|
|
1178
1170
|
const continuityResult = await this.agentService.invokeSubAgent(agentName, conversationId, userMessage, this.conversationHistory, 'Continuing previous work based on user feedback', statusMessage.ID, previousPayload, this.createProgressCallback(statusMessage, agentName), previousArtifactInfo?.artifactId, previousArtifactInfo?.versionId);
|
|
1179
1171
|
// Remove from active tasks
|
|
1180
|
-
this.activeTasks.remove(taskId);
|
|
1172
|
+
// Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
|
|
1181
1173
|
if (continuityResult && continuityResult.success) {
|
|
1182
1174
|
// Create response message
|
|
1183
1175
|
const agentResponseMessage = await this.dataCache.createConversationDetail(this.currentUser);
|
|
@@ -1197,39 +1189,27 @@ export class MessageInputComponent {
|
|
|
1197
1189
|
versionId: '',
|
|
1198
1190
|
versionNumber: 0,
|
|
1199
1191
|
conversationDetailId: agentResponseMessage.ID,
|
|
1200
|
-
name: ''
|
|
1192
|
+
name: ''
|
|
1201
1193
|
});
|
|
1202
1194
|
console.log('🎨 Server created artifact (versioned) from agent continuity');
|
|
1203
1195
|
this.messageSent.emit(agentResponseMessage);
|
|
1204
1196
|
}
|
|
1205
1197
|
// Mark user message as complete
|
|
1206
|
-
userMessage.
|
|
1207
|
-
await userMessage.Save();
|
|
1208
|
-
this.messageSent.emit(userMessage);
|
|
1198
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
1209
1199
|
}
|
|
1210
1200
|
else {
|
|
1211
1201
|
// Agent failed
|
|
1212
|
-
statusMessage.Status = 'Error';
|
|
1213
|
-
statusMessage.Message = `❌ **${agentName}** failed during refinement\n\n${continuityResult?.agentRun?.ErrorMessage || 'Unknown error'}`;
|
|
1214
1202
|
statusMessage.Error = continuityResult?.agentRun?.ErrorMessage || null;
|
|
1215
|
-
await
|
|
1216
|
-
this.
|
|
1217
|
-
userMessage.Status = 'Complete';
|
|
1218
|
-
await userMessage.Save();
|
|
1219
|
-
this.messageSent.emit(userMessage);
|
|
1203
|
+
await this.updateConversationDetail(statusMessage, `❌ **${agentName}** failed during refinement\n\n${continuityResult?.agentRun?.ErrorMessage || 'Unknown error'}`, 'Error');
|
|
1204
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
1220
1205
|
}
|
|
1221
1206
|
}
|
|
1222
1207
|
catch (error) {
|
|
1223
1208
|
console.error(`❌ Error in agent continuity with ${agentName}:`, error);
|
|
1224
|
-
this.activeTasks.remove(taskId);
|
|
1225
|
-
statusMessage.Status = 'Error';
|
|
1226
|
-
statusMessage.Message = `❌ **${agentName}** encountered an error\n\n${String(error)}`;
|
|
1209
|
+
// Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
|
|
1227
1210
|
statusMessage.Error = String(error);
|
|
1228
|
-
await
|
|
1229
|
-
this.
|
|
1230
|
-
userMessage.Status = 'Complete';
|
|
1231
|
-
await userMessage.Save();
|
|
1232
|
-
this.messageSent.emit(userMessage);
|
|
1211
|
+
await this.updateConversationDetail(statusMessage, `❌ **${agentName}** encountered an error\n\n${String(error)}`, 'Error');
|
|
1212
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
1233
1213
|
}
|
|
1234
1214
|
}
|
|
1235
1215
|
/**
|
|
@@ -1244,16 +1224,20 @@ export class MessageInputComponent {
|
|
|
1244
1224
|
status: 'Processing...',
|
|
1245
1225
|
relatedMessageId: userMessage.ID,
|
|
1246
1226
|
conversationDetailId: userMessage.ID,
|
|
1227
|
+
conversationId: this.conversationId,
|
|
1228
|
+
conversationName: this.conversationName
|
|
1247
1229
|
});
|
|
1230
|
+
// Declare agentResponseMessage outside try block so it's accessible in catch
|
|
1231
|
+
let agentResponseMessage = undefined;
|
|
1248
1232
|
try {
|
|
1249
1233
|
// Update user message status to In-Progress
|
|
1250
1234
|
userMessage.Status = 'In-Progress';
|
|
1251
1235
|
await userMessage.Save();
|
|
1252
1236
|
this.messageSent.emit(userMessage);
|
|
1253
1237
|
// Look up the agent to get its ID
|
|
1254
|
-
const agent = AIEngineBase.Instance.Agents.find(
|
|
1238
|
+
const agent = AIEngineBase.Instance.Agents.find(a => a.Name === agentName);
|
|
1255
1239
|
// Create AI response message BEFORE invoking agent (for duration tracking)
|
|
1256
|
-
|
|
1240
|
+
agentResponseMessage = await this.dataCache.createConversationDetail(this.currentUser);
|
|
1257
1241
|
agentResponseMessage.ConversationID = conversationId;
|
|
1258
1242
|
agentResponseMessage.Role = 'AI';
|
|
1259
1243
|
agentResponseMessage.Message = '⏳ Starting...'; // Initial message
|
|
@@ -1271,7 +1255,7 @@ export class MessageInputComponent {
|
|
|
1271
1255
|
const result = await this.agentService.invokeSubAgent(agentName, conversationId, userMessage, this.conversationHistory, `User mentioned agent directly with @${agentName}`, agentResponseMessage.ID, undefined, // no payload for direct mention
|
|
1272
1256
|
this.createProgressCallback(agentResponseMessage, agentName));
|
|
1273
1257
|
// Remove from active tasks
|
|
1274
|
-
this.activeTasks.remove(taskId);
|
|
1258
|
+
// Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
|
|
1275
1259
|
if (result && result.success) {
|
|
1276
1260
|
if (result.agentRun.AgentID) {
|
|
1277
1261
|
agentResponseMessage.AgentID = result.agentRun.AgentID;
|
|
@@ -1289,7 +1273,7 @@ export class MessageInputComponent {
|
|
|
1289
1273
|
}
|
|
1290
1274
|
// Stage 3: Normal chat response
|
|
1291
1275
|
else {
|
|
1292
|
-
await this.updateConversationDetail(agentResponseMessage, result.agentRun?.Message || `✅ **${agentName}** completed`, 'Complete');
|
|
1276
|
+
await this.updateConversationDetail(agentResponseMessage, result.agentRun?.Message || `✅ **${agentName}** completed`, 'Complete', result.suggestedResponses);
|
|
1293
1277
|
// Server created artifacts - emit event to trigger UI reload
|
|
1294
1278
|
if (result.payload && Object.keys(result.payload).length > 0) {
|
|
1295
1279
|
this.artifactCreated.emit({
|
|
@@ -1297,108 +1281,105 @@ export class MessageInputComponent {
|
|
|
1297
1281
|
versionId: '',
|
|
1298
1282
|
versionNumber: 0,
|
|
1299
1283
|
conversationDetailId: agentResponseMessage.ID,
|
|
1300
|
-
name: ''
|
|
1284
|
+
name: ''
|
|
1301
1285
|
});
|
|
1302
1286
|
this.messageSent.emit(agentResponseMessage);
|
|
1303
1287
|
}
|
|
1304
1288
|
// Mark user message as complete
|
|
1305
|
-
userMessage.
|
|
1306
|
-
await userMessage.Save();
|
|
1307
|
-
this.messageSent.emit(userMessage);
|
|
1289
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
1308
1290
|
}
|
|
1309
1291
|
}
|
|
1310
1292
|
else {
|
|
1311
|
-
// Agent failed -
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
errorMessage.Message = `❌ **@${agentName}** failed\n\n${result?.agentRun?.ErrorMessage || 'Unknown error'}`;
|
|
1316
|
-
errorMessage.ParentID = userMessage.ID;
|
|
1317
|
-
errorMessage.Status = 'Error';
|
|
1318
|
-
errorMessage.Error = result?.agentRun?.ErrorMessage || null;
|
|
1319
|
-
errorMessage.HiddenToUser = false;
|
|
1320
|
-
await errorMessage.Save();
|
|
1321
|
-
this.messageSent.emit(errorMessage);
|
|
1322
|
-
userMessage.Status = 'Complete';
|
|
1323
|
-
await userMessage.Save();
|
|
1324
|
-
this.messageSent.emit(userMessage);
|
|
1293
|
+
// Agent failed - update the existing message instead of creating a new one
|
|
1294
|
+
agentResponseMessage.Error = result?.agentRun?.ErrorMessage || null;
|
|
1295
|
+
await this.updateConversationDetail(agentResponseMessage, `❌ **@${agentName}** failed\n\n${result?.agentRun?.ErrorMessage || 'Unknown error'}`, 'Error');
|
|
1296
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
1325
1297
|
}
|
|
1326
1298
|
}
|
|
1327
1299
|
catch (error) {
|
|
1328
1300
|
console.error(`❌ Error invoking mentioned agent ${agentName}:`, error);
|
|
1329
|
-
this.activeTasks.remove(taskId);
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
errorMessage.Error = String(error);
|
|
1337
|
-
errorMessage.HiddenToUser = false;
|
|
1338
|
-
await errorMessage.Save();
|
|
1339
|
-
this.messageSent.emit(errorMessage);
|
|
1340
|
-
userMessage.Status = 'Complete';
|
|
1341
|
-
await userMessage.Save();
|
|
1342
|
-
this.messageSent.emit(userMessage);
|
|
1301
|
+
// Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
|
|
1302
|
+
// Update the existing agent response message if it was created
|
|
1303
|
+
if (agentResponseMessage) {
|
|
1304
|
+
agentResponseMessage.Error = String(error);
|
|
1305
|
+
await this.updateConversationDetail(agentResponseMessage, `❌ **@${agentName}** encountered an error\n\n${String(error)}`, 'Error');
|
|
1306
|
+
}
|
|
1307
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
1343
1308
|
}
|
|
1344
1309
|
}
|
|
1345
1310
|
/**
|
|
1346
1311
|
* Continue with the same agent from previous message (implicit continuation)
|
|
1347
1312
|
* Bypasses Sage - no status messages
|
|
1313
|
+
*
|
|
1314
|
+
* @param targetArtifactVersionId Optional specific artifact version to use as payload (from intent check)
|
|
1348
1315
|
*/
|
|
1349
|
-
async continueWithAgent(userMessage, agentId, conversationId) {
|
|
1316
|
+
async continueWithAgent(userMessage, agentId, conversationId, targetArtifactVersionId) {
|
|
1350
1317
|
// Load the agent entity to get its name
|
|
1351
|
-
const
|
|
1352
|
-
|
|
1353
|
-
EntityName: 'AI Agents',
|
|
1354
|
-
ExtraFilter: `ID='${agentId}'`,
|
|
1355
|
-
ResultType: 'entity_object',
|
|
1356
|
-
}, this.currentUser);
|
|
1357
|
-
if (!agentResult.Success || !agentResult.Results || agentResult.Results.length === 0) {
|
|
1318
|
+
const agent = AIEngineBase.Instance.Agents.find(a => a.ID === agentId);
|
|
1319
|
+
if (!agent) {
|
|
1358
1320
|
console.warn('⚠️ Could not load agent for continuation - falling back to Sage');
|
|
1359
1321
|
await this.processMessageThroughAgent(userMessage, { mentions: [], agentMention: null, userMentions: [] });
|
|
1360
1322
|
return;
|
|
1361
1323
|
}
|
|
1362
|
-
const agent = agentResult.Results[0];
|
|
1363
1324
|
const agentName = agent.Name || 'Agent';
|
|
1364
|
-
// Find the last AI message from this same agent to get the previous OUTPUT artifact
|
|
1365
|
-
const lastAIMessage = this.conversationHistory
|
|
1366
|
-
.slice()
|
|
1367
|
-
.reverse()
|
|
1368
|
-
.find((msg) => msg.Role === 'AI' && msg.AgentID === agentId);
|
|
1369
1325
|
let previousPayload = null;
|
|
1370
1326
|
let previousArtifactInfo = null;
|
|
1371
|
-
if (
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
EntityName: 'MJ: Artifact Versions',
|
|
1383
|
-
ExtraFilter: `ID='${junctionRecord.ArtifactVersionID}'`,
|
|
1384
|
-
ResultType: 'entity_object',
|
|
1385
|
-
}, this.currentUser);
|
|
1386
|
-
if (versionResult.Success && versionResult.Results && versionResult.Results.length > 0) {
|
|
1387
|
-
const version = versionResult.Results[0];
|
|
1388
|
-
if (version.Content) {
|
|
1389
|
-
try {
|
|
1327
|
+
// Use targetArtifactVersionId if specified (from intent check)
|
|
1328
|
+
if (targetArtifactVersionId && this.artifactsByDetailId) {
|
|
1329
|
+
console.log('🎯 Using target artifact version from intent check:', targetArtifactVersionId);
|
|
1330
|
+
// Find the artifact in pre-loaded data (O(n) search across all messages)
|
|
1331
|
+
for (const [detailId, artifacts] of this.artifactsByDetailId.entries()) {
|
|
1332
|
+
const targetArtifact = artifacts.find(a => a.artifactVersionId === targetArtifactVersionId);
|
|
1333
|
+
if (targetArtifact) {
|
|
1334
|
+
try {
|
|
1335
|
+
// Lazy load the full version entity to get Content
|
|
1336
|
+
const version = await targetArtifact.getVersion();
|
|
1337
|
+
if (version.Content) {
|
|
1390
1338
|
previousPayload = JSON.parse(version.Content);
|
|
1391
1339
|
previousArtifactInfo = {
|
|
1392
|
-
artifactId:
|
|
1393
|
-
versionId:
|
|
1394
|
-
versionNumber:
|
|
1340
|
+
artifactId: targetArtifact.artifactId,
|
|
1341
|
+
versionId: targetArtifact.artifactVersionId,
|
|
1342
|
+
versionNumber: targetArtifact.versionNumber
|
|
1395
1343
|
};
|
|
1396
|
-
console.log('📦 Loaded
|
|
1344
|
+
console.log('📦 Loaded target artifact version as payload', previousArtifactInfo);
|
|
1397
1345
|
}
|
|
1398
|
-
|
|
1399
|
-
|
|
1346
|
+
}
|
|
1347
|
+
catch (error) {
|
|
1348
|
+
console.warn('⚠️ Could not load target artifact version:', error);
|
|
1349
|
+
}
|
|
1350
|
+
break;
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
// Fall back to most recent artifact if no target specified or target not found
|
|
1355
|
+
if (!previousPayload) {
|
|
1356
|
+
console.log('📦 Using most recent artifact from last agent message');
|
|
1357
|
+
// Find the last AI message from this same agent
|
|
1358
|
+
const lastAIMessage = this.conversationHistory
|
|
1359
|
+
.slice()
|
|
1360
|
+
.reverse()
|
|
1361
|
+
.find(msg => msg.Role === 'AI' && msg.AgentID === agentId);
|
|
1362
|
+
if (lastAIMessage && this.artifactsByDetailId) {
|
|
1363
|
+
// Get artifacts from pre-loaded data (no DB query!)
|
|
1364
|
+
const artifacts = this.artifactsByDetailId.get(lastAIMessage.ID);
|
|
1365
|
+
if (artifacts && artifacts.length > 0) {
|
|
1366
|
+
try {
|
|
1367
|
+
// Use the first artifact (should only be one OUTPUT per message)
|
|
1368
|
+
const artifact = artifacts[0];
|
|
1369
|
+
const version = await artifact.getVersion();
|
|
1370
|
+
if (version.Content) {
|
|
1371
|
+
previousPayload = JSON.parse(version.Content);
|
|
1372
|
+
previousArtifactInfo = {
|
|
1373
|
+
artifactId: artifact.artifactId,
|
|
1374
|
+
versionId: artifact.artifactVersionId,
|
|
1375
|
+
versionNumber: artifact.versionNumber
|
|
1376
|
+
};
|
|
1377
|
+
console.log('📦 Loaded most recent artifact as payload', previousArtifactInfo);
|
|
1400
1378
|
}
|
|
1401
1379
|
}
|
|
1380
|
+
catch (error) {
|
|
1381
|
+
console.warn('⚠️ Could not parse artifact content:', error);
|
|
1382
|
+
}
|
|
1402
1383
|
}
|
|
1403
1384
|
}
|
|
1404
1385
|
}
|
|
@@ -1408,14 +1389,18 @@ export class MessageInputComponent {
|
|
|
1408
1389
|
status: 'Processing...',
|
|
1409
1390
|
relatedMessageId: userMessage.ID,
|
|
1410
1391
|
conversationDetailId: userMessage.ID,
|
|
1392
|
+
conversationId: this.conversationId,
|
|
1393
|
+
conversationName: this.conversationName
|
|
1411
1394
|
});
|
|
1395
|
+
// Declare agentResponseMessage outside try block so it's accessible in catch
|
|
1396
|
+
let agentResponseMessage = undefined;
|
|
1412
1397
|
try {
|
|
1413
1398
|
// Update user message status to In-Progress
|
|
1414
1399
|
userMessage.Status = 'In-Progress';
|
|
1415
1400
|
await userMessage.Save();
|
|
1416
1401
|
this.messageSent.emit(userMessage);
|
|
1417
1402
|
// Create AI response message BEFORE invoking agent (for duration tracking)
|
|
1418
|
-
|
|
1403
|
+
agentResponseMessage = await this.dataCache.createConversationDetail(this.currentUser);
|
|
1419
1404
|
agentResponseMessage.ConversationID = conversationId;
|
|
1420
1405
|
agentResponseMessage.Role = 'AI';
|
|
1421
1406
|
agentResponseMessage.Message = '⏳ Starting...'; // Initial message
|
|
@@ -1430,10 +1415,10 @@ export class MessageInputComponent {
|
|
|
1430
1415
|
const result = await this.agentService.invokeSubAgent(agentName, conversationId, userMessage, this.conversationHistory, 'Continuing previous conversation with user', agentResponseMessage.ID, previousPayload, // Pass previous OUTPUT artifact payload for continuity
|
|
1431
1416
|
this.createProgressCallback(agentResponseMessage, agentName), previousArtifactInfo?.artifactId, previousArtifactInfo?.versionId);
|
|
1432
1417
|
// Remove from active tasks
|
|
1433
|
-
this.activeTasks.remove(taskId);
|
|
1418
|
+
// Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
|
|
1434
1419
|
if (result && result.success) {
|
|
1435
1420
|
// Update the response message with agent result
|
|
1436
|
-
await this.updateConversationDetail(agentResponseMessage, result.agentRun?.Message || `✅ **${agentName}** completed`, 'Complete');
|
|
1421
|
+
await this.updateConversationDetail(agentResponseMessage, result.agentRun?.Message || `✅ **${agentName}** completed`, 'Complete', result.suggestedResponses);
|
|
1437
1422
|
// Server created artifacts (handles versioning) - emit event to trigger UI reload
|
|
1438
1423
|
if (result.payload && Object.keys(result.payload).length > 0) {
|
|
1439
1424
|
this.artifactCreated.emit({
|
|
@@ -1441,48 +1426,29 @@ export class MessageInputComponent {
|
|
|
1441
1426
|
versionId: '',
|
|
1442
1427
|
versionNumber: 0,
|
|
1443
1428
|
conversationDetailId: agentResponseMessage.ID,
|
|
1444
|
-
name: ''
|
|
1429
|
+
name: ''
|
|
1445
1430
|
});
|
|
1446
1431
|
this.messageSent.emit(agentResponseMessage);
|
|
1447
1432
|
}
|
|
1448
1433
|
// Mark user message as complete
|
|
1449
|
-
userMessage.
|
|
1450
|
-
await userMessage.Save();
|
|
1451
|
-
this.messageSent.emit(userMessage);
|
|
1434
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
1452
1435
|
}
|
|
1453
1436
|
else {
|
|
1454
|
-
// Agent failed -
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
errorMessage.Message = `❌ **${agentName}** failed\n\n${result?.agentRun?.ErrorMessage || 'Unknown error'}`;
|
|
1459
|
-
errorMessage.ParentID = userMessage.ID;
|
|
1460
|
-
errorMessage.Status = 'Error';
|
|
1461
|
-
errorMessage.Error = result?.agentRun?.ErrorMessage || null;
|
|
1462
|
-
errorMessage.HiddenToUser = false;
|
|
1463
|
-
await errorMessage.Save();
|
|
1464
|
-
this.messageSent.emit(errorMessage);
|
|
1465
|
-
userMessage.Status = 'Complete';
|
|
1466
|
-
await userMessage.Save();
|
|
1467
|
-
this.messageSent.emit(userMessage);
|
|
1437
|
+
// Agent failed - update the existing message instead of creating a new one
|
|
1438
|
+
agentResponseMessage.Error = result?.agentRun?.ErrorMessage || null;
|
|
1439
|
+
await this.updateConversationDetail(agentResponseMessage, `❌ **${agentName}** failed\n\n${result?.agentRun?.ErrorMessage || 'Unknown error'}`, 'Error');
|
|
1440
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
1468
1441
|
}
|
|
1469
1442
|
}
|
|
1470
1443
|
catch (error) {
|
|
1471
1444
|
console.error(`❌ Error continuing with agent ${agentName}:`, error);
|
|
1472
|
-
this.activeTasks.remove(taskId);
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
errorMessage.Error = String(error);
|
|
1480
|
-
errorMessage.HiddenToUser = false;
|
|
1481
|
-
await errorMessage.Save();
|
|
1482
|
-
this.messageSent.emit(errorMessage);
|
|
1483
|
-
userMessage.Status = 'Complete';
|
|
1484
|
-
await userMessage.Save();
|
|
1485
|
-
this.messageSent.emit(userMessage);
|
|
1445
|
+
// Task removed in markMessageComplete() - this.activeTasks.remove(taskId);
|
|
1446
|
+
// Update the existing agent response message if it was created
|
|
1447
|
+
if (agentResponseMessage) {
|
|
1448
|
+
agentResponseMessage.Error = String(error);
|
|
1449
|
+
await this.updateConversationDetail(agentResponseMessage, `❌ **${agentName}** encountered an error\n\n${String(error)}`, 'Error');
|
|
1450
|
+
}
|
|
1451
|
+
await this.updateConversationDetail(userMessage, userMessage.Message, 'Complete');
|
|
1486
1452
|
}
|
|
1487
1453
|
}
|
|
1488
1454
|
/**
|
|
@@ -1493,7 +1459,7 @@ export class MessageInputComponent {
|
|
|
1493
1459
|
console.log('🏷️ Naming conversation based on first message...');
|
|
1494
1460
|
// Load the Name Conversation prompt to get its ID
|
|
1495
1461
|
await AIEngineBase.Instance.Config(false);
|
|
1496
|
-
const p = AIEngineBase.Instance.Prompts.find(
|
|
1462
|
+
const p = AIEngineBase.Instance.Prompts.find(pr => pr.Name === 'Name Conversation');
|
|
1497
1463
|
if (!p) {
|
|
1498
1464
|
console.warn('⚠️ Name Conversation prompt not found');
|
|
1499
1465
|
return;
|
|
@@ -1512,7 +1478,8 @@ export class MessageInputComponent {
|
|
|
1512
1478
|
});
|
|
1513
1479
|
if (result && result.success && (result.parsedResult || result.output)) {
|
|
1514
1480
|
// Use parsedResult if available, otherwise parse output
|
|
1515
|
-
const parsed = result.parsedResult ||
|
|
1481
|
+
const parsed = result.parsedResult ||
|
|
1482
|
+
(result.output ? JSON.parse(result.output) : null);
|
|
1516
1483
|
if (parsed) {
|
|
1517
1484
|
const { name, description } = parsed;
|
|
1518
1485
|
if (name) {
|
|
@@ -1524,7 +1491,7 @@ export class MessageInputComponent {
|
|
|
1524
1491
|
this.conversationRenamed.emit({
|
|
1525
1492
|
conversationId: this.conversationId,
|
|
1526
1493
|
name: name,
|
|
1527
|
-
description: description || ''
|
|
1494
|
+
description: description || ''
|
|
1528
1495
|
});
|
|
1529
1496
|
}
|
|
1530
1497
|
}
|
|
@@ -1545,10 +1512,26 @@ export class MessageInputComponent {
|
|
|
1545
1512
|
markMessageComplete(conversationDetail) {
|
|
1546
1513
|
const now = Date.now();
|
|
1547
1514
|
this.completionTimestamps.set(conversationDetail.ID, now);
|
|
1515
|
+
// Remove task from active tasks if it exists
|
|
1516
|
+
const task = this.activeTasks.getByConversationDetailId(conversationDetail.ID);
|
|
1517
|
+
if (task) {
|
|
1518
|
+
console.log(`✅ Task found for message ${conversationDetail.ID} - removing from active tasks:`, {
|
|
1519
|
+
taskId: task.id,
|
|
1520
|
+
agentName: task.agentName,
|
|
1521
|
+
conversationId: task.conversationId,
|
|
1522
|
+
conversationName: task.conversationName
|
|
1523
|
+
});
|
|
1524
|
+
this.activeTasks.remove(task.id);
|
|
1525
|
+
// Show completion notification
|
|
1526
|
+
MJNotificationService.Instance?.CreateSimpleNotification(`${task.agentName} completed in ${task.conversationName || 'conversation'}`, 'success', 3000);
|
|
1527
|
+
}
|
|
1528
|
+
else {
|
|
1529
|
+
console.warn(`⚠️ No task found for completed message ${conversationDetail.ID} - task may have been removed prematurely or not added`);
|
|
1530
|
+
}
|
|
1548
1531
|
// Emit completion event to parent so it can refresh agent run data
|
|
1549
1532
|
this.messageComplete.emit({
|
|
1550
1533
|
conversationDetailId: conversationDetail.ID,
|
|
1551
|
-
agentRunId: conversationDetail.AgentRunID
|
|
1534
|
+
agentRunId: conversationDetail.AgentRunID
|
|
1552
1535
|
});
|
|
1553
1536
|
}
|
|
1554
1537
|
/**
|
|
@@ -1566,7 +1549,7 @@ export class MessageInputComponent {
|
|
|
1566
1549
|
} if (rf & 2) {
|
|
1567
1550
|
let _t;
|
|
1568
1551
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.inputBox = _t.first);
|
|
1569
|
-
} }, inputs: { conversationId: "conversationId", currentUser: "currentUser", disabled: "disabled", placeholder: "placeholder", parentMessageId: "parentMessageId", conversationHistory: "conversationHistory", initialMessage: "initialMessage" }, outputs: { messageSent: "messageSent", agentResponse: "agentResponse", agentRunDetected: "agentRunDetected", agentRunUpdate: "agentRunUpdate", messageComplete: "messageComplete", artifactCreated: "artifactCreated", conversationRenamed: "conversationRenamed", intentCheckStarted: "intentCheckStarted", intentCheckCompleted: "intentCheckCompleted" }, features: [i0.ɵɵNgOnChangesFeature], decls: 4, vars: 8, consts: [["inputBox", ""], [1, "message-input-wrapper"], ["class", "processing-indicator", 4, "ngIf"], [3, "valueChange", "textSubmitted", "placeholder", "disabled", "showCharacterCount", "enableMentions", "currentUser", "rows", "value"], [1, "processing-indicator"], [1, "fas", "fa-circle-notch", "fa-spin"]], template: function MessageInputComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1552
|
+
} }, inputs: { conversationId: "conversationId", conversationName: "conversationName", currentUser: "currentUser", disabled: "disabled", placeholder: "placeholder", parentMessageId: "parentMessageId", conversationHistory: "conversationHistory", initialMessage: "initialMessage", artifactsByDetailId: "artifactsByDetailId", agentRunsByDetailId: "agentRunsByDetailId", inProgressMessageIds: "inProgressMessageIds" }, outputs: { messageSent: "messageSent", agentResponse: "agentResponse", agentRunDetected: "agentRunDetected", agentRunUpdate: "agentRunUpdate", messageComplete: "messageComplete", artifactCreated: "artifactCreated", conversationRenamed: "conversationRenamed", intentCheckStarted: "intentCheckStarted", intentCheckCompleted: "intentCheckCompleted" }, features: [i0.ɵɵNgOnChangesFeature], decls: 4, vars: 8, consts: [["inputBox", ""], [1, "message-input-wrapper"], ["class", "processing-indicator", 4, "ngIf"], [3, "valueChange", "textSubmitted", "placeholder", "disabled", "showCharacterCount", "enableMentions", "currentUser", "rows", "value"], [1, "processing-indicator"], [1, "fas", "fa-circle-notch", "fa-spin"]], template: function MessageInputComponent_Template(rf, ctx) { if (rf & 1) {
|
|
1570
1553
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
1571
1554
|
i0.ɵɵelementStart(0, "div", 1);
|
|
1572
1555
|
i0.ɵɵtemplate(1, MessageInputComponent_div_1_Template, 4, 1, "div", 2);
|
|
@@ -1587,6 +1570,8 @@ export class MessageInputComponent {
|
|
|
1587
1570
|
args: [{ selector: 'mj-message-input', template: "<div class=\"message-input-wrapper\">\n <!-- Processing Indicator Overlay -->\n <div class=\"processing-indicator\" *ngIf=\"isProcessing\">\n <i class=\"fas fa-circle-notch fa-spin\"></i>\n <span>{{ processingMessage }}</span>\n </div>\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 [currentUser]=\"currentUser\"\n [rows]=\"3\"\n [(value)]=\"messageText\"\n (textSubmitted)=\"onTextSubmitted($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: rgba(255, 255, 255, 0.95);\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n z-index: 10;\n pointer-events: none;\n\n i {\n color: var(--primary-color, #007bff);\n }\n\n span {\n font-size: 0.9rem;\n color: var(--text-primary, #333);\n }\n}"] }]
|
|
1588
1571
|
}], () => [{ type: i1.DialogService }, { type: i2.ToastService }, { type: i3.ConversationAgentService }, { type: i4.ConversationStateService }, { type: i5.DataCacheService }, { type: i6.ActiveTasksService }, { type: i7.MentionParserService }, { type: i8.MentionAutocompleteService }], { conversationId: [{
|
|
1589
1572
|
type: Input
|
|
1573
|
+
}], conversationName: [{
|
|
1574
|
+
type: Input
|
|
1590
1575
|
}], currentUser: [{
|
|
1591
1576
|
type: Input
|
|
1592
1577
|
}], disabled: [{
|
|
@@ -1599,6 +1584,12 @@ export class MessageInputComponent {
|
|
|
1599
1584
|
type: Input
|
|
1600
1585
|
}], initialMessage: [{
|
|
1601
1586
|
type: Input
|
|
1587
|
+
}], artifactsByDetailId: [{
|
|
1588
|
+
type: Input
|
|
1589
|
+
}], agentRunsByDetailId: [{
|
|
1590
|
+
type: Input
|
|
1591
|
+
}], inProgressMessageIds: [{
|
|
1592
|
+
type: Input
|
|
1602
1593
|
}], messageSent: [{
|
|
1603
1594
|
type: Output
|
|
1604
1595
|
}], agentResponse: [{
|
|
@@ -1621,5 +1612,5 @@ export class MessageInputComponent {
|
|
|
1621
1612
|
type: ViewChild,
|
|
1622
1613
|
args: ['inputBox']
|
|
1623
1614
|
}] }); })();
|
|
1624
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MessageInputComponent, { className: "MessageInputComponent", filePath: "src/lib/components/message/message-input.component.ts", lineNumber:
|
|
1615
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MessageInputComponent, { className: "MessageInputComponent", filePath: "src/lib/components/message/message-input.component.ts", lineNumber: 25 }); })();
|
|
1625
1616
|
//# sourceMappingURL=message-input.component.js.map
|