@memberjunction/ng-conversations 6.1.0-edge.6 → 6.1.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/dialogs/input-dialog.component.d.ts.map +1 -1
- package/dist/lib/components/dialogs/input-dialog.component.js +3 -3
- package/dist/lib/components/dialogs/input-dialog.component.js.map +1 -1
- package/dist/lib/components/message/message-input.component.js +4 -4
- package/dist/lib/components/message/message-input.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-activity-rail.component.js +2 -2
- package/dist/lib/components/realtime/realtime-activity-rail.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +16 -1
- package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-agent-picker.component.js +39 -7
- package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts +2 -2
- package/dist/lib/components/realtime/realtime-delegation-card.component.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-delegation-card.component.js +159 -107
- package/dist/lib/components/realtime/realtime-delegation-card.component.js.map +1 -1
- package/dist/lib/components/realtime/realtime-session-state.d.ts +9 -4
- package/dist/lib/components/realtime/realtime-session-state.d.ts.map +1 -1
- package/dist/lib/components/realtime/realtime-session-state.js +95 -19
- package/dist/lib/components/realtime/realtime-session-state.js.map +1 -1
- package/dist/lib/services/delegation-result-parser.d.ts +5 -0
- package/dist/lib/services/delegation-result-parser.d.ts.map +1 -1
- package/dist/lib/services/delegation-result-parser.js +12 -0
- package/dist/lib/services/delegation-result-parser.js.map +1 -1
- package/dist/lib/services/realtime-session-review.service.d.ts +31 -1
- package/dist/lib/services/realtime-session-review.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session-review.service.js +63 -8
- package/dist/lib/services/realtime-session-review.service.js.map +1 -1
- package/dist/lib/services/realtime-session.service.d.ts +15 -8
- package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
- package/dist/lib/services/realtime-session.service.js +62 -14
- package/dist/lib/services/realtime-session.service.js.map +1 -1
- package/package.json +31 -31
|
@@ -6,7 +6,7 @@ import { AIEngineBase } from '@memberjunction/ai-engine-base';
|
|
|
6
6
|
import { MJGlobal } from '@memberjunction/global';
|
|
7
7
|
import { BaseRealtimeClient, LoadAssemblyAIRealtimeClient, LoadElevenLabsRealtimeClient, LoadGeminiRealtimeClient, LoadHuggingFaceRealtimeClient, LoadOpenAIRealtimeClient, LoadxAIRealtimeClient } from '@memberjunction/ai-realtime-client';
|
|
8
8
|
import { BuildNarrationInstructions } from './narration-template';
|
|
9
|
-
import { ParseDelegationResultJson } from './delegation-result-parser';
|
|
9
|
+
import { ParseDelegationResultJson, FormatToolName } from './delegation-result-parser';
|
|
10
10
|
import { BaseRealtimeChannelClient } from '../components/realtime/channels/base-realtime-channel-client';
|
|
11
11
|
import { RealtimeAudioRecorder } from './realtime-audio-recorder';
|
|
12
12
|
import * as i0 from "@angular/core";
|
|
@@ -181,6 +181,10 @@ export class RealtimeSessionService {
|
|
|
181
181
|
sessionConversationId = null;
|
|
182
182
|
/** First final user utterance of the live session (the naming seed). */
|
|
183
183
|
firstUserTranscript = null;
|
|
184
|
+
/** Buffer accumulating streaming user interim deltas into a single in-progress bubble. */
|
|
185
|
+
pendingUserCaption = '';
|
|
186
|
+
/** Whether an in-place interim user caption is currently placed in `_captions$`. */
|
|
187
|
+
hasActiveInterimUserCaption = false;
|
|
184
188
|
/**
|
|
185
189
|
* When the active/last session CREATED its conversation (started without one), the new
|
|
186
190
|
* conversation's id — the host uses it to refresh the cached list, conditionally select
|
|
@@ -1299,7 +1303,7 @@ export class RealtimeSessionService {
|
|
|
1299
1303
|
void this.handleToolCall(call);
|
|
1300
1304
|
});
|
|
1301
1305
|
client.OnError((error) => {
|
|
1302
|
-
console.error('[RealtimeSession] Provider error event:', error);
|
|
1306
|
+
console.error('[RealtimeSession] Provider error event:', JSON.stringify(error), error);
|
|
1303
1307
|
});
|
|
1304
1308
|
// Usage telemetry: accumulate the driver's per-response token DELTAS and relay them to
|
|
1305
1309
|
// the server (onto the co-agent AIPromptRun) debounced + once at teardown. Providers
|
|
@@ -1367,9 +1371,25 @@ export class RealtimeSessionService {
|
|
|
1367
1371
|
// silence gap is timed where its audio really is — not inherited from the prior
|
|
1368
1372
|
// turn's end. Narration interims are ephemeral and excluded (Kind guard inside).
|
|
1369
1373
|
this.markTurnAudioStart(transcript.Kind);
|
|
1374
|
+
if (transcript.Role === 'User') {
|
|
1375
|
+
if (!this.hasActiveInterimUserCaption) {
|
|
1376
|
+
if (transcript.Text.trim().length === 0) {
|
|
1377
|
+
return;
|
|
1378
|
+
}
|
|
1379
|
+
this.hasActiveInterimUserCaption = true;
|
|
1380
|
+
this.pendingUserCaption = transcript.Text;
|
|
1381
|
+
this.appendCaption({ Role: 'User', Text: this.pendingUserCaption });
|
|
1382
|
+
}
|
|
1383
|
+
else {
|
|
1384
|
+
this.pendingUserCaption += transcript.Text;
|
|
1385
|
+
this.replaceLastCaption('User', this.pendingUserCaption);
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1370
1388
|
return;
|
|
1371
1389
|
}
|
|
1372
1390
|
if (transcript.Role === 'Assistant') {
|
|
1391
|
+
this.hasActiveInterimUserCaption = false;
|
|
1392
|
+
this.pendingUserCaption = '';
|
|
1373
1393
|
if (transcript.Kind === 'narration') {
|
|
1374
1394
|
this._delegationNarration$.next({ Text: transcript.Text });
|
|
1375
1395
|
// Remember what was actually SAID so later updates build on it instead of repeating.
|
|
@@ -1390,11 +1410,26 @@ export class RealtimeSessionService {
|
|
|
1390
1410
|
await this.relayTranscript('assistant', transcript.Text);
|
|
1391
1411
|
}
|
|
1392
1412
|
}
|
|
1413
|
+
else if (this.hasActiveInterimUserCaption) {
|
|
1414
|
+
this.hasActiveInterimUserCaption = false;
|
|
1415
|
+
this.pendingUserCaption = '';
|
|
1416
|
+
if (transcript.Text.trim().length === 0) {
|
|
1417
|
+
return;
|
|
1418
|
+
}
|
|
1419
|
+
this.replaceLastCaption('User', transcript.Text);
|
|
1420
|
+
if (this.firstUserTranscript === null) {
|
|
1421
|
+
this.firstUserTranscript = transcript.Text;
|
|
1422
|
+
}
|
|
1423
|
+
await this.relayTranscript('user', transcript.Text);
|
|
1424
|
+
}
|
|
1393
1425
|
else if (transcript.ReplacesPrevious) {
|
|
1394
|
-
// STREAMING user transcription: providers like Grok emit the growing utterance as repeated
|
|
1426
|
+
// STREAMING user transcription: providers like Grok and OpenAI Live emit the growing utterance as repeated
|
|
1395
1427
|
// events (each the full text so far), flagging all but the first ReplacesPrevious. Update the
|
|
1396
1428
|
// in-place User caption + persisted turn instead of stacking a new bubble per increment — the
|
|
1397
|
-
// same correction semantics the assistant branch uses. (OpenAI sends one final → the else path.)
|
|
1429
|
+
// same correction semantics the assistant branch uses. (Classic OpenAI Realtime sends one final → the else path.)
|
|
1430
|
+
if (transcript.Text.trim().length === 0) {
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1398
1433
|
this.replaceLastCaption('User', transcript.Text);
|
|
1399
1434
|
await this.relayTranscript('user', transcript.Text, true);
|
|
1400
1435
|
}
|
|
@@ -1488,8 +1523,9 @@ export class RealtimeSessionService {
|
|
|
1488
1523
|
async handleToolCall(call) {
|
|
1489
1524
|
const clientHandler = this.findClientToolHandler(call.ToolName);
|
|
1490
1525
|
if (clientHandler) {
|
|
1491
|
-
// Local UI tool: no server relay, no 'thinking' turn-state / narration burst
|
|
1492
|
-
// are fast, in-browser surface mutations (e.g. drawing on the whiteboard)
|
|
1526
|
+
// Local UI tool: no server relay, no 'thinking' turn-state / narration burst, and intentionally
|
|
1527
|
+
// NO thread card — these are fast, in-browser surface mutations (e.g. drawing on the whiteboard)
|
|
1528
|
+
// whose visual effects are immediately visible on the dedicated canvas/surface.
|
|
1493
1529
|
const resultJson = await this.executeClientTool(clientHandler, call);
|
|
1494
1530
|
this.client?.SendToolResult(call.CallID, resultJson);
|
|
1495
1531
|
// Observability: record the channel tool call on the co-agent's run (run-only — NOT a chat
|
|
@@ -1511,9 +1547,19 @@ export class RealtimeSessionService {
|
|
|
1511
1547
|
this.lastNarratedTail = '';
|
|
1512
1548
|
}
|
|
1513
1549
|
this.inFlightCallIds.add(call.CallID);
|
|
1550
|
+
if (call.ToolName !== 'invoke-target-agent') {
|
|
1551
|
+
// Direct action: emit synthetic progress immediately so the conversation thread
|
|
1552
|
+
// and activity rail render an active "working" action card while the tool executes.
|
|
1553
|
+
this._delegationProgress$.next({
|
|
1554
|
+
CallID: call.CallID,
|
|
1555
|
+
ToolName: call.ToolName,
|
|
1556
|
+
Step: 'direct_action',
|
|
1557
|
+
Message: `Executing ${FormatToolName(call.ToolName)}`
|
|
1558
|
+
});
|
|
1559
|
+
}
|
|
1514
1560
|
try {
|
|
1515
1561
|
const resultJson = await this.executeSessionTool(call.CallID, call.ToolName, call.ArgumentsJson);
|
|
1516
|
-
this.emitDelegationResult(call.CallID, resultJson);
|
|
1562
|
+
this.emitDelegationResult(call.CallID, resultJson, call.ToolName);
|
|
1517
1563
|
this.client?.SendToolResult(call.CallID, resultJson);
|
|
1518
1564
|
}
|
|
1519
1565
|
catch (error) {
|
|
@@ -1526,7 +1572,7 @@ export class RealtimeSessionService {
|
|
|
1526
1572
|
success: false,
|
|
1527
1573
|
error: error instanceof Error ? error.message : String(error)
|
|
1528
1574
|
});
|
|
1529
|
-
this.emitDelegationResult(call.CallID, errorJson);
|
|
1575
|
+
this.emitDelegationResult(call.CallID, errorJson, call.ToolName);
|
|
1530
1576
|
this.client?.SendToolResult(call.CallID, errorJson);
|
|
1531
1577
|
}
|
|
1532
1578
|
}
|
|
@@ -1559,13 +1605,12 @@ export class RealtimeSessionService {
|
|
|
1559
1605
|
/**
|
|
1560
1606
|
* Emits a delegation result so the overlay's "working" card flips to a result card with real
|
|
1561
1607
|
* content. Parses the broker's `{success, output, runId}` | `{success:false, error}` shape via
|
|
1562
|
-
* {@link ParseDelegationResultJson}; if it isn't JSON, surfaces the raw string.
|
|
1563
|
-
*
|
|
1564
|
-
*
|
|
1565
|
-
*
|
|
1566
|
-
* ride along as {@link RealtimeDelegationResult.Artifacts} for the surface panel's artifact tabs.
|
|
1608
|
+
* {@link ParseDelegationResultJson}; if it isn't JSON, surfaces the raw string. The `runId`
|
|
1609
|
+
* (the delegated `MJ: AI Agent Runs` record) rides along as {@link RealtimeDelegationResult.RunID}
|
|
1610
|
+
* for the overlay's dev links, and any `artifacts` ride along as {@link RealtimeDelegationResult.Artifacts}
|
|
1611
|
+
* for the surface panel's artifact tabs.
|
|
1567
1612
|
*/
|
|
1568
|
-
emitDelegationResult(callId, resultJson) {
|
|
1613
|
+
emitDelegationResult(callId, resultJson, toolName) {
|
|
1569
1614
|
// The result will be spoken next — a deferred interim update is now pointless
|
|
1570
1615
|
// (this is what keeps fast agents like Sage from narrating over their own answer),
|
|
1571
1616
|
// and any progress still in the PubSub pipe for this call is stale.
|
|
@@ -1580,6 +1625,7 @@ export class RealtimeSessionService {
|
|
|
1580
1625
|
const parsed = ParseDelegationResultJson(resultJson);
|
|
1581
1626
|
this._delegationResult$.next({
|
|
1582
1627
|
CallID: callId,
|
|
1628
|
+
ToolName: toolName,
|
|
1583
1629
|
Success: parsed.Success,
|
|
1584
1630
|
Output: parsed.Output,
|
|
1585
1631
|
RunID: parsed.RunID,
|
|
@@ -2259,6 +2305,8 @@ export class RealtimeSessionService {
|
|
|
2259
2305
|
/** Resets reactive + internal state at the start of a session. */
|
|
2260
2306
|
resetState() {
|
|
2261
2307
|
this._captions$.next([]);
|
|
2308
|
+
this.pendingUserCaption = '';
|
|
2309
|
+
this.hasActiveInterimUserCaption = false;
|
|
2262
2310
|
this.SetMinimized(false);
|
|
2263
2311
|
this.stopSegmentFlushing();
|
|
2264
2312
|
this.segmentIndex = 0;
|