@memberjunction/ng-conversations 6.2.0-edge.4 → 6.2.0-edge.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/dist/lib/components/attachment/image-viewer.component.d.ts +3 -1
- package/dist/lib/components/attachment/image-viewer.component.d.ts.map +1 -1
- package/dist/lib/components/attachment/image-viewer.component.js +5 -1
- package/dist/lib/components/attachment/image-viewer.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-agent-picker.component.d.ts +1 -1
- package/dist/lib/components/conversation/conversation-agent-picker.component.js +3 -3
- package/dist/lib/components/conversation/conversation-agent-picker.component.js.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +88 -20
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
- package/dist/lib/components/conversation/conversation-chat-area.component.js +785 -387
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.d.ts +60 -20
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-input.component.js +290 -389
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/message/message-item.component.d.ts +153 -17
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-item.component.js +1400 -299
- package/dist/lib/components/message/message-item.component.js.map +1 -1
- package/dist/lib/components/message/message-list.component.d.ts +25 -2
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
- package/dist/lib/components/message/message-list.component.js +79 -40
- package/dist/lib/components/message/message-list.component.js.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.d.ts +19 -0
- package/dist/lib/components/overlay/chat-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/overlay/chat-overlay.component.js +125 -13
- package/dist/lib/components/overlay/chat-overlay.component.js.map +1 -1
- package/dist/lib/components/project/project-form-modal.component.js +2 -2
- package/dist/lib/components/project/project-form-modal.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +6 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-banner.component.js +110 -82
- package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-call-failure-notice.d.ts +13 -0
- package/dist/lib/components/realtime/realtime-call-failure-notice.d.ts.map +1 -0
- package/dist/lib/components/realtime/realtime-call-failure-notice.js +21 -0
- package/dist/lib/components/realtime/realtime-call-failure-notice.js.map +1 -0
- package/dist/lib/components/realtime/realtime-composer.component.js +114 -102
- package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +21 -2
- package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-overlay.component.js +113 -76
- package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +7 -1
- package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
- package/dist/lib/components/sidebar/routines-section.component.js +1 -1
- package/dist/lib/components/sidebar/routines-section.component.js.map +1 -1
- package/dist/lib/components/task/tasks-full-view.component.d.ts +152 -31
- package/dist/lib/components/task/tasks-full-view.component.d.ts.map +1 -1
- package/dist/lib/components/task/tasks-full-view.component.js +2227 -214
- package/dist/lib/components/task/tasks-full-view.component.js.map +1 -1
- package/dist/lib/components/tasks/tasks-dropdown.component.js +4 -4
- package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +11 -1
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
- package/dist/lib/components/workspace/conversation-workspace.component.js +25 -28
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
- package/dist/lib/services/agent-state.service.d.ts.map +1 -1
- package/dist/lib/services/agent-state.service.js +8 -8
- package/dist/lib/services/agent-state.service.js.map +1 -1
- package/dist/lib/services/browser-realtime-media-host.d.ts +7 -7
- package/dist/lib/services/browser-realtime-media-host.js +8 -78
- package/dist/lib/services/browser-realtime-media-host.js.map +1 -1
- package/dist/lib/services/conversation-agent.service.d.ts +53 -20
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
- package/dist/lib/services/conversation-agent.service.js +108 -54
- package/dist/lib/services/conversation-agent.service.js.map +1 -1
- package/dist/lib/services/conversation-detail-window.store.d.ts +5 -0
- package/dist/lib/services/conversation-detail-window.store.d.ts.map +1 -1
- package/dist/lib/services/conversation-detail-window.store.js +52 -5
- package/dist/lib/services/conversation-detail-window.store.js.map +1 -1
- package/dist/lib/services/conversation-naming.d.ts.map +1 -1
- package/dist/lib/services/conversation-naming.js +9 -2
- package/dist/lib/services/conversation-naming.js.map +1 -1
- package/dist/lib/services/conversation-tasks-filter.d.ts +15 -0
- package/dist/lib/services/conversation-tasks-filter.d.ts.map +1 -0
- package/dist/lib/services/conversation-tasks-filter.js +69 -0
- package/dist/lib/services/conversation-tasks-filter.js.map +1 -0
- package/dist/lib/services/realtime-audio-recorder.d.ts +94 -86
- package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -1
- package/dist/lib/services/realtime-audio-recorder.js +222 -195
- package/dist/lib/services/realtime-audio-recorder.js.map +1 -1
- package/dist/lib/services/realtime-session.service.d.ts +30 -2
- package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session.service.js +35 -7
- package/dist/lib/services/realtime-session.service.js.map +1 -1
- package/dist/lib/services/recording/libopus-wasm-binary.d.ts +3 -0
- package/dist/lib/services/recording/libopus-wasm-binary.d.ts.map +1 -0
- package/dist/lib/services/recording/libopus-wasm-binary.js +489 -0
- package/dist/lib/services/recording/libopus-wasm-binary.js.map +1 -0
- package/dist/lib/services/recording/libopus-worker-source.d.ts +48 -0
- package/dist/lib/services/recording/libopus-worker-source.d.ts.map +1 -0
- package/dist/lib/services/recording/libopus-worker-source.js +170 -0
- package/dist/lib/services/recording/libopus-worker-source.js.map +1 -0
- package/dist/lib/services/recording/linear-resampler.d.ts +45 -0
- package/dist/lib/services/recording/linear-resampler.d.ts.map +1 -0
- package/dist/lib/services/recording/linear-resampler.js +85 -0
- package/dist/lib/services/recording/linear-resampler.js.map +1 -0
- package/dist/lib/services/recording/opus-packet-encoder.d.ts +50 -0
- package/dist/lib/services/recording/opus-packet-encoder.d.ts.map +1 -0
- package/dist/lib/services/recording/opus-packet-encoder.js +41 -0
- package/dist/lib/services/recording/opus-packet-encoder.js.map +1 -0
- package/dist/lib/services/recording/wasm-opus-encoder.d.ts +86 -0
- package/dist/lib/services/recording/wasm-opus-encoder.d.ts.map +1 -0
- package/dist/lib/services/recording/wasm-opus-encoder.js +232 -0
- package/dist/lib/services/recording/wasm-opus-encoder.js.map +1 -0
- package/dist/lib/services/recording/webcodecs-opus-encoder.d.ts +39 -0
- package/dist/lib/services/recording/webcodecs-opus-encoder.d.ts.map +1 -0
- package/dist/lib/services/recording/webcodecs-opus-encoder.js +101 -0
- package/dist/lib/services/recording/webcodecs-opus-encoder.js.map +1 -0
- package/dist/lib/services/search.service.d.ts.map +1 -1
- package/dist/lib/services/search.service.js +3 -16
- package/dist/lib/services/search.service.js.map +1 -1
- package/dist/lib/utils/agent-failure-display.d.ts +14 -0
- package/dist/lib/utils/agent-failure-display.d.ts.map +1 -0
- package/dist/lib/utils/agent-failure-display.js +26 -0
- package/dist/lib/utils/agent-failure-display.js.map +1 -0
- package/dist/lib/utils/distinct-artifacts.d.ts +9 -3
- package/dist/lib/utils/distinct-artifacts.d.ts.map +1 -1
- package/dist/lib/utils/distinct-artifacts.js +24 -5
- package/dist/lib/utils/distinct-artifacts.js.map +1 -1
- package/dist/lib/utils/message-list-order.d.ts +13 -0
- package/dist/lib/utils/message-list-order.d.ts.map +1 -0
- package/dist/lib/utils/message-list-order.js +31 -0
- package/dist/lib/utils/message-list-order.js.map +1 -0
- package/dist/lib/utils/pin-state.d.ts +11 -0
- package/dist/lib/utils/pin-state.d.ts.map +1 -0
- package/dist/lib/utils/pin-state.js +9 -0
- package/dist/lib/utils/pin-state.js.map +1 -0
- package/dist/public-api.d.ts +1 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +36 -36
- package/dist/lib/services/browser-recording-unload-guard.d.ts +0 -30
- package/dist/lib/services/browser-recording-unload-guard.d.ts.map +0 -1
- package/dist/lib/services/browser-recording-unload-guard.js +0 -43
- package/dist/lib/services/browser-recording-unload-guard.js.map +0 -1
- package/dist/lib/services/realtime-pcm-wav.d.ts +0 -79
- package/dist/lib/services/realtime-pcm-wav.d.ts.map +0 -1
- package/dist/lib/services/realtime-pcm-wav.js +0 -213
- package/dist/lib/services/realtime-pcm-wav.js.map +0 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Injectable } from '@angular/core';
|
|
2
|
-
import { Metadata, RunView } from '@memberjunction/core';
|
|
2
|
+
import { LogStatusEx, Metadata, RunView } from '@memberjunction/core';
|
|
3
3
|
import { GraphQLAIClient } from '@memberjunction/graphql-dataprovider';
|
|
4
4
|
import { coerceFailedExecuteAgentResult } from '@memberjunction/ai-core-plus';
|
|
5
5
|
import { AIEngineBase } from '@memberjunction/ai-engine-base';
|
|
6
6
|
import { ConversationEngine } from '@memberjunction/core-entities';
|
|
7
7
|
import { MJNotificationService } from '@memberjunction/ng-notifications';
|
|
8
8
|
import { ConversationsRuntime } from '@memberjunction/conversations-runtime';
|
|
9
|
-
import { UUIDsEqual } from '@memberjunction/global';
|
|
9
|
+
import { EscapeSQLString, UUIDsEqual } from '@memberjunction/global';
|
|
10
10
|
import { GroupVersionsByArtifact } from '../utils/agent-artifact-summary';
|
|
11
11
|
import * as i0 from "@angular/core";
|
|
12
12
|
import * as i1 from "./conversations-runtime-bootstrap.service";
|
|
@@ -115,6 +115,11 @@ export class ConversationAgentService {
|
|
|
115
115
|
if (this._conversationManagerAgent) {
|
|
116
116
|
return this._conversationManagerAgent;
|
|
117
117
|
}
|
|
118
|
+
// A user who may not read the agents has no manager agent to resolve: say nothing, rather than an error for a state
|
|
119
|
+
// that is theirs by design (MJ#5240)
|
|
120
|
+
if (AIEngineBase.Instance.IsPermissionConstrained && AIEngineBase.Instance.ReadableAgents.length === 0) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
118
123
|
try {
|
|
119
124
|
const provider = this.Provider;
|
|
120
125
|
const agent = await ConversationsRuntime.Instance.DefaultAgent.resolve({
|
|
@@ -158,17 +163,19 @@ export class ConversationAgentService {
|
|
|
158
163
|
* Process a message through the conversation manager agent. Delegates to
|
|
159
164
|
* `ConversationsRuntime.Instance.AgentRunner.processMessage(...)`.
|
|
160
165
|
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
+
* The unused `conversationHistory` parameter is kept for backwards compatibility (it was already
|
|
167
|
+
* documented as "kept for backwards compatibility but not used" in the original).
|
|
168
|
+
*
|
|
169
|
+
* @param onReplyAccepted Called with the reply row the server creates for the turn (only the server
|
|
170
|
+
* writes agent replies), before any progress: key the turn's task and completion by its ID.
|
|
166
171
|
*/
|
|
167
|
-
async ProcessMessage(conversationId, message, conversationHistory,
|
|
172
|
+
async ProcessMessage(conversationId, message, conversationHistory, onReplyAccepted, onProgress, appContext, planMode, requestedSkillIDs,
|
|
168
173
|
/** The agents the conversation manager may delegate to. Null or omitted allows every agent. */
|
|
169
174
|
allowedAgentIDs,
|
|
170
175
|
/** The first moment of the conversation the run may read. Null or omitted reads all of it. */
|
|
171
|
-
agentHistoryFrom
|
|
176
|
+
agentHistoryFrom,
|
|
177
|
+
/** The branch the turn runs on when it forks off an earlier message on another branch. */
|
|
178
|
+
replyBranchId) {
|
|
172
179
|
// Warm the cached default-agent name for any synchronous consumers
|
|
173
180
|
// before the runtime resolves on its own.
|
|
174
181
|
if (!this._conversationManagerAgent) {
|
|
@@ -177,18 +184,19 @@ export class ConversationAgentService {
|
|
|
177
184
|
return ConversationsRuntime.Instance.AgentRunner.processMessage({
|
|
178
185
|
conversationId,
|
|
179
186
|
message,
|
|
180
|
-
|
|
187
|
+
onReplyAccepted,
|
|
181
188
|
appContext,
|
|
182
189
|
onProgress,
|
|
183
190
|
...(planMode ? { planMode: true } : {}),
|
|
184
191
|
...(requestedSkillIDs?.length ? { requestedSkillIDs } : {}),
|
|
185
192
|
...(allowedAgentIDs != null ? { AllowedAgentIDs: allowedAgentIDs } : {}),
|
|
186
193
|
...(agentHistoryFrom ? { AgentHistoryFrom: agentHistoryFrom } : {}),
|
|
194
|
+
...(replyBranchId ? { ReplyBranchID: replyBranchId } : {}),
|
|
187
195
|
});
|
|
188
196
|
}
|
|
189
197
|
/** @deprecated Use {@link ProcessMessage}. */
|
|
190
|
-
async processMessage(conversationId, message, conversationHistory,
|
|
191
|
-
return this.ProcessMessage(conversationId, message, conversationHistory,
|
|
198
|
+
async processMessage(conversationId, message, conversationHistory, onReplyAccepted, onProgress, appContext, planMode, requestedSkillIDs, allowedAgentIDs, agentHistoryFrom, replyBranchId) {
|
|
199
|
+
return this.ProcessMessage(conversationId, message, conversationHistory, onReplyAccepted, onProgress, appContext, planMode, requestedSkillIDs, allowedAgentIDs, agentHistoryFrom, replyBranchId);
|
|
192
200
|
}
|
|
193
201
|
/**
|
|
194
202
|
* Configuration preset an agent was pinned to by a previous `@mention` in this conversation.
|
|
@@ -232,7 +240,7 @@ export class ConversationAgentService {
|
|
|
232
240
|
for (const row of result.Results || []) {
|
|
233
241
|
const configurationId = this.readAgentConfigFromMention(row.Message, agentId);
|
|
234
242
|
if (configurationId) {
|
|
235
|
-
|
|
243
|
+
LogStatusEx({ message: `\u{1F3AF} Found configuration preset from @mention: ${configurationId}`, verboseOnly: true });
|
|
236
244
|
return configurationId;
|
|
237
245
|
}
|
|
238
246
|
}
|
|
@@ -243,7 +251,7 @@ export class ConversationAgentService {
|
|
|
243
251
|
if (!message) {
|
|
244
252
|
return null;
|
|
245
253
|
}
|
|
246
|
-
const parsed = this.mentionParser.parseMentions(message, AIEngineBase.Instance.
|
|
254
|
+
const parsed = this.mentionParser.parseMentions(message, AIEngineBase.Instance.ReadableAgents, []);
|
|
247
255
|
const mention = parsed.agentMention;
|
|
248
256
|
return mention?.id === agentId && mention.configurationId ? mention.configurationId : null;
|
|
249
257
|
}
|
|
@@ -280,15 +288,20 @@ export class ConversationAgentService {
|
|
|
280
288
|
*
|
|
281
289
|
* Stays on the Angular shim because it directly uses AgentClientService.
|
|
282
290
|
* Could move to the runtime in a follow-up if needed.
|
|
291
|
+
*
|
|
292
|
+
* @param onReplyAccepted Called with the reply row the server creates for the run (only the server
|
|
293
|
+
* writes agent replies), before any progress: key the run's task and completion by its ID.
|
|
283
294
|
*/
|
|
284
|
-
async InvokeSubAgent(agentName, conversationId, message, conversationHistory, reasoning,
|
|
295
|
+
async InvokeSubAgent(agentName, conversationId, message, conversationHistory, reasoning, onReplyAccepted, payload, onProgress, sourceArtifactId, sourceArtifactVersionId, agentConfigurationPresetId, appContext, planMode, requestedSkillIDs,
|
|
285
296
|
/** The first moment of the conversation the run may read. Null or omitted reads all of it. */
|
|
286
|
-
agentHistoryFrom
|
|
297
|
+
agentHistoryFrom,
|
|
298
|
+
/** Where the reply sits in the conversation. Omitted, it answers `message` directly. */
|
|
299
|
+
threading) {
|
|
287
300
|
try {
|
|
288
301
|
// Ensure AIEngineBase is configured
|
|
289
302
|
await AIEngineBase.Instance.Config(false);
|
|
290
303
|
// Find the agent by name
|
|
291
|
-
const agent = AIEngineBase.Instance.
|
|
304
|
+
const agent = AIEngineBase.Instance.ReadableAgents.find(a => a.Name === agentName);
|
|
292
305
|
if (!agent || !agent.ID) {
|
|
293
306
|
const errorMsg = `Sub-agent "${agentName}" not found`;
|
|
294
307
|
console.warn(`${errorMsg}`);
|
|
@@ -298,7 +311,11 @@ export class ConversationAgentService {
|
|
|
298
311
|
if (requestedSkillIDs?.length) {
|
|
299
312
|
this.warnOnUnacceptedSkills(agent, requestedSkillIDs);
|
|
300
313
|
}
|
|
301
|
-
|
|
314
|
+
LogStatusEx({
|
|
315
|
+
message: `Invoking sub-agent: ${agentName}`,
|
|
316
|
+
verboseOnly: true,
|
|
317
|
+
additionalArgs: [{ reasoning, hasPayload: !!payload, hasConfigPreset: !!agentConfigurationPresetId }]
|
|
318
|
+
});
|
|
302
319
|
// Map AIAgentConfiguration preset ID to actual AIConfiguration ID
|
|
303
320
|
let aiConfigurationId = undefined;
|
|
304
321
|
if (agentConfigurationPresetId) {
|
|
@@ -306,14 +323,18 @@ export class ConversationAgentService {
|
|
|
306
323
|
const preset = presets.find(p => UUIDsEqual(p.ID, agentConfigurationPresetId) || UUIDsEqual(p.AIConfigurationID, agentConfigurationPresetId));
|
|
307
324
|
if (preset) {
|
|
308
325
|
aiConfigurationId = preset.AIConfigurationID || undefined;
|
|
309
|
-
|
|
326
|
+
LogStatusEx({ message: `Mapped agent configuration preset "${preset.Name}" to AIConfigurationID: ${aiConfigurationId || 'default'}`, verboseOnly: true });
|
|
310
327
|
}
|
|
311
328
|
else {
|
|
312
329
|
console.warn(`Agent configuration preset ${agentConfigurationPresetId} not found for agent ${agent.ID}`);
|
|
313
330
|
}
|
|
314
331
|
}
|
|
315
332
|
const agentParams = {
|
|
316
|
-
|
|
333
|
+
UserMessageId: message.ID,
|
|
334
|
+
OnAccepted: onReplyAccepted,
|
|
335
|
+
...(threading?.ReplyParentId ? { ReplyParentId: threading.ReplyParentId } : {}),
|
|
336
|
+
...(threading?.AnnouncedByAgentId ? { AnnouncedByAgentId: threading.AnnouncedByAgentId } : {}),
|
|
337
|
+
...(threading?.ReplyBranchId ? { ReplyBranchId: threading.ReplyBranchId } : {}),
|
|
317
338
|
AgentId: agent.ID,
|
|
318
339
|
MaxHistoryMessages: 20,
|
|
319
340
|
Data: {
|
|
@@ -358,8 +379,8 @@ export class ConversationAgentService {
|
|
|
358
379
|
}
|
|
359
380
|
}
|
|
360
381
|
/** @deprecated Use {@link InvokeSubAgent}. */
|
|
361
|
-
async invokeSubAgent(agentName, conversationId, message, conversationHistory, reasoning,
|
|
362
|
-
return this.InvokeSubAgent(agentName, conversationId, message, conversationHistory, reasoning,
|
|
382
|
+
async invokeSubAgent(agentName, conversationId, message, conversationHistory, reasoning, onReplyAccepted, payload, onProgress, sourceArtifactId, sourceArtifactVersionId, agentConfigurationPresetId, appContext, planMode, requestedSkillIDs, agentHistoryFrom, threading) {
|
|
383
|
+
return this.InvokeSubAgent(agentName, conversationId, message, conversationHistory, reasoning, onReplyAccepted, payload, onProgress, sourceArtifactId, sourceArtifactVersionId, agentConfigurationPresetId, appContext, planMode, requestedSkillIDs, agentHistoryFrom, threading);
|
|
363
384
|
}
|
|
364
385
|
/**
|
|
365
386
|
* Check if user's latest message should continue with the previous agent or route through Sage.
|
|
@@ -383,7 +404,7 @@ export class ConversationAgentService {
|
|
|
383
404
|
console.warn('⚠️ Check Sage Intent prompt not found, defaulting to UNSURE');
|
|
384
405
|
return { decision: 'UNSURE', reasoning: 'Check Sage Intent prompt not found' };
|
|
385
406
|
}
|
|
386
|
-
const agent = AIEngineBase.Instance.
|
|
407
|
+
const agent = AIEngineBase.Instance.ReadableAgents.find(a => UUIDsEqual(a.ID, agentId));
|
|
387
408
|
if (!agent) {
|
|
388
409
|
console.warn('⚠️ Previous agent not found, defaulting to UNSURE');
|
|
389
410
|
return { decision: 'UNSURE', reasoning: 'Previous agent not found' };
|
|
@@ -419,10 +440,14 @@ export class ConversationAgentService {
|
|
|
419
440
|
${compactHistory}${artifactContext}
|
|
420
441
|
|
|
421
442
|
**Latest User Message**: "${latestMessage}"`;
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
443
|
+
LogStatusEx({
|
|
444
|
+
message: '🔍 Checking agent continuity intent...',
|
|
445
|
+
verboseOnly: true,
|
|
446
|
+
additionalArgs: [{
|
|
447
|
+
agentName: agent.Name,
|
|
448
|
+
messagePreview: latestMessage.substring(0, 50),
|
|
449
|
+
artifactCount: agentArtifacts.length
|
|
450
|
+
}]
|
|
426
451
|
});
|
|
427
452
|
const result = await this._aiClient.RunAIPrompt({
|
|
428
453
|
promptId: prompt.ID,
|
|
@@ -439,10 +464,14 @@ ${compactHistory}${artifactContext}
|
|
|
439
464
|
const decision = parsed.continuesWith.toUpperCase();
|
|
440
465
|
const reasoning = parsed.reasoning || 'No reasoning provided';
|
|
441
466
|
const targetArtifactVersionId = parsed.targetArtifactVersionId || undefined;
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
467
|
+
LogStatusEx({
|
|
468
|
+
message: `✅ Intent check result: ${decision}`,
|
|
469
|
+
verboseOnly: true,
|
|
470
|
+
additionalArgs: [{
|
|
471
|
+
reasoning,
|
|
472
|
+
targetArtifactVersionId,
|
|
473
|
+
latency: result.executionTimeMs || 'unknown'
|
|
474
|
+
}]
|
|
446
475
|
});
|
|
447
476
|
if (decision === 'YES' || decision === 'NO' || decision === 'UNSURE') {
|
|
448
477
|
return {
|
|
@@ -510,21 +539,21 @@ ${compactHistory}${artifactContext}
|
|
|
510
539
|
* plausible, and wrong: the same failure class as {@link FindLatestAgentOutputVersion},
|
|
511
540
|
* closed the same way.
|
|
512
541
|
*
|
|
513
|
-
*
|
|
542
|
+
* Three reads: the agent's replies, their Output versions, and the artifacts' names. See
|
|
514
543
|
* {@link AgentArtifactSummary} for why dropping `runId` removes the join back to agent runs.
|
|
515
544
|
*
|
|
516
545
|
* @param historyFrom The chat's history floor, when set (see {@link FindAgentArtifacts}).
|
|
517
546
|
* @param branchId The branch whose path to read; null or omitted reads the trunk.
|
|
518
547
|
*/
|
|
519
548
|
async findAllAgentArtifacts(conversationId, agentId, historyFrom, branchId) {
|
|
520
|
-
const
|
|
521
|
-
if (
|
|
549
|
+
const versionFilter = await this.agentOutputVersionFilter(conversationId, agentId, historyFrom, branchId);
|
|
550
|
+
if (!versionFilter) {
|
|
522
551
|
return []; // the classifier degrades to no artifact context
|
|
523
552
|
}
|
|
524
553
|
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
525
554
|
const versionResult = await rv.RunView({
|
|
526
555
|
EntityName: 'MJ: Artifact Versions',
|
|
527
|
-
ExtraFilter:
|
|
556
|
+
ExtraFilter: versionFilter,
|
|
528
557
|
OrderBy: '__mj_CreatedAt DESC',
|
|
529
558
|
MaxRows: MAX_AGENT_ARTIFACT_VERSIONS,
|
|
530
559
|
Fields: ['ID', 'ArtifactID', 'VersionNumber', 'Name'],
|
|
@@ -566,7 +595,7 @@ ${compactHistory}${artifactContext}
|
|
|
566
595
|
* again" exchanges where payload continuity matters most. A null payload is a LEGAL agent
|
|
567
596
|
* input, so the failure is silent: the agent regenerates from scratch instead of modifying.
|
|
568
597
|
*
|
|
569
|
-
*
|
|
598
|
+
* Two reads: the agent's replies, then their newest Output version. Versions carry
|
|
570
599
|
* `__mj_CreatedAt`, so "newest" is expressible without joining back for `Sequence`.
|
|
571
600
|
*
|
|
572
601
|
* @param historyFrom The chat's history floor. When set, only artifacts on replies written at
|
|
@@ -576,35 +605,60 @@ ${compactHistory}${artifactContext}
|
|
|
576
605
|
* another branch is never the latest here; null or omitted reads the trunk.
|
|
577
606
|
*/
|
|
578
607
|
async FindLatestAgentOutputVersion(conversationId, agentId, historyFrom, branchId) {
|
|
579
|
-
const
|
|
580
|
-
|
|
608
|
+
const versionFilter = await this.agentOutputVersionFilter(conversationId, agentId, historyFrom, branchId);
|
|
609
|
+
return versionFilter ? this.runPayloadSourceQuery(versionFilter, '__mj_CreatedAt DESC') : null;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* `ArtifactVersion.ID IN (...)` for every OUTPUT artifact an agent produced on one
|
|
613
|
+
* conversation path, in messages no rerun replaced, or null when the agent has no such reply
|
|
614
|
+
* there. Shared by {@link FindLatestAgentOutputVersion} and {@link findAllAgentArtifacts} so
|
|
615
|
+
* the two can never disagree about what "this agent's artifacts" means.
|
|
616
|
+
*
|
|
617
|
+
* The replies are read with their own RunView ({@link agentReplyIds}), so the row-level
|
|
618
|
+
* security on conversation messages applies. A subquery over their view would skip it, and the
|
|
619
|
+
* server refuses one for a user whose read of messages is row-filtered.
|
|
620
|
+
*/
|
|
621
|
+
async agentOutputVersionFilter(conversationId, agentId, historyFrom, branchId) {
|
|
622
|
+
const replyIds = await this.agentReplyIds(conversationId, agentId, historyFrom, branchId);
|
|
623
|
+
if (replyIds.length === 0) {
|
|
581
624
|
return null;
|
|
582
625
|
}
|
|
583
|
-
|
|
626
|
+
const inReplies = replyIds.map(id => `'${EscapeSQLString(id)}'`).join(',');
|
|
627
|
+
return `ID IN (
|
|
628
|
+
SELECT ArtifactVersionID FROM [__mj].[vwConversationDetailArtifacts]
|
|
629
|
+
WHERE Direction='Output' AND ConversationDetailID IN (${inReplies})
|
|
630
|
+
)`;
|
|
584
631
|
}
|
|
585
632
|
/**
|
|
586
|
-
*
|
|
587
|
-
*
|
|
588
|
-
* {@link
|
|
589
|
-
* artifacts" means.
|
|
633
|
+
* IDs of the agent's replies on one conversation path, in messages no rerun replaced, written
|
|
634
|
+
* at or after the history floor when one is set. Empty when the path cannot be built
|
|
635
|
+
* ({@link branchPathFilter}) or the read fails.
|
|
590
636
|
*
|
|
591
637
|
* Filters on the DETAIL's `Status <> 'Error'` rather than the agent run's
|
|
592
638
|
* `Status = 'Completed'` (which is what the array scan this replaced used). Doing it on the
|
|
593
639
|
* run would mean joining back to `MJ: AI Agent Runs` purely to restate a condition the
|
|
594
640
|
* detail already carries.
|
|
595
|
-
*
|
|
596
|
-
* @param pathFilter The conversation-and-branch predicate from {@link branchPathFilter}.
|
|
597
641
|
*/
|
|
598
|
-
|
|
642
|
+
async agentReplyIds(conversationId, agentId, historyFrom, branchId) {
|
|
643
|
+
const pathFilter = await this.branchPathFilter(conversationId, branchId);
|
|
644
|
+
if (pathFilter == null) {
|
|
645
|
+
return [];
|
|
646
|
+
}
|
|
599
647
|
const floor = historyFrom ? ` AND ${ConversationEngine.HistoryFromFilter(historyFrom)}` : '';
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
648
|
+
const rv = RunView.FromMetadataProvider(this.Provider);
|
|
649
|
+
const result = await rv.RunView({
|
|
650
|
+
EntityName: 'MJ: Conversation Details',
|
|
651
|
+
ExtraFilter: `${ConversationEngine.LiveRowsFilter(pathFilter)} AND AgentID='${EscapeSQLString(agentId)}'` +
|
|
652
|
+
` AND Role='AI' AND Status <> 'Error'${floor}`,
|
|
653
|
+
Fields: ['ID'],
|
|
654
|
+
ResultType: 'simple',
|
|
655
|
+
IgnoreMaxRows: true
|
|
656
|
+
}, this.Provider.CurrentUser ?? undefined);
|
|
657
|
+
if (!result.Success) {
|
|
658
|
+
console.error('Failed to load agent replies:', result.ErrorMessage);
|
|
659
|
+
return [];
|
|
660
|
+
}
|
|
661
|
+
return (result.Results || []).map(reply => reply.ID);
|
|
608
662
|
}
|
|
609
663
|
/**
|
|
610
664
|
* The SQL predicate for one branch's path in a conversation, from
|