@runtypelabs/persona 4.26.0 → 4.27.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/approval-ui.d.cts +11 -0
- package/dist/approval-ui.d.ts +11 -0
- package/dist/artifacts-ui.d.cts +11 -0
- package/dist/artifacts-ui.d.ts +11 -0
- package/dist/chunk-3255TNY7.js +1 -0
- package/dist/{client-history-YPEG45Q4.js → client-history-HTRKHBAF.js} +1 -1
- package/dist/client-history.js +1 -1
- package/dist/client-stream-N22JHTLE.js +4 -0
- package/dist/client-stream.js +3 -3
- package/dist/codegen.cjs +1 -1
- package/dist/codegen.js +1 -1
- package/dist/context-mentions.d.cts +11 -0
- package/dist/context-mentions.d.ts +11 -0
- package/dist/event-stream-view.d.cts +11 -0
- package/dist/event-stream-view.d.ts +11 -0
- package/dist/forms-ui.d.cts +13 -0
- package/dist/forms-ui.d.ts +13 -0
- package/dist/index.cjs +57 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.global.js +1 -1
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +58 -58
- package/dist/index.js.map +1 -1
- package/dist/session-reconnect.d.cts +11 -0
- package/dist/session-reconnect.d.ts +11 -0
- package/dist/smart-dom-reader.d.cts +11 -0
- package/dist/smart-dom-reader.d.ts +11 -0
- package/dist/theme-editor-preview.cjs +59 -59
- package/dist/theme-editor-preview.d.cts +11 -0
- package/dist/theme-editor-preview.d.ts +11 -0
- package/dist/theme-editor-preview.js +31 -31
- package/dist/theme-editor.d.cts +11 -0
- package/dist/theme-editor.d.ts +11 -0
- package/dist/voice-runtime-RHRX4F3T.js +17 -0
- package/dist/voice-runtime.cjs +8 -8
- package/dist/voice-runtime.d.cts +15 -0
- package/dist/voice-runtime.d.ts +15 -0
- package/dist/voice-runtime.js +8 -8
- package/package.json +1 -1
- package/src/approval-paused-tool-settle.test.ts +108 -4
- package/src/client-stream.ts +10 -3
- package/src/client.test.ts +20 -0
- package/src/session.ts +56 -10
- package/src/session.voice.test.ts +60 -3
- package/src/types.ts +11 -0
- package/src/ui.composer-defer-one.test.ts +17 -0
- package/src/ui.ts +49 -12
- package/src/voice/__fixtures__/voice-wire/server/session_end-provider-error.json +6 -0
- package/src/voice/__fixtures__/voice-wire/server/session_end-unknown-reason.json +4 -0
- package/src/voice/__fixtures__/voice-wire/server/session_end.json +5 -0
- package/src/voice/runtype-voice-provider.ts +131 -19
- package/src/voice/voice-delegation.ts +27 -11
- package/src/voice/voice.test.ts +257 -2
- package/dist/chunk-QPPJUSZH.js +0 -1
- package/dist/client-stream-42FOI3EC.js +0 -4
- package/dist/voice-runtime-UOQOFAFY.js +0 -17
package/src/voice/voice.test.ts
CHANGED
|
@@ -896,7 +896,7 @@ describe('RuntypeVoiceProvider (realtime streaming)', () => {
|
|
|
896
896
|
|
|
897
897
|
it('declares client_delegation (never the kebab form) only with a bridge and the switch on', async () => {
|
|
898
898
|
const { ws } = await startDelegatedCall();
|
|
899
|
-
expect(ws.url).toBe(voiceUrl('wss://api.example.com', 'a1', [...BASE_CAPS, 'client_delegation', 'delegation_update']));
|
|
899
|
+
expect(ws.url).toBe(voiceUrl('wss://api.example.com', 'a1', [...BASE_CAPS, 'client_delegation', 'delegation_update', 'delegation_read_back']));
|
|
900
900
|
expect(ws.url).not.toContain('client-delegation');
|
|
901
901
|
await startDelegatedCall({ clientDelegation: false });
|
|
902
902
|
expect(lastWs().url).toBe(voiceUrl('wss://api.example.com', 'a1', BASE_CAPS));
|
|
@@ -1144,6 +1144,85 @@ describe('RuntypeVoiceProvider (realtime streaming)', () => {
|
|
|
1144
1144
|
expect(calls).toEqual([]);
|
|
1145
1145
|
});
|
|
1146
1146
|
|
|
1147
|
+
describe('with delegation_read_back negotiated', () => {
|
|
1148
|
+
const TAG_CAPS = [...ALL_CAPS, 'delegation_read_back'];
|
|
1149
|
+
const tagged = (role: string, text: string, turnId: string, delegationId?: string) =>
|
|
1150
|
+
JSON.stringify({ type: 'transcript_update', role, text, utteranceId: turnId, final: true, delegationId });
|
|
1151
|
+
async function answered(text = 'Three are overdue.') {
|
|
1152
|
+
const call = await startDelegatedCall({}, { capabilities: TAG_CAPS });
|
|
1153
|
+
delegate(call.ws, 'd1', 'q');
|
|
1154
|
+
await flush();
|
|
1155
|
+
call.pending[0]({ status: 'completed', text });
|
|
1156
|
+
await flush();
|
|
1157
|
+
completed(call.ws, 'd1');
|
|
1158
|
+
return call;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
it('folds the tagged read-back, not a cut filler resuming first (production trace)', async () => {
|
|
1162
|
+
const { ws, transcripts } = await answered();
|
|
1163
|
+
ws.triggerMessage(tagged('assistant', "I'm pulling up the support queue.", 'f2'));
|
|
1164
|
+
ws.triggerMessage(tagged('assistant', 'Three are overdue.', 'r1', 'd1'));
|
|
1165
|
+
expect(transcripts.map((t) => t[1])).toEqual(["I'm pulling up the support queue."]);
|
|
1166
|
+
});
|
|
1167
|
+
|
|
1168
|
+
it('keeps folding the tagged read-back after a late user transcript', async () => {
|
|
1169
|
+
const { ws, transcripts } = await answered();
|
|
1170
|
+
ws.triggerMessage(tagged('user', 'Who is overdue?', 'u1'));
|
|
1171
|
+
ws.triggerMessage(tagged('assistant', 'Three are overdue.', 'r1', 'd1'));
|
|
1172
|
+
expect(transcripts.map((t) => t[1])).toEqual(['Who is overdue?']);
|
|
1173
|
+
});
|
|
1174
|
+
|
|
1175
|
+
it('renders untagged speech and a read-back tagged for a delegation the chat does not show', async () => {
|
|
1176
|
+
const { ws, transcripts } = await answered();
|
|
1177
|
+
ws.triggerMessage(tagged('assistant', 'Anything else?', 'a2'));
|
|
1178
|
+
ws.triggerMessage(tagged('assistant', 'I could not do that.', 'r9', 'd9'));
|
|
1179
|
+
expect(transcripts.map((t) => t[1])).toEqual(['Anything else?', 'I could not do that.']);
|
|
1180
|
+
});
|
|
1181
|
+
|
|
1182
|
+
it('keeps the tagged read-back of an answer that is not in the chat (a spoken decline)', async () => {
|
|
1183
|
+
const { ws, transcripts, pending } = await startDelegatedCall({}, { capabilities: TAG_CAPS });
|
|
1184
|
+
delegate(ws, 'd1', 'cancel that');
|
|
1185
|
+
await flush();
|
|
1186
|
+
pending[0]({ status: 'denied', text: 'Okay, I cancelled the request.', inChat: false });
|
|
1187
|
+
await flush();
|
|
1188
|
+
completed(ws, 'd1');
|
|
1189
|
+
ws.triggerMessage(tagged('assistant', 'Okay, I cancelled the request.', 'r1', 'd1'));
|
|
1190
|
+
expect(transcripts.map((t) => t[1])).toEqual(['Okay, I cancelled the request.']);
|
|
1191
|
+
});
|
|
1192
|
+
|
|
1193
|
+
it('folds every frame of a read-back tagged from its first partial', async () => {
|
|
1194
|
+
const { ws, transcripts } = await answered();
|
|
1195
|
+
const frame = (text: string, final: boolean, delegationId?: string) =>
|
|
1196
|
+
JSON.stringify({ type: 'transcript_update', role: 'assistant', text, utteranceId: 'r1', final, delegationId });
|
|
1197
|
+
ws.triggerMessage(frame('Three are', false, 'd1'));
|
|
1198
|
+
ws.triggerMessage(frame('Three are overdue.', true, 'd1'));
|
|
1199
|
+
expect(transcripts).toEqual([]);
|
|
1200
|
+
});
|
|
1201
|
+
|
|
1202
|
+
it('keeps showing an utterance whose tag arrives after an untagged partial, so no caption is left half-done', async () => {
|
|
1203
|
+
const { ws, transcripts } = await answered();
|
|
1204
|
+
const frame = (text: string, final: boolean, delegationId?: string) =>
|
|
1205
|
+
JSON.stringify({ type: 'transcript_update', role: 'assistant', text, utteranceId: 'r1', final, delegationId });
|
|
1206
|
+
ws.triggerMessage(frame('Three are', false));
|
|
1207
|
+
ws.triggerMessage(frame('Three are overdue.', true, 'd1'));
|
|
1208
|
+
expect(transcripts.map((t) => [t[1], t[2]])).toEqual([
|
|
1209
|
+
['Three are', false],
|
|
1210
|
+
['Three are overdue.', true],
|
|
1211
|
+
]);
|
|
1212
|
+
});
|
|
1213
|
+
|
|
1214
|
+
it('does not fold the tagged read-back of a failed delegation', async () => {
|
|
1215
|
+
const { ws, transcripts, pending } = await startDelegatedCall({}, { capabilities: TAG_CAPS });
|
|
1216
|
+
delegate(ws, 'd1', 'q');
|
|
1217
|
+
await flush();
|
|
1218
|
+
pending[0]({ status: 'failed', text: '' });
|
|
1219
|
+
await flush();
|
|
1220
|
+
completed(ws, 'd1');
|
|
1221
|
+
ws.triggerMessage(tagged('assistant', "Sorry, I couldn't complete that.", 'r1', 'd1'));
|
|
1222
|
+
expect(transcripts).toHaveLength(1);
|
|
1223
|
+
});
|
|
1224
|
+
});
|
|
1225
|
+
|
|
1147
1226
|
it('does not fold after a failed delegation', async () => {
|
|
1148
1227
|
const { ws, transcripts, pending } = await startDelegatedCall();
|
|
1149
1228
|
delegate(ws, 'd1', 'q');
|
|
@@ -1458,6 +1537,182 @@ describe('RuntypeVoiceProvider (realtime streaming)', () => {
|
|
|
1458
1537
|
});
|
|
1459
1538
|
});
|
|
1460
1539
|
});
|
|
1540
|
+
|
|
1541
|
+
describe('session_end (Amendment 6)', () => {
|
|
1542
|
+
const fixture = (name: string) =>
|
|
1543
|
+
JSON.stringify(wireFixtures('server').find((f) => JSON.stringify(f).includes(name)) ?? {});
|
|
1544
|
+
/** A live full-duplex call that collects errors and statuses from here on. */
|
|
1545
|
+
const endableCall = async () => {
|
|
1546
|
+
const call = await startFullDuplexCall();
|
|
1547
|
+
const errors: string[] = [];
|
|
1548
|
+
call.provider.onError((e) => errors.push(e.message));
|
|
1549
|
+
return { ...call, errors };
|
|
1550
|
+
};
|
|
1551
|
+
const end = (ws: MockWebSocket, frame: Record<string, unknown> | string, code: number) => {
|
|
1552
|
+
ws.triggerMessage(typeof frame === 'string' ? frame : JSON.stringify({ type: 'session_end', ...frame }));
|
|
1553
|
+
ws.triggerClose(code);
|
|
1554
|
+
};
|
|
1555
|
+
|
|
1556
|
+
it.each([
|
|
1557
|
+
['idle_timeout', 1000, 'Voice call ended after a quiet period.'],
|
|
1558
|
+
['max_duration', 1000, 'This voice call reached its time limit.'],
|
|
1559
|
+
['provider_ended', 1000, 'The voice session ended.'],
|
|
1560
|
+
['quota', 1008, 'Voice is unavailable right now.'],
|
|
1561
|
+
['auth_expired', 1008, 'Voice session expired. Tap the mic to reconnect.'], // reserved: no auto-reconnect
|
|
1562
|
+
['ended_by_server', 1000, null],
|
|
1563
|
+
['maintenance_window', 1000, null], // unknown: an ordinary server end
|
|
1564
|
+
])('ends on %s with its status text, without an error', async (reason, code, text) => {
|
|
1565
|
+
const { ws, provider, statuses, errors } = await endableCall();
|
|
1566
|
+
end(ws, { reason }, code);
|
|
1567
|
+
expect(provider.takeNotice()).toBe(text);
|
|
1568
|
+
expect(provider.takeNotice()).toBeNull(); // read once
|
|
1569
|
+
expect(errors).toEqual([]);
|
|
1570
|
+
expect(statuses.at(-1)).toBe('idle');
|
|
1571
|
+
expect(provider.isBargeInActive()).toBe(false);
|
|
1572
|
+
await vi.advanceTimersByTimeAsync(5_000);
|
|
1573
|
+
expect(MockWebSocket.instances.at(-1)).toBe(ws); // no reconnect
|
|
1574
|
+
});
|
|
1575
|
+
|
|
1576
|
+
it('shows the quota message the server sent', async () => {
|
|
1577
|
+
const { ws, provider } = await endableCall();
|
|
1578
|
+
end(ws, { reason: 'quota', message: 'Your voice minutes are used up.' }, 1008);
|
|
1579
|
+
expect(provider.takeNotice()).toBe('Your voice minutes are used up.');
|
|
1580
|
+
});
|
|
1581
|
+
|
|
1582
|
+
it('takes the doc fixtures: max_duration, and an unknown reason as ended_by_server', async () => {
|
|
1583
|
+
const first = await endableCall();
|
|
1584
|
+
end(first.ws, fixture('max_duration'), 1000);
|
|
1585
|
+
expect(first.provider.takeNotice()).toBe('This voice call reached its time limit.');
|
|
1586
|
+
const second = await endableCall();
|
|
1587
|
+
end(second.ws, fixture('maintenance_window'), 1000);
|
|
1588
|
+
expect(second.provider.takeNotice()).toBeNull();
|
|
1589
|
+
expect(second.errors).toEqual([]);
|
|
1590
|
+
});
|
|
1591
|
+
|
|
1592
|
+
it('reports a fatal error once: the error frame, not the session_end after it', async () => {
|
|
1593
|
+
const { ws, provider, statuses, errors } = await endableCall();
|
|
1594
|
+
ws.triggerMessage(JSON.stringify({ type: 'error', error: 'Voice engine failed', fatal: true }));
|
|
1595
|
+
end(ws, { reason: 'error' }, 1011);
|
|
1596
|
+
expect(errors).toEqual(['Voice engine failed']);
|
|
1597
|
+
expect(statuses.at(-1)).toBe('error');
|
|
1598
|
+
expect(provider.takeNotice()).toBeNull();
|
|
1599
|
+
});
|
|
1600
|
+
|
|
1601
|
+
it('reconnects once after a provider error, 1-2 s later, and says so', async () => {
|
|
1602
|
+
const { ws, provider, statuses, errors } = await endableCall();
|
|
1603
|
+
end(ws, fixture('provider_error'), 1011);
|
|
1604
|
+
expect(provider.takeNotice()).toBe('Voice connection lost. Reconnecting…');
|
|
1605
|
+
expect(errors).toEqual([]);
|
|
1606
|
+
expect(statuses.at(-1)).toBe('idle');
|
|
1607
|
+
expect(provider.isBargeInActive()).toBe(true); // the mic button hangs up meanwhile
|
|
1608
|
+
await vi.advanceTimersByTimeAsync(999);
|
|
1609
|
+
expect(MockWebSocket.instances.at(-1)).toBe(ws);
|
|
1610
|
+
await vi.advanceTimersByTimeAsync(1_001);
|
|
1611
|
+
const second = lastWs();
|
|
1612
|
+
expect(second).not.toBe(ws);
|
|
1613
|
+
expect(second.protocols).toEqual(['runtype.bearer', 'ct_secret']);
|
|
1614
|
+
|
|
1615
|
+
// A second failure doesn't reconnect again.
|
|
1616
|
+
second.triggerOpen();
|
|
1617
|
+
end(second, { reason: 'provider_error' }, 1011);
|
|
1618
|
+
expect(provider.takeNotice()).toBe('Voice connection lost.');
|
|
1619
|
+
expect(errors).toEqual(['Voice connection lost.']);
|
|
1620
|
+
expect(statuses.at(-1)).toBe('error');
|
|
1621
|
+
await vi.advanceTimersByTimeAsync(5_000);
|
|
1622
|
+
expect(lastWs()).toBe(second);
|
|
1623
|
+
});
|
|
1624
|
+
|
|
1625
|
+
it('reconnects once on server_restart, saying "Reconnecting…"', async () => {
|
|
1626
|
+
const { ws, provider } = await endableCall();
|
|
1627
|
+
end(ws, { reason: 'server_restart' }, 1012);
|
|
1628
|
+
expect(provider.takeNotice()).toBe('Reconnecting…');
|
|
1629
|
+
await vi.advanceTimersByTimeAsync(2_000);
|
|
1630
|
+
expect(lastWs()).not.toBe(ws);
|
|
1631
|
+
});
|
|
1632
|
+
|
|
1633
|
+
it('never reconnects once the visitor hangs up, during the wait or before the close', async () => {
|
|
1634
|
+
const waiting = await endableCall();
|
|
1635
|
+
end(waiting.ws, { reason: 'provider_error' }, 1011);
|
|
1636
|
+
await waiting.provider.stopListening();
|
|
1637
|
+
await vi.advanceTimersByTimeAsync(5_000);
|
|
1638
|
+
expect(lastWs()).toBe(waiting.ws);
|
|
1639
|
+
|
|
1640
|
+
const hungUp = await endableCall();
|
|
1641
|
+
hungUp.ws.triggerMessage(JSON.stringify({ type: 'session_end', reason: 'provider_error' }));
|
|
1642
|
+
await hungUp.provider.stopListening(); // closes the socket itself
|
|
1643
|
+
await vi.advanceTimersByTimeAsync(5_000);
|
|
1644
|
+
expect(lastWs()).toBe(hungUp.ws);
|
|
1645
|
+
expect(hungUp.errors).toEqual([]);
|
|
1646
|
+
});
|
|
1647
|
+
|
|
1648
|
+
it('reconnects on the real failure order: error, audio_end, session_end, close 1011', async () => {
|
|
1649
|
+
const { ws, provider, statuses, errors } = await endableCall();
|
|
1650
|
+
ws.triggerMessage(JSON.stringify({ type: 'error', error: 'Voice engine failed', fatal: true }));
|
|
1651
|
+
ws.triggerMessage(JSON.stringify({ type: 'audio_end' }));
|
|
1652
|
+
end(ws, { reason: 'provider_error', retryable: true }, 1011);
|
|
1653
|
+
expect(errors).toEqual(['Voice engine failed']); // reported once, by the error frame
|
|
1654
|
+
expect(statuses.at(-1)).toBe('idle');
|
|
1655
|
+
expect(provider.takeNotice()).toBe('Voice connection lost. Reconnecting…');
|
|
1656
|
+
expect(provider.isBargeInActive()).toBe(true);
|
|
1657
|
+
await vi.advanceTimersByTimeAsync(2_000);
|
|
1658
|
+
expect(lastWs()).not.toBe(ws);
|
|
1659
|
+
});
|
|
1660
|
+
|
|
1661
|
+
it('still reconnects when a socket error comes between session_end and the close', async () => {
|
|
1662
|
+
const { ws, provider, errors } = await endableCall();
|
|
1663
|
+
ws.triggerMessage(JSON.stringify({ type: 'session_end', reason: 'provider_error' }));
|
|
1664
|
+
ws.triggerError();
|
|
1665
|
+
ws.triggerClose(1011);
|
|
1666
|
+
expect(errors).toEqual([]);
|
|
1667
|
+
expect(provider.takeNotice()).toBe('Voice connection lost. Reconnecting…');
|
|
1668
|
+
await vi.advanceTimersByTimeAsync(2_000);
|
|
1669
|
+
expect(lastWs()).not.toBe(ws);
|
|
1670
|
+
});
|
|
1671
|
+
|
|
1672
|
+
it('ends the automatic reconnect when audio stays suspended outside a click (iOS)', async () => {
|
|
1673
|
+
const { ws, provider, statuses, errors } = await endableCall();
|
|
1674
|
+
end(ws, { reason: 'server_restart' }, 1012);
|
|
1675
|
+
provider.takeNotice();
|
|
1676
|
+
class SuspendedAudioContext extends MockAudioContext {
|
|
1677
|
+
state = 'suspended';
|
|
1678
|
+
resume() {
|
|
1679
|
+
return new Promise<void>(() => {}); // iOS: pending until a gesture
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
(globalThis as any).window.AudioContext = SuspendedAudioContext;
|
|
1683
|
+
try {
|
|
1684
|
+
await vi.advanceTimersByTimeAsync(2_500);
|
|
1685
|
+
} finally {
|
|
1686
|
+
(globalThis as any).window.AudioContext = MockAudioContext;
|
|
1687
|
+
}
|
|
1688
|
+
expect(lastWs()).toBe(ws); // no dead call opened
|
|
1689
|
+
expect(errors).toEqual(['Voice connection lost. Tap the mic to reconnect.']);
|
|
1690
|
+
expect(statuses.at(-1)).toBe('error');
|
|
1691
|
+
expect(provider.takeNotice()).toBe('Voice connection lost. Tap the mic to reconnect.');
|
|
1692
|
+
expect(provider.isBargeInActive()).toBe(false);
|
|
1693
|
+
});
|
|
1694
|
+
|
|
1695
|
+
it('treats the attach idle close (4408) as a quiet end, not an error', async () => {
|
|
1696
|
+
for (const withFrame of [false, true]) {
|
|
1697
|
+
const { ws, provider, statuses, errors } = await endableCall();
|
|
1698
|
+
if (withFrame) ws.triggerMessage(JSON.stringify({ type: 'session_end', reason: 'idle_timeout' }));
|
|
1699
|
+
ws.triggerClose(4408);
|
|
1700
|
+
expect(errors).toEqual([]);
|
|
1701
|
+
expect(statuses.at(-1)).toBe('idle');
|
|
1702
|
+
expect(provider.takeNotice()).toBe('Voice call ended after a quiet period.');
|
|
1703
|
+
}
|
|
1704
|
+
});
|
|
1705
|
+
|
|
1706
|
+
it('keeps an abnormal close without session_end exactly as before', async () => {
|
|
1707
|
+
const { ws, provider, statuses, errors } = await endableCall();
|
|
1708
|
+
ws.triggerClose(1006);
|
|
1709
|
+
expect(errors).toEqual(['Voice connection closed (code 1006)']);
|
|
1710
|
+
expect(statuses.at(-1)).toBe('error');
|
|
1711
|
+
expect(provider.takeNotice()).toBeNull();
|
|
1712
|
+
await vi.advanceTimersByTimeAsync(5_000);
|
|
1713
|
+
expect(lastWs()).toBe(ws);
|
|
1714
|
+
});
|
|
1715
|
+
});
|
|
1461
1716
|
});
|
|
1462
1717
|
});
|
|
1463
1718
|
|
|
@@ -1583,7 +1838,7 @@ describe('RuntypeVoiceProvider prewarm', () => {
|
|
|
1583
1838
|
provider.setSessionBridge({ getHistory: () => [], runDelegatedTurn: async () => ({ status: 'completed', text: '' }) });
|
|
1584
1839
|
provider.prewarm();
|
|
1585
1840
|
expect(lastWs().url).toBe(
|
|
1586
|
-
voiceUrl('wss://api.example.com', 'agent%2F1', ['attach', ...BASE_CAPS, 'client_delegation', 'delegation_update']),
|
|
1841
|
+
voiceUrl('wss://api.example.com', 'agent%2F1', ['attach', ...BASE_CAPS, 'client_delegation', 'delegation_update', 'delegation_read_back']),
|
|
1587
1842
|
);
|
|
1588
1843
|
});
|
|
1589
1844
|
|
package/dist/chunk-QPPJUSZH.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var t="4.26.0";var n=t;export{n as a};
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{c as me,d as ye,e as Ie}from"./chunk-K6HKIP5K.js";import"./chunk-K7NA7G7J.js";import{d as we}from"./chunk-2ANTRKTV.js";import"./chunk-TR2H475E.js";import{e as de,p as z}from"./chunk-NQLDCJAP.js";import"./chunk-76IELU7F.js";async function Te(c,h,m){let u={"Content-Type":"application/json",...c.headers};c.getHeaders&&Object.assign(u,await c.getHeaders());let M={executionId:h.executionId,approvalId:h.approvalId,decision:m,streamResponse:!0},x=(k,p)=>fetch(`${c.clientApiBase()}${k}`,{method:"POST",headers:u,body:JSON.stringify({...p,...M})}),A=`/v1/agents/${h.agentId}/approve`;if(!c.isClientTokenMode())return x(A);let{sessionId:y}=await c.initSession(),S=await x("/v1/client/approve",{sessionId:y});if(S.status===404){let k=await S.clone().json().catch(()=>null);if(!k||k.error==="Not Found")return x(A)}return S}async function Se(c,h,m,u){let M=c.isClientTokenMode(),x=M?c.getClientApiUrl("resume"):`${c.config.apiUrl?.replace(/\/+$/,"")||we}/resume`,A,y=null;if(M){let p=await c.initSession();A=p.sessionId,p.durableRecovery?.enabled===!0&&(y=await c.readVisitorToken())}let S={"Content-Type":"application/json",...y?{"X-Visitor-Token":y}:{},...c.headers};c.getHeaders&&Object.assign(S,await c.getHeaders());let k={executionId:h,toolOutputs:m,streamResponse:u?.streamResponse??!0,...u?.after?{after:u.after}:{}};if(A&&(k.sessionId=A),M&&A){let p=[...Ie(c.config),...await(await c.getWebMcpBridge())?.snapshotForDispatch()??[]],{response:D,commit:ee}=await c.sendWithClientToolsDiff(A,p,d=>{let f={...k,...d};return c.debug&&console.debug("[AgentWidgetClient] client token resume",f),fetch(x,{method:"POST",headers:S,body:JSON.stringify(f),signal:u?.signal})},{emptyMeansReplace:!0});return D.ok&&ee(),D}return fetch(x,{method:"POST",headers:S,body:JSON.stringify(k),signal:u?.signal})}function ke(c){let h=c.toLowerCase(),u={"application/pdf":"pdf","application/json":"json","application/zip":"zip","text/plain":"txt","text/csv":"csv","text/markdown":"md"}[h];if(u)return`attachment.${u}`;let M=h.indexOf("/");if(M>0){let x=h.slice(M+1).split(";")[0]?.trim()??"";if(x&&x!=="octet-stream"&&/^[a-z0-9.+-]+$/i.test(x))return`attachment.${x}`}return"attachment"}var he=c=>c.startsWith("{")||c.startsWith("[")||c.startsWith("<");function We(c,h){if(!c)return h;let m=c.trim(),u=h.trim();if(m.length===0)return h;if(u.length===0)return c;let M=he(m);if(!he(u))return c;if(!M||u===m||u.startsWith(m))return h;let A=z(c);return z(h)!==null&&A===null?h:c}async function be(c,h,m,u,M,x,A){if(!c.parseSSEEvent)return!1;try{let y=await c.parseSSEEvent(h);if(y===null)return!1;let S=p=>{let D={id:`assistant-${Date.now()}-${Math.random().toString(16).slice(2)}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!0,variant:"assistant",sequence:x(),...p!==void 0&&{partId:p}};return u.current=D,M(D),D},k=p=>u.current?u.current:S(p);if(y.text!==void 0){y.partId!==void 0&&A.current!==null&&y.partId!==A.current&&(u.current&&(u.current.streaming=!1,M(u.current)),S(y.partId)),y.partId!==void 0&&(A.current=y.partId);let p=k(y.partId);y.partId!==void 0&&!p.partId&&(p.partId=y.partId),p.content+=y.text,M(p)}return y.done&&(u.current&&(u.current.streaming=!1,M(u.current)),A.current=null,m({type:"status",status:"idle"})),y.error&&(A.current=null,m({type:"error",error:new Error(y.error)})),!0}catch(y){return typeof console<"u"&&console.error("[AgentWidget] parseSSEEvent error:",y),!1}}async function Ee(c,h,m,u,M){let x=h.getReader(),A=new TextDecoder,y="",S=Date.now(),k=0,p=()=>S+k++,D=n=>{let e=n.reasoning?{...n.reasoning,chunks:[...n.reasoning.chunks]}:void 0,t=n.toolCall?{...n.toolCall,chunks:n.toolCall.chunks?[...n.toolCall.chunks]:void 0}:void 0,o=n.tools?n.tools.map(s=>({...s,chunks:s.chunks?[...s.chunks]:void 0})):void 0;return{...n,reasoning:e,toolCall:t,tools:o}},ee=n=>{if(n.role!=="assistant"||n.variant)return!0;let e=Array.isArray(n.contentParts)&&n.contentParts.length>0,t=typeof n.rawContent=="string"&&n.rawContent.trim()!=="";return typeof n.content=="string"&&n.content.trim()!==""||e||t||!!n.stopReason},d=n=>{ee(n)&&m({type:"message",message:D(n)})},f=null,U=null,O={current:null},Ce={current:null},F=null,E="",$=new Map,v=new Map,te=new Map,Q=new Map,ne=new Map,X=u,ce=!1,oe=()=>{if(f)return f;let n,e="",t=F;return!ce&&X?(n=X,ce=!0,e=M??""):X&&t?n=`${X}_${t}`:n=`assistant-${Date.now()}-${Math.random().toString(16).slice(2)}`,f={id:n,role:"assistant",content:e,createdAt:new Date().toISOString(),streaming:!0,sequence:p()},d(f),f},se=n=>{let e=Q.get(n);if(e)return e;let t={id:`reason-${n}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!0,variant:"reasoning",sequence:p(),reasoning:{id:n,status:"streaming",chunks:[]}};return Q.set(n,t),d(t),t},H=new Set,re=new Map,ge=new Set,J=new Map,Ae=n=>{if(!n)return!1;let e=n.replace(/_+/g,"_").replace(/^_|_$/g,"");return e==="emit_artifact_markdown"||e==="emit_artifact_component"},L=n=>{let e=ne.get(n);if(e)return e;let t={id:`tool-${n}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!0,variant:"tool",sequence:p(),toolCall:{id:n,status:"pending"}};return ne.set(n,t),d(t),t},ue=n=>{if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n=="string"){let e=Number(n);if(!Number.isNaN(e)&&Number.isFinite(e))return e;let t=Date.parse(n);if(!Number.isNaN(t))return t}return Date.now()},ie=n=>{if(typeof n=="string")return n;if(n==null)return"";try{return JSON.stringify(n)}catch{return String(n)}},T=new Map,W=new Map,Me=(n,e)=>{let t=ie(e),o=W.get(n.id),s=We(o,t);n.rawContent=s;let r=T.get(n.id),i=I=>{let g=n.content??"";I.trim()!==""&&(g.trim().length===0||I.startsWith(g)||I.trimStart().startsWith(g.trim()))&&(n.content=I)},l=()=>{if(r){let I=r.close?.();I instanceof Promise&&I.catch(()=>{})}T.delete(n.id),W.delete(n.id),n.streaming=!1,d(n)};if(!r){i(t),l();return}let a=z(s);if(a!==null&&a.trim()!==""){i(a),l();return}let w=I=>{let g=typeof I=="string"?I:I?.text??null;if(g!==null&&g.trim()!=="")return g;let N=r.getExtractedText();return N!==null&&N.trim()!==""?N:t},C;try{C=r.processChunk(s)}catch{i(t),l();return}if(C instanceof Promise){C.then(I=>{i(w(I)),l()}).catch(()=>{i(t),l()});return}i(w(C)),l()},K=null,ae=(n,e,t,o)=>{n.rawContent=e,T.has(n.id)||T.set(n.id,c.createStreamParser());let s=T.get(n.id),r=e.trim().startsWith("{")||e.trim().startsWith("[");if(r&&W.set(n.id,e),s.__isPlainTextParser===!0){n.content=o!==void 0?e:n.content+t,W.delete(n.id),T.delete(n.id),n.rawContent=void 0,d(n);return}let l=s.processChunk(e);if(l instanceof Promise)l.then(a=>{let w=typeof a=="string"?a:a?.text??null;w!==null&&w.trim()!==""?(n.content=w,d(n)):!r&&!e.trim().startsWith("<")&&(n.content=o!==void 0?e:n.content+t,W.delete(n.id),T.delete(n.id),n.rawContent=void 0,d(n))}).catch(()=>{n.content=o!==void 0?e:n.content+t,W.delete(n.id),T.delete(n.id),n.rawContent=void 0,d(n)});else{let a=typeof l=="string"?l:l?.text??null;a!==null&&a.trim()!==""?(n.content=a,d(n)):!r&&!e.trim().startsWith("<")&&(n.content=o!==void 0?e:n.content+t,W.delete(n.id),T.delete(n.id),n.rawContent=void 0,d(n))}},V=(n,e)=>{let t=e??n.content;if(t==null||t===""){n.streaming=!1,d(n);return}let s=W.get(n.id)??ie(t);n.rawContent=s;let r=T.get(n.id),i=null,l=!1;if(r&&(i=r.getExtractedText(),i===null&&(i=z(s)),i===null)){let a=r.processChunk(s);a instanceof Promise?(l=!0,a.then(w=>{let C=typeof w=="string"?w:w?.text??null;C!==null&&(n.content=C,n.streaming=!1,T.delete(n.id),W.delete(n.id),d(n))}).catch(()=>{})):i=typeof a=="string"?a:a?.text??null}if(!l){i!==null&&i.trim()!==""?n.content=i:W.has(n.id)||(n.content=ie(t));let a=T.get(n.id);if(a){let w=a.close?.();w instanceof Promise&&w.catch(()=>{}),T.delete(n.id)}W.delete(n.id),n.streaming=!1,d(n)}},pe=(n,e,t)=>{let o=v.get(n);if(o)return o;let s={id:`nested-${e}-${n}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!0,sequence:p(),...t?{variant:t}:{},...t==="reasoning"?{reasoning:{id:n,status:"streaming",chunks:[]}}:{},agentMetadata:{parentToolId:e}};return v.set(n,s),d(s),s},G=[],le,Y=new Map,_=0,B="agent",fe=!1,Z=null,j=null,xe=c.config().iterationDisplay??"separate";for(le=()=>{for(let n=0;n<G.length;n++){let e=G[n];if(!fe&&B!=="flow"&&typeof e.stepType=="string"&&(B="flow"),e.type==="reasoning_start"){let t=typeof e.id=="string"?e.id:null,o=typeof e.parentToolCallId=="string"&&e.parentToolCallId?e.parentToolCallId:null;if(t&&o){$.set(t,o),pe(t,o,"reasoning");continue}let s=e.id,r=se(s);r.reasoning=r.reasoning??{id:s,status:"streaming",chunks:[]},r.reasoning.startedAt=r.reasoning.startedAt??Date.now(),r.reasoning.completedAt=void 0,r.reasoning.durationMs=void 0,(e.scope==="loop"||e.scope==="turn")&&(r.reasoning.scope=e.scope),r.streaming=!0,r.reasoning.status="streaming",d(r)}else if(e.type==="reasoning_delta"){let t=typeof e.id=="string"?e.id:null;if(t&&$.has(t)&&v.has(t)){let r=v.get(t),i=e.delta;i&&r.reasoning&&(r.reasoning.chunks.push(String(i)),d(r));continue}let o=e.id,s=se(o);s.reasoning=s.reasoning??{id:o,status:"streaming",chunks:[]},s.reasoning.startedAt=s.reasoning.startedAt??Date.now(),e.delta&&s.reasoning.chunks.push(e.delta),s.reasoning.status="streaming",s.streaming=!0,d(s)}else if(e.type==="reasoning_complete"){let t=typeof e.id=="string"?e.id:null;if(t&&$.has(t)&&v.has(t)){let i=v.get(t);if(i.reasoning){let l=typeof e.text=="string"?e.text:"";l&&i.reasoning.chunks.length===0&&i.reasoning.chunks.push(l),i.reasoning.status="complete",i.streaming=!1,d(i)}$.delete(t),v.delete(t);continue}let o=e.id,s=typeof e.text=="string"?e.text:"";!Q.get(o)&&(s||e.scope==="loop")&&se(o);let r=Q.get(o);if(r?.reasoning){(e.scope==="loop"||e.scope==="turn")&&(r.reasoning.scope=e.scope),s&&r.reasoning.chunks.length===0&&r.reasoning.chunks.push(s),r.reasoning.status="complete",r.reasoning.completedAt=Date.now();let i=r.reasoning.startedAt??Date.now();r.reasoning.durationMs=Math.max(0,(r.reasoning.completedAt??Date.now())-i),r.streaming=!1,d(r)}}else if(e.type==="tool_start"){f&&(f.streaming=!1,d(f),f=null),typeof e.iteration=="number"&&(_=e.iteration);let t=e.toolCallId,o=e.toolName;if(Ae(o)){H.add(t);continue}let s=L(t),r=s.toolCall??{id:t,status:"pending"};r.name=o??r.name,r.status="running",r.success=void 0,r.error=void 0,r.duration=void 0,e.parameters!==void 0&&(r.args=e.parameters),r.startedAt=r.startedAt??ue(e.startedAt),r.completedAt=void 0,r.durationMs=void 0,s.toolCall=r,s.streaming=!0,e.executionId&&(s.agentMetadata={executionId:e.executionId,iteration:e.iteration}),d(s)}else if(e.type==="tool_output_delta"){let t=e.toolCallId;if(H.has(t))continue;let o=L(t),s=o.toolCall??{id:t,status:"running"};s.startedAt=s.startedAt??Date.now();let r=e.delta;r&&(s.chunks=s.chunks??[],s.chunks.push(String(r))),s.status="running",o.toolCall=s,o.streaming=!0,e.executionId&&(o.agentMetadata=o.agentMetadata??{executionId:e.executionId,iteration:_}),d(o)}else if(e.type==="tool_complete"){let t=e.toolCallId;if(H.has(t)){H.delete(t);continue}let o=L(t),s=o.toolCall??{id:t,status:"running"};s.status="complete",e.result!==void 0&&(s.result=e.result),s.name=e.toolName??s.name,s.success=e.success,s.error=e.error,s.completedAt=Date.now();let r=e.executionTime;if(typeof r=="number")s.durationMs=r,s.duration=r;else{let i=s.startedAt??Date.now();s.durationMs=Math.max(0,(s.completedAt??Date.now())-i)}o.toolCall=s,o.streaming=!1,e.executionId&&(o.agentMetadata=o.agentMetadata??{executionId:e.executionId,iteration:e.iteration??_}),d(o)}else if(e.type==="await"&&e.toolName){let t=typeof e.toolCallId=="string"&&e.toolCallId.length>0?e.toolCallId:void 0,o=t??e.toolId??`local-${p()}`,s=L(o),r=e.toolName,i=e.origin==="webmcp"&&!de(r)?`webmcp:${r}`:r,l=de(i),a=s.toolCall??{id:o,status:"pending"};a.name=i,a.args=e.parameters,a.status=l?"running":"complete",a.chunks=a.chunks??[],a.startedAt=a.startedAt??ue(e.awaitedAt),l?(a.completedAt=void 0,a.duration=void 0,a.durationMs=void 0):a.completedAt=a.completedAt??a.startedAt,s.toolCall=a,s.streaming=!1,s.agentMetadata={...s.agentMetadata,executionId:e.executionId??s.agentMetadata?.executionId,awaitingLocalTool:!0,...t?{webMcpToolCallId:t}:{}},d(s)}else if(e.type==="text_start"){let t=typeof e.id=="string"?e.id:null,o=typeof e.parentToolCallId=="string"&&e.parentToolCallId?e.parentToolCallId:null;if(t&&o){$.set(t,o);continue}let s=f;s&&(B==="flow"?(V(s),K=s):(s.streaming=!1,d(s)),f=null),F=typeof e.id=="string"?e.id:F,E=""}else if(e.type==="text_delta"){let t=typeof e.id=="string"?e.id:null,o=t?$.get(t):void 0;if(t&&o){let i=typeof e.delta=="string"?e.delta:"",l=(te.get(t)??"")+i;if(te.set(t,l),l.trim()==="")continue;let a=pe(t,o);a.agentMetadata={...a.agentMetadata,executionId:e.executionId,parentToolId:o},ae(a,l,i,void 0);continue}if(F=typeof e.id=="string"?e.id:F,B==="flow"){let i=typeof e.delta=="string"?e.delta:"";if(E+=i,E.trim()==="")continue;let l=oe();l.agentMetadata={executionId:e.executionId,iteration:_},ae(l,E,i,void 0),U=l;continue}let s=typeof e.delta=="string"?e.delta:"";E+=s;let r=oe();r.agentMetadata={executionId:e.executionId,iteration:_,turnId:Z??void 0,agentName:j?.agentName},ae(r,E,s,void 0),U=r}else if(e.type==="text_complete"){let t=typeof e.id=="string"?e.id:null;if(t&&$.has(t)){let s=v.get(t);s&&V(s),$.delete(t),te.delete(t),v.delete(t);continue}let o=f;o&&(B==="flow"?(V(o),K=o):((o.content??"")===""&&typeof e.text=="string"&&(o.content=e.text),o.streaming=!1,d(o)),f=null),F=null,E=""}else if(e.type==="step_complete"){if(e.stepType==="tool")continue;if(e.success===!1){let t=e.error||"Step failed";m({type:"error",error:new Error(t)});let o=f;o&&o.streaming&&(o.streaming=!1,d(o)),m({type:"status",status:"idle"});continue}{let t=K;K=null;let o=e.stopReason,r=(e.result&&typeof e.result=="object"?e.result:null)?.response;if(t)o&&(t.stopReason=o),r!=null?Me(t,r):t.streaming!==!1&&(T.delete(t.id),W.delete(t.id),t.streaming=!1,d(t));else{let i=r!=null&&r!=="";if(i||o){let l=oe();o&&(l.stopReason=o),i?V(l,r):(l.streaming=!1,d(l))}}continue}}else if(e.type==="execution_start")B=e.kind==="flow"?"flow":"agent",fe=!0,B==="agent"&&(j={executionId:e.executionId,agentId:e.agentId??"virtual",agentName:e.agentName??""});else if(e.type==="turn_start"){let t=typeof e.iteration=="number"?e.iteration:_;if(t!==_){if(xe==="separate"&&t>1){let o=f;o&&(o.streaming=!1,d(o),f=null)}_=t}Z=typeof e.id=="string"?e.id:null,U=null}else if(e.type==="tool_input_delta"){let t=e.toolCallId;if(t){let o=ne.get(t);o?.toolCall&&(o.toolCall.chunks=o.toolCall.chunks??[],o.toolCall.chunks.push(e.delta??""),d(o))}}else if(e.type==="tool_input_complete"){if(H.has(e.toolCallId))continue;let t=L(e.toolCallId),o=t.toolCall;o.args=e.parameters,o.name=e.toolName??o.name,d(t)}else if(e.type==="turn_complete"){let t=e.stopReason,o=f??U;if(t&&o!==null){let s=e.id;(!s||o.agentMetadata?.turnId===s)&&(o.stopReason=t,d(o))}Z===e.id&&(Z=null)}else if(e.type==="media_start"){let t=String(e.id);Y.set(t,{mediaType:typeof e.mediaType=="string"?e.mediaType:void 0,toolCallId:e.toolCallId,parts:[]})}else if(e.type==="media_delta"){let t=Y.get(String(e.id));t&&typeof e.delta=="string"&&t.parts.push(e.delta)}else if(e.type==="media_complete"){let t=String(e.id),o=Y.get(t);Y.delete(t);let s=(typeof e.mediaType=="string"?e.mediaType:void 0)??o?.mediaType??"application/octet-stream",r=typeof e.data=="string"?e.data:void 0,i=typeof e.url=="string"?e.url:o&&o.parts.length>0?o.parts.join(""):void 0,l=null;if(r)l={type:"media",data:r,mediaType:s};else if(i){let I=s.toLowerCase();l={type:I==="image"||I.startsWith("image/")?"image-url":"file-url",url:i,mediaType:s}}let a=e.toolCallId??o?.toolCallId,w=l?[l]:[],C=[];for(let I of w){if(!I||typeof I!="object")continue;let g=I,N=typeof g.type=="string"?g.type:void 0,q=typeof g.mediaType=="string"?g.mediaType.toLowerCase():"",b=null,P="";if(N==="media"){let R=typeof g.data=="string"?g.data:void 0;if(!R)continue;P=q.length>0?q:"application/octet-stream",b=`data:${P};base64,${R}`}else if(N==="image-url"){let R=typeof g.url=="string"?g.url:void 0;if(!R)continue;P=q,b=R}else if(N==="file-url"){let R=typeof g.url=="string"?g.url:void 0;if(!R)continue;P=q,b=R}else continue;if(b)if(N==="image-url"||P.startsWith("image/"))C.push({type:"image",image:b,...P.includes("/")?{mimeType:P}:{}});else if(P.startsWith("audio/"))C.push({type:"audio",audio:b,mimeType:P});else if(P.startsWith("video/"))C.push({type:"video",video:b,mimeType:P});else{let R=P||"application/octet-stream";C.push({type:"file",data:b,mimeType:R,filename:ke(R)})}}if(C.length>0){let I=p(),g=a,q={id:`agent-media-${typeof g=="string"&&g.length>0?`${g}-${I}`:String(I)}`,role:"assistant",content:"",contentParts:C,createdAt:new Date().toISOString(),streaming:!1,sequence:I,agentMetadata:{executionId:e.executionId,iteration:_}};d(q);let b=f;b&&(b.streaming=!1,d(b)),f=null,O.current=null}}else if(e.type==="execution_complete"){let t=f;t&&(e.kind==="flow"&&t.streaming!==!1?V(t):(t.streaming=!1,d(t)),f=null),F=null,E="",K=null,m({type:"status",status:"idle",terminal:!0})}else if(e.type==="execution_error"){let t=typeof e.error=="string"?e.error:e.error?.message??"Execution error";m({type:"error",error:new Error(t)})}else if(e.type!=="ping"){if(e.type==="approval_start"){let t=e.approvalId??`approval-${p()}`,o={id:`approval-${t}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!1,variant:"approval",sequence:p(),approval:{id:t,status:"pending",agentId:j?.agentId??"virtual",executionId:e.executionId??j?.executionId??"",toolName:e.toolName??"",toolType:e.toolType,description:e.description??`Execute ${e.toolName??"tool"}`,...typeof e.reason=="string"&&e.reason?{reason:e.reason}:{},parameters:e.parameters,...typeof e.toolCallId=="string"&&e.toolCallId?{toolCallId:e.toolCallId}:{}}};d(o)}else if(e.type==="approval_complete"){let t=e.approvalId;if(t){let s={id:`approval-${t}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!1,variant:"approval",sequence:p(),approval:{id:t,status:e.decision??"approved",agentId:j?.agentId??"virtual",executionId:e.executionId??j?.executionId??"",toolName:"",description:"",resolvedAt:Date.now()}};d(s)}}else if(e.type==="artifact_start"||e.type==="artifact_delta"||e.type==="artifact_update"||e.type==="artifact_complete"){if(e.type==="artifact_start"){let t=e.artifactType,o=String(e.id),s=typeof e.title=="string"?e.title:void 0,r=e.file,i;if(r&&typeof r=="object"&&!Array.isArray(r)&&typeof r.path=="string"&&typeof r.mimeType=="string"&&(i={path:r.path,mimeType:r.mimeType,...typeof r.language=="string"?{language:r.language}:{}}),m({type:"artifact_start",id:o,artifactType:t,title:s,component:typeof e.component=="string"?e.component:void 0,...i?{file:i}:{}}),J.set(o,{markdown:"",title:s,file:i}),!ge.has(o)){ge.add(o);let l=me(c.config().features?.artifacts,{artifactType:t,...i?{file:i}:{}}),a=typeof e.component=="string"?e.component:void 0,w={id:`artifact-ref-${o}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!0,sequence:p(),rawContent:ye(l,{artifactId:o,title:s,artifactType:t,status:"streaming",...i?{file:i}:{},...a?{component:a}:{}})};re.set(o,w),d(w)}}else if(e.type==="artifact_delta"){let t=String(e.id),o=typeof e.delta=="string"?e.delta:String(e.delta??"");m({type:"artifact_delta",id:t,artDelta:o});let s=J.get(t);s&&(s.markdown+=o)}else if(e.type==="artifact_update"){let t=e.props&&typeof e.props=="object"&&!Array.isArray(e.props)?e.props:{};m({type:"artifact_update",id:String(e.id),props:t,component:typeof e.component=="string"?e.component:void 0});let o=J.get(String(e.id));o&&(o.props={...o.props??{},...t})}else if(e.type==="artifact_complete"){let t=String(e.id);m({type:"artifact_complete",id:t});let o=re.get(t);if(o){o.streaming=!1;try{let s=JSON.parse(o.rawContent??"{}");if(s.props){s.props.status="complete";let r=J.get(t);r?.markdown&&(s.props.markdown=r.markdown),r?.file&&(s.props.file=r.file),s.component==="PersonaArtifactInline"&&r?.props&&Object.keys(r.props).length>0&&(s.props.componentProps=r.props)}o.rawContent=JSON.stringify(s)}catch{}J.delete(t),d(o),re.delete(t)}}}else if(e.type==="error"&&e.recoverable===!1&&e.error!=null&&e.error!==""){let t=typeof e.error=="string"?e.error:e.error?.message!=null?String(e.error.message):"Execution error";m({type:"error",error:new Error(t)});let o=f;o&&o.streaming&&(o.streaming=!1,d(o)),m({type:"status",status:"idle"})}}}G.length=0};;){let{done:n,value:e}=await x.read();if(n)break;y+=A.decode(e,{stream:!0});let t=y.split(`
|
|
2
|
-
|
|
3
|
-
`);y=t.pop()??"";for(let o of t){let s=o.split(`
|
|
4
|
-
`),r="message",i="",l=null;for(let g of s)g.startsWith("event:")?r=g.replace("event:","").trim():g.startsWith("data:")?i+=g.replace("data:","").trim():g.startsWith("id:")&&(l=g.slice(3).trim());let a=()=>{l!==null&&l!==""&&m({type:"cursor",id:l})};if(!i){a();continue}let w;try{w=JSON.parse(i)}catch(g){m({type:"error",error:g instanceof Error?g:new Error("Failed to parse chat stream payload")});continue}let C=w!==null&&typeof w=="object"&&!Array.isArray(w)?w:null,I=r!=="message"?r:typeof C?.type=="string"?C.type:"message";if(c.onSSEEvent?.(I,w),c.parseSSEEvent){O.current=f;let g=await be(c,w,m,O,d,p,Ce);if(O.current&&O.current!==f&&(f=O.current),g){a();continue}}C&&(G.push({...C,type:I}),le()),a()}}le()}export{We as preferFinalStructuredContent,Te as resolveApproval,Se as resumeFlow,Ee as streamResponse};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import{a as Y}from"./chunk-6V3MNEKB.js";import{a as K}from"./chunk-QPPJUSZH.js";var x=16e3,ue=24e3,ge=4096,he=x*2*8,pe=4,fe=1380533830,me=3e4,ve=5e3,ye=3e4,be=3e4,Se=6e5,we="full-duplex-v1",Ae=300,ke=2e3,Me=2e3,Ce="runtype-browser-v1",Te=54e4,Ee="You're talking to an AI assistant. Voice is processed by OpenAI.",Ie=8e3,Pe=4e3,Ve=12,J=2e3;function _e(i,e){let t="Conversation so far:",s=e.slice(0,Pe).trim(),n=Ie-(s?s.length+2:0)-t.length,r=[];for(let l of i.slice(-Ve).reverse()){let a=l.content.replace(/\s+/g," ").trim();if(!a)continue;a.length>J&&(a=`${a.slice(0,J-1)}\u2026`);let o=`${l.role==="user"?"User":"Assistant"}: ${a}`;if(o.length+1>n)break;n-=o.length+1,r.unshift(o)}let d=r.length>0?[`${t}
|
|
2
|
-
${r.join(`
|
|
3
|
-
`)}`]:[];return s&&d.push(s),d.join(`
|
|
4
|
-
|
|
5
|
-
`)}function Re(i){return i.byteLength>=44&&new DataView(i).getUint32(0,!1)===fe?new Uint8Array(i,44):new Uint8Array(i)}function Z(i){let e=i.replace(/\/+$/,"");return/^wss?:\/\//i.test(e)?e:/^https?:\/\//i.test(e)?e.replace(/^http/i,"ws"):`${typeof window<"u"&&window.location?.protocol==="https:"?"wss:":"ws:"}//${e}`}function Le(i){return Z(i).replace(/^ws/i,"http")}function De(i){return typeof i!="number"||!Number.isFinite(i)?ye:Math.min(Se,Math.max(be,Math.round(i)))}var P=class{constructor(e){this.config=e;this.type="runtype";this.#e=null;this.#d=null;this.#u=[];this.#i=null;this.#r=null;this.#a=null;this.#f=[];this.#m=0;this.#n=null;this.#g=!1;this.#c=!1;this.#s=0;this.#w=!1;this.#F=Number.NEGATIVE_INFINITY;this.#o=null;this.#l=!1;this.#A=!1;this.#k=0;this.#h=0;this.#v=!1;this.bridge=null;this.#C=!1;this.#y=new Set;this.#b=new Map;this.#T=new Set;this.#_=!1;this.#E=null;this.#R=null;this.#L=Promise.resolve();this.#D=new Set;this.#S=!1;this.#O=new Set;this.#N=new Set;this.#z=[];this.#B=[];this.#W=[];this.#U=[];this.#x=[]}#e;#d;#u;#i;#r;#a;#f;#m;#n;#g;#c;#s;#w;#F;#o;#l;#A;#k;#h;#M;#v;#C;#y;#b;#T;#V;#_;#E;#R;#L;#D;#S;#O;#N;#z;#B;#W;#U;#x;async connect(){}setSessionBridge(e){this.bridge=e}prewarm(){if(this.#g||this.#o)return;let e=this.config?.agentId,t=this.config?.clientToken,s=this.config?.host;if(!e||!t||!s)return;let n=Date.now();if(!(n-this.#F<me)){this.#F=n;try{this.config?.prewarmMode==="attach"?this.#te(s,e,t):this.#ee(s,e,t)}catch{}}}#ee(e,t,s){if(typeof fetch!="function")return;let n=`${Le(e)}/v1/client/agents/${encodeURIComponent(t)}/voice/prewarm`;fetch(n,{method:"POST",headers:{Authorization:`Bearer ${s}`},keepalive:!0}).catch(()=>{})}#te(e,t,s){let n=new URLSearchParams,r=this.config?.attachIdleMs,d=De(r);r!==void 0&&n.set("attachIdleMs",String(d));let l=new WebSocket(this.#G(e,t,n),["runtype.bearer","runtype.attach",s]);l.binaryType="arraybuffer";let a=()=>{},o=new Promise(u=>{a=u}),c={ws:l,state:"connecting",ready:o,settle:a,openedAt:0,idleTimer:void 0};this.#o=c,l.onopen=()=>{this.#o===c&&(c.state=l.protocol==="runtype.attach"?"attached":"live",c.openedAt=Date.now(),this.#X(c,d),c.state==="attached"&&l.send('{"type":"ping"}'),c.settle())},l.onmessage=u=>{if(this.#o!==c||typeof u.data!="string")return;let p;try{p=JSON.parse(u.data)}catch{return}p.type==="attached"&&typeof p.idleMs=="number"&&this.#X(c,p.idleMs-(Date.now()-c.openedAt))},l.onerror=()=>{},l.onclose=()=>{this.#o===c&&this.#I()}}#X(e,t){clearTimeout(e.idleTimer),e.idleTimer=setTimeout(()=>{this.#o===e&&this.#I()},Math.max(0,t))}#I(){let e=this.#o;if(!e)return;this.#o=null,clearTimeout(e.idleTimer);let{ws:t}=e;if(t.onopen=null,t.onmessage=null,t.onerror=null,t.onclose=null,e.settle(),t.readyState===WebSocket.CONNECTING||t.readyState===WebSocket.OPEN)try{t.close(1e3,"prewarm released")}catch{}}async#se(){let e=this.#o;if(!e)return null;if(e.state==="connecting"){let t;await Promise.race([e.ready,new Promise(s=>{t=setTimeout(s,ve)})]),clearTimeout(t)}return this.#o!==e?null:e.state==="connecting"||e.ws.readyState!==WebSocket.OPEN?(this.#I(),null):(this.#o=null,clearTimeout(e.idleTimer),{ws:e.ws,live:e.state==="live"})}#G(e,t,s){let n=["partial_transcript","context"];this.bridge&&this.config?.clientDelegation!==!1&&n.push("client_delegation","delegation_update"),s&&n.unshift("attach");let r=new URLSearchParams({voiceProtocol:Ce,clientVersion:`persona/${K}`,voiceCapabilities:we,clientCapabilities:n.join(",")});return s?.forEach((d,l)=>r.set(l,d)),`${Z(e)}/ws/agents/${encodeURIComponent(t)}/voice?${r}`}async startListening(){if(this.#g)return;let e=this.config?.agentId,t=this.config?.clientToken,s=this.config?.host;if(!e)throw new Error("Runtype voice requires an agentId");if(!t)throw new Error("Runtype voice requires a clientToken");if(!s)throw new Error("Runtype voice requires a host (or widget apiUrl)");let n=++this.#s;this.#w=!1,this.#g=!0;try{let r=await navigator.mediaDevices.getUserMedia({audio:{sampleRate:x,channelCount:1,echoCancellation:!0}});if(n!==this.#s){r.getTracks().forEach(u=>u.stop());return}this.#i=r;let d=window.AudioContext||window.webkitAudioContext,l=new d({sampleRate:x});l.state==="suspended"&&await l.resume().catch(()=>{}),this.#d=l;let a=this.config?.createPlaybackEngine?await this.config.createPlaybackEngine():new Y(ue);if(n!==this.#s){a.destroy(),r.getTracks().forEach(u=>u.stop()),l.close().catch(()=>{});return}this.#n=a,this.#j(),this.#ie(l,r,n);let o=await this.#se();if(n!==this.#s){o?.ws.close(1e3,"client ended call");return}if(o){let{ws:u}=o;this.#e=u,this.#K(u,n),o.live||u.send('{"type":"start"}'),this.#$(u),this.#t("listening");return}let c=new WebSocket(this.#G(s,e),["runtype.bearer",t]);c.binaryType="arraybuffer",this.#e=c,c.onopen=()=>{n===this.#s&&(this.#$(c),this.#t("listening"))},this.#K(c,n)}catch(r){throw this.#p(),this.#P(r),this.#t("error"),r}}#K(e,t){e.onmessage=s=>this.#ne(s,t),e.onerror=()=>{t===this.#s&&(this.#P(new Error("Voice connection failed")),this.#t("error"),this.#p())},e.onclose=s=>{if(this.#w){this.#w=!1;return}if(t===this.#s){if(s.code!==1e3){let n=s.code?` (code ${s.code})`:"";this.#P(new Error(`Voice connection closed${n}`)),this.#t("error")}else this.#t("idle");this.#p()}}}getDisclosure(){let e=this.config?.disclosureText;return this.#g&&this.#l&&e!==!1?e||Ee:null}async stopListening(){this.#p(),this.#t("idle")}async disconnect(){this.#p(),this.#t("disconnected"),this.#z=[],this.#B=[],this.#W=[],this.#U=[],this.#x=[]}stopPlayback(){this.#Q();let e=this.#e;e&&e.readyState===WebSocket.OPEN&&(this.#l&&(this.#k=Date.now()+ke,e.send('{"type":"cancel"}')),this.#t("listening"))}getInterruptionMode(){return"barge-in"}isBargeInActive(){return this.#g}onLevel(e){this.#u.push(e)}async deactivateBargeIn(){this.#p(),this.#t("idle")}#ie(e,t,s){let n=e.createMediaStreamSource(t);this.#r=n;let r=e.createScriptProcessor(ge,1,1);this.#a=r,r.onaudioprocess=d=>{if(s!==this.#s)return;let l=this.#e,a=l?.readyState===WebSocket.OPEN;if(l&&!a&&l.readyState!==WebSocket.CONNECTING)return;let o=d.inputBuffer.getChannelData(0),c=new Int16Array(o.length),u=0;for(let p=0;p<o.length;p++){let f=Math.max(-1,Math.min(1,o[p]));u+=f*f,c[p]=f<0?f*32768:f*32767}if(l&&a)this.#$(l),l.send(c.buffer);else for(this.#f.push(c.buffer),this.#m+=c.byteLength;this.#m>he;)this.#m-=this.#f.shift().byteLength;if(this.#u.length>0){let p=Math.sqrt(u/o.length),f=Math.max(0,Math.min(1,p*pe));for(let g of this.#u)g(f)}},n.connect(r),r.connect(e.destination)}#$(e){for(let t of this.#f)e.send(t);this.#f=[],this.#m=0}#ne(e,t){if(t!==this.#s)return;if(e.data instanceof ArrayBuffer){this.#ce(e.data,t);return}let s;try{s=JSON.parse(e.data)}catch{return}switch(s.type){case"session_config":s.speechMode&&(this.#l=s.speechMode==="speech_to_speech",this.#n?.setContinuousMode?.(this.#l)),Array.isArray(s.capabilities)&&(this.#y=new Set(s.capabilities)),typeof s.callId=="string"&&(this.#V=s.callId),this.#C=this.#l&&this.#y.has("client_delegation")&&!!this.bridge,this.#l&&!this.#c&&this.#t("listening"),this.#y.has("context")&&!this.#_&&(this.#_=!0,this.#E=this.#oe());break;case"transcript_update":{let n=s.role==="assistant"?"assistant":"user",r=s.utteranceId??s.turnId;if(!r||n==="assistant"&&this.#q())break;let d=String(r);if(n==="user")s.final===!0&&this.#Y(t),this.#S=!1;else if(this.#S&&!this.#O.has(d)&&(this.#N.add(d),this.#S=!1),this.#O.add(d),this.#N.has(d))break;this.#H(n,s.text??"",s.final===!0,{turnId:d,...typeof s.startMs=="number"&&{startMs:s.startMs},...typeof s.endMs=="number"&&{endMs:s.endMs},...this.#C&&{caption:!0}});break}case"delegation_started":case"delegation_completed":{let n=String(s.delegationId??s.turnId);if(s.type==="delegation_started"){this.#Y(t);let r=s.input;this.#C&&r&&this.#ae(n,{delegationId:n,userText:String(r.text??""),userUtteranceIds:Array.isArray(r.userUtteranceIds)?r.userUtteranceIds.filter(d=>typeof d=="string"):[],messages:Array.isArray(r.messages)?r.messages:[]},t)}else s.speak!==!1&&this.#D.has(n)&&(this.#S=!0);this.#A=s.type==="delegation_started",!this.#c&&!this.#q()&&this.#t(this.#A?"processing":"listening");break}case"delegation_cancelled":this.#J(String(s.delegationId),s.reason!=="session_ending"&&s.reason!=="provider_cancelled");break;case"warning":console.warn(`[Persona voice] ${s.code}: ${s.message??""}`,this.#V??""),s.delegationId&&(s.code==="UNKNOWN_DELEGATION"||s.code==="LATE_RESULT_LIMIT")&&this.#J(String(s.delegationId));break;case"audio_clear":this.#Q(),this.#k=0,this.#t("listening");break;case"transcript_interim":this.#t("listening"),this.#H("user",s.text??"",!1);break;case"transcript_final":{let n=s.role==="assistant"?"assistant":"user";this.#t(n==="user"?"processing":"speaking"),this.#H(n,s.text??"",!0);break}case"audio_end":this.#n?this.#n.markStreamEnd():(this.#c=!1,this.#t("listening"));break;case"metrics":this.#de({llmMs:s.llm_ms,ttsMs:s.tts_ms,firstAudioMs:s.first_audio_ms,totalMs:s.total_ms});break;case"error":this.#P(new Error(s.error||"Voice error")),this.#t("error");break}}async#oe(){let e=this.bridge?.getHistory()??[],t="";try{let s=this.config?.callContext;t=String((typeof s=="function"?await s():s)??"")}catch{}return _e(e,t)}#Y(e){let t=this.#E;if(!t)return;this.#E=null;let s=!1,n=t.then(r=>{let d=this.#e;s||!r||e!==this.#s||d?.readyState!==WebSocket.OPEN||d.send(JSON.stringify({type:"context",text:r}))});this.#R={done:n,drop:()=>s=!0}}async#re(){let e=this.#R;if(!e)return;let t,s=await Promise.race([e.done.then(()=>!1),new Promise(n=>{t=setTimeout(()=>n(!0),Me)})]);clearTimeout(t),s&&e.drop()}#J(e,t=!1){this.#T.add(e),this.bridge?.dropDelegation?.(e,t),this.#b.get(e)?.abort()}#ae(e,t,s){let n=this.bridge,r=(d,l,a)=>{let o=this.#e;return s!==this.#s||o?.readyState!==WebSocket.OPEN||this.#T.has(e)?!1:(o.send(JSON.stringify({type:d,delegationId:e,status:l,text:a})),!0)};this.#L=this.#L.then(async()=>{if(s!==this.#s||this.#T.has(e))return;let d=await n.runDelegatedTurn(t).catch(()=>({status:"failed",text:""}));await this.#re();let l=!!d.followUp,a=l&&this.#y.has("delegation_update");if(!r(a?"delegation_update":"delegation_result",l&&!a?"completed":d.status,d.text)||(d.status!=="failed"&&this.#D.add(e),!d.followUp))return;let c=new AbortController;this.#b.set(e,c),d.followUp({signal:c.signal,approvalTimeoutMs:this.config?.approvalTimeoutMs&&Math.min(this.config.approvalTimeoutMs,Te),readBack:a,onUpdate:u=>r("delegation_update","pending_approval",u)}).then(u=>{this.#b.delete(e),a&&u&&!c.signal.aborted&&r("delegation_result",u.status,u.text)})})}#ce(e,t){if(t!==this.#s||!this.#n||this.#q())return;let s=Re(e);s.length!==0&&(this.#c||(this.#c=!0,this.#t("speaking")),this.#j(),this.#n.enqueue(s),this.#l&&this.#le(s.length))}#q(){return Date.now()<this.#k}#j(){if(this.#v||!this.#n)return;this.#v=!0;let e=this.#s;this.#n.onFinished(()=>{e===this.#s&&(this.#v=!1,this.#Z())})}#le(e){let t=Date.now();this.#h=Math.max(t,this.#h)+e/48,clearTimeout(this.#M),this.#M=setTimeout(()=>this.#Z(),this.#h-t+Ae)}#Z(){this.#c=!1,this.#h=0,this.#e&&this.#e.readyState===WebSocket.OPEN&&this.#t(this.#A?"processing":"listening")}#Q(){this.#n?.flush(),this.#v=!1,this.#j(),this.#c=!1,this.#h=0,clearTimeout(this.#M)}#p(){this.#s+=1,this.#g=!1,this.#c=!1,this.#I(),this.#l=!1,this.#A=!1,this.#C=!1,this.#y=new Set;for(let e of this.#b.values())e.abort();if(this.#b.clear(),this.#T.clear(),this.#V=void 0,this.#_=!1,this.#E=null,this.#R=null,this.#L=Promise.resolve(),this.#D.clear(),this.#S=!1,this.#O.clear(),this.#N.clear(),this.#v=!1,this.#k=0,this.#h=0,clearTimeout(this.#M),this.#f=[],this.#m=0,this.#a&&(this.#a.onaudioprocess=null,this.#a.disconnect(),this.#a=null),this.#r&&(this.#r.disconnect(),this.#r=null),this.#i&&(this.#i.getTracks().forEach(e=>e.stop()),this.#i=null),this.#d&&(this.#d.close().catch(()=>{}),this.#d=null),this.#n&&(this.#n.destroy(),this.#n=null),this.#e){this.#w=!0;try{this.#e.close(1e3,"client ended call")}catch{}this.#e=null}}onResult(e){this.#z.push(e)}onError(e){this.#B.push(e)}onStatusChange(e){this.#W.push(e)}onTranscript(e){this.#U.push(e)}onMetrics(e){this.#x.push(e)}#t(e){this.#W.forEach(t=>t(e))}#P(e){this.#B.forEach(t=>t(e))}#H(e,t,s,n){this.#U.forEach(r=>r(e,t,s,n))}#de(e){this.#x.forEach(t=>t(e))}};var C=class{constructor(e={}){this.config=e;this.type="browser";this.#e=null;this.#d=[];this.#u=[];this.#i=[];this.#r=!1;this.#a=typeof window<"u"?window:void 0}#e;#d;#u;#i;#r;#a;async connect(){this.#i.forEach(e=>e("connected"))}async startListening(){try{if(this.#r)throw new Error("Already listening");if(!this.#a)throw new Error("Window object not available");let e=this.#a.SpeechRecognition||this.#a.webkitSpeechRecognition;if(!e)throw new Error("Browser speech recognition not supported");this.#e=new e,this.#e.lang=this.config?.language||"en-US",this.#e.continuous=this.config?.continuous||!1,this.#e.interimResults=!0,this.#e.onresult=t=>{let s=Array.from(t.results).map(r=>r[0]).map(r=>r.transcript).join(""),n=t.results[t.results.length-1].isFinal;this.#d.forEach(r=>r({text:s,confidence:n?.8:.5,provider:"browser"})),n&&!this.config?.continuous&&this.stopListening()},this.#e.onerror=t=>{this.#u.forEach(s=>s(new Error(t.error))),this.#i.forEach(s=>s("error"))},this.#e.onstart=()=>{this.#r=!0,this.#i.forEach(t=>t("listening"))},this.#e.onend=()=>{this.#r=!1,this.#i.forEach(t=>t("idle"))},this.#e.start()}catch(e){throw this.#u.forEach(t=>t(e)),this.#i.forEach(t=>t("error")),e}}async stopListening(){this.#e&&(this.#e.stop(),this.#e=null),this.#r=!1,this.#i.forEach(e=>e("idle"))}onResult(e){this.#d.push(e)}onError(e){this.#u.push(e)}onStatusChange(e){this.#i.push(e)}async disconnect(){await this.stopListening(),this.#i.forEach(e=>e("disconnected"))}static isSupported(){return"SpeechRecognition"in window||"webkitSpeechRecognition"in window}};function _(i){switch(i.type){case"runtype":if(!i.runtype)throw new Error("Runtype voice provider requires configuration");return new P(i.runtype);case"browser":if(!C.isSupported())throw new Error("Browser speech recognition not supported");return new C(i.browser||{});case"custom":{let e=i.custom;if(!e)throw new Error("Custom voice provider requires a `custom` provider instance or factory");let t=typeof e=="function"?e():e;if(!t||typeof t.startListening!="function")throw new Error("Custom voice provider `custom` must be a VoiceProvider (or a factory returning one)");return t}default:throw new Error(`Unknown voice provider type: ${i.type}`)}}function Q(i){if(i?.type==="custom"&&i.custom)return _({type:"custom",custom:i.custom});if(i?.type==="runtype"&&i.runtype)return _({type:"runtype",runtype:i.runtype});if(C.isSupported())return _({type:"browser",browser:i?.browser||{language:"en-US"}});throw new Error("No supported voice providers available")}function Oe(i){try{return Q(i),!0}catch{return!1}}var ee=i=>i.toLowerCase().replace(/[^\p{L}\p{N}]+/gu,""),$=class{constructor(e){this.host=e;this.turns=new Map;this.latestId=null;this.cancelled=new Set}apply(e,t,s,n,r,d){let l=this.host;t=t.trim();let a=this.turns.get(n);if(a||(a={},this.turns.set(n,a),this.latestId=n),e==="user"){a.userFinal=s;let o=a.userId?l.find(a.userId):void 0;if(o){let c=a.userStartMs===void 0&&r!==void 0;c&&(a.userStartMs=r),l.upsert({...o,content:t,voiceProcessing:!s,...c&&this.placeBefore(this.startedAfter(r))})}else{a.userStartMs=r;let c=a.assistantId?l.find(a.assistantId):void 0;a.userId=l.inject({role:"user",content:t,streaming:!1,voiceProcessing:!s,voiceCaption:d,...this.placeBefore(this.startedAfter(r)??c)}).id}}else if(!this.cancelled.has(n)){a.assistantFinal=s;let o=a.assistantId?l.find(a.assistantId):void 0;if(o){let c=a.assistantStartMs===void 0&&r!==void 0;c&&(a.assistantStartMs=r),l.upsert({...o,content:t,streaming:!s,voiceProcessing:!s,...c&&this.placeBefore(this.startedAfter(r))})}else t&&(a.assistantStartMs=r,a.assistantId=l.inject({role:"assistant",content:t,streaming:!s,voiceProcessing:!s,voiceCaption:d,...this.placeBefore(this.startedAfter(r))}).id);s&&a.assistantId&&l.markSpoken(a.assistantId)}this.sync()}claimUserTurn(e,t=[]){let s=t[t.length-1];for(let r of t)r!==s&&(this.turns.has(r)||this.turns.set(r,{}),this.turns.get(r).claimed=!0);let n;if(s){if(n=this.turns.get(s),n||(n={},this.turns.set(s,n)),n.claimed)return null;(!n.userId||!this.host.find(n.userId))&&(n.userFinal=!0,n.userId=this.host.inject({role:"user",content:e.trim()}).id)}else{let r=ee(e),d=[...this.turns.values()].reverse().flatMap(l=>{let a=l.userId&&!l.claimed?this.host.find(l.userId):void 0;return a?[{turn:l,text:ee(a.content)}]:[]}).filter(({text:l})=>l&&r);n=(d.find(({text:l})=>l===r)??d.find(({text:l})=>l.startsWith(r)||r.startsWith(l)))?.turn}return n?(n.claimed=!0,n.userId):null}cancel(){let e=this.inFlight();if(e.length===0){let t=this.awaiting();if(!t)return;e=[t]}for(let t of e)this.cancelled.add(t);this.closeReplies(e),this.sync()}fail(e){let t=this.awaiting(),s=this.inFlight();if(!t&&s.length===0)return;for(let d of s)this.turns.get(d).assistantFinal=!0;this.closeReplies(s);let n=this.host.inject({role:"assistant",content:e,streaming:!1,voiceProcessing:!1}),r=t?this.turns.get(t):void 0;r&&(r.assistantId=n.id,r.assistantFinal=!0),this.sync()}settle(){if(this.turns.size===0)return;let e=this.pending(),t=new Set;for(let s of this.turns.values())s.userId&&t.add(s.userId),s.assistantId&&(t.add(s.assistantId),this.host.markSpoken(s.assistantId));this.turns.clear(),this.latestId=null,this.host.settle(t),e&&this.host.setStreaming(!1)}startedAfter(e){if(e===void 0)return;let t;for(let s of this.turns.values())for(let[n,r]of[[s.userId,s.userStartMs],[s.assistantId,s.assistantStartMs]])n&&r!==void 0&&r>e&&(!t||r<t.start)&&(t={start:r,id:n});return t&&this.host.find(t.id)}placeBefore(e){if(!e)return;let t=e.sequence??0,s=t-1;for(let n of this.turns.values())for(let r of[n.userId,n.assistantId]){let d=r?this.host.find(r):void 0,l=d?.sequence;d?.createdAt===e.createdAt&&l!==void 0&&l>s&&l<t&&(s=l)}return{createdAt:e.createdAt,sequence:(s+t)/2}}closeReplies(e){let t=new Set;for(let s of e){let n=this.turns.get(s)?.assistantId;n&&(t.add(n),this.host.markSpoken(n))}t.size>0&&this.host.settle(t)}inFlight(){let e=[];for(let[t,s]of this.turns)s.assistantId&&!s.assistantFinal&&!this.cancelled.has(t)&&e.push(t);return e}awaiting(){let e=this.latestId;if(!e)return null;let t=this.turns.get(e);return t?.userFinal&&!t.assistantId&&!t.claimed&&!this.cancelled.has(e)?e:null}pending(){return this.awaiting()!==null||this.inFlight().length>0}sync(){this.host.setStreaming(this.pending())}};var Ne="I need your answer in the chat before I can continue.";var te="no|nope|never ?mind|decline(?: it| that)?|cancel(?: it| that| this)?(?: (?:the|my|that|this) (?:[a-z]+ )?(?:order|request))?|don'?t (?:do|place) (?:it|that|the (?:[a-z]+ )?order)",Be=new RegExp(`^(?:${te})(?: (?:${te}))?(?: thanks| thank you)?$`),We=i=>Be.test(i.toLowerCase().replace(/[^a-z' ]+/g," ").replace(/\s+/g," ").trim()),se="Briefly tell the user what you're about to do and ask them to approve or decline it in the chat. Don't claim it's done.",ie=()=>new Promise(i=>setTimeout(i,50)),q=(i,e)=>i.length>e?`${i.slice(0,e-1).trimEnd()}\u2026`:i,E=i=>i.replace(/^webmcp:/,"").replace(/([a-z\d])([A-Z])/g,"$1 $2").replace(/[_\-.]+/g," ").trim().toLowerCase();function j(i,e=0){if(i==null||i==="")return"";if(typeof i!="object")return String(i);if(e>2)return"";if(Array.isArray(i))return i.map(r=>j(r,e+1)).filter(Boolean).join(", ");let t=i,s=t.quantity??t.qty??t.count,n=t.name??t.item??t.product??t.title;return s!=null&&n!=null&&typeof n!="object"?`${s} ${n}`:Object.entries(t).filter(([r])=>!r.startsWith("_")).map(([r,d])=>{let l=j(d,e+1);return l&&(e?`${E(r)} ${l}`:`${E(r)}: ${l}`)}).filter(Boolean).join(e?", ":"; ")}function ne(i){let e=i.length>1?"These actions need the user's approval in the chat before they happen:":"This action needs the user's approval in the chat before it happens:",t=1e3-e.length-se.length-2,s=i.map(n=>{let r=[E(n.toolName)];n.description&&r.push(`(${q(n.description.trim(),160)})`);let d=j(n.parameters);return d&&r.push(`with ${d}`),n.reason&&r.push(`because: ${q(n.reason.trim(),160)}`),q(`- ${r.join(" ")}`,Math.floor(t/i.length)-1)});return`${e}
|
|
6
|
-
${s.join(`
|
|
7
|
-
`)}
|
|
8
|
-
|
|
9
|
-
${se}`}var R=i=>i.variant==="approval"&&i.approval?.status==="pending";function Ue(i){let e=null,t=null,s=()=>i.track(e??t),n=[],r=new Map,d=new Map,l=(g,m)=>{r.set(g,[...r.get(g)??[],m]),r.size>32&&r.delete(r.keys().next().value)},a=g=>i.messages().find(m=>m.id===g),o=g=>g.approvals.filter(m=>a(m)?.approval?.status==="pending"),c=g=>E(a(g)?.approval?.toolName??""),u=(g,m,b)=>{g.outcome={status:m,text:b};for(let S of o(g))i.decide(S)},p=g=>g.flatMap(m=>i.messages().find(b=>b.id===m)??[]).filter(m=>!m.variant&&m.content.trim()).map(m=>m.content.trim()).join(`
|
|
10
|
-
|
|
11
|
-
`),f=async g=>{do await ie();while(i.busy()&&!(g&&(i.parked()||g.failed)))};return{getHistory:()=>i.messages().flatMap(g=>(g.role==="user"||g.role==="assistant")&&!g.variant&&!g.voiceProcessing&&!g.voiceCaption&&g.content?[{role:g.role,content:g.content}]:[]),dropDelegation(g,m){d.set(g,!!m),d.size>32&&d.delete(d.keys().next().value);let b=m&&n.find(S=>S.delegationId===g);b&&!b.outcome&&u(b,"timeout","");for(let S of r.get(g)??[])S.dropped=!0,S.ids.length&&i.unspoken(S.ids)},async runDelegatedTurn({delegationId:g,userText:m,userUtteranceIds:b}){let S=n.filter(h=>o(h).length),I=S.flatMap(o);if(I.length===1&&We(m)){let h=c(I[0]);return u(S[0],"denied",""),{status:"denied",text:`Okay, I cancelled the ${h} request. Nothing was done.`}}let H=i.parked()&&i.messages().every(h=>!R(h)||I.includes(h.id));i.busy()&&!H&&await f();let oe=new Set(i.messages().map(h=>h.id)),L=()=>i.messages().filter(h=>!oe.has(h.id)&&h.variant==="approval"),A={ids:[],failed:!1};l(g,A),e=A,s();try{await i.send(m,i.claim(m,b)??void 0),await f(A)}catch{A.failed=!0}finally{e=null,s()}let re=A.ids.flatMap(h=>i.messages().find(y=>y.id===h)??[]),T=p(A.ids),V=A.failed?[]:L().filter(R),ae=new Set(V.map(h=>E(h.approval.toolName)));for(let h of S){if(h.outcome)continue;for(let w of o(h).filter(D=>ae.has(c(D))))h.replaced.add(w),i.decide(w);let y=c(h.approvals[0]);h.approvals.every(w=>h.replaced.has(w))?h.outcome={status:"cancelled",text:`The earlier ${y} request was replaced by the new one; it was not done.`}:H&&h.approvals.every(w=>a(w)?.approval?.status==="denied")&&(h.outcome={status:"cancelled",text:`The earlier ${y} request was replaced by the new one; it was not done.`})}if(V.length){let h=new Set(V.map(w=>w.id)),y={delegationId:g,approvals:[...h],at:Date.now(),replaced:new Set};return n.push(y),d.get(g)&&u(y,"timeout",""),T=`${T}
|
|
12
|
-
|
|
13
|
-
${ne(V.map(w=>w.approval))}`.trim(),{status:"pending_approval",text:T,followUp:async({signal:w,approvalTimeoutMs:D=3e5,readBack:F=!0,onUpdate:ce})=>{let k={ids:[],failed:!1};r.delete(g),l(g,k);let z=()=>L().filter(v=>h.has(v.id)||k.ids.includes(v.id)),le=()=>L().filter(v=>R(v)&&!h.has(v.id)&&!n.some(M=>M.approvals.includes(v.id))&&(k.ids.includes(v.id)||v.approval?.toolType==="webmcp"&&t===k)),X=()=>{t=k,s()};F&&X();try{for(;!w.aborted&&!y.outcome&&(e||i.busy()||z().some(R));){F&&t!==k&&!o(y).length&&X();let v=le();if(v.length){for(let M of v)h.add(M.id),y.approvals.push(M.id);y.at=Date.now(),ce?.(ne(v.map(M=>M.approval)))}if(Date.now()-y.at>=D&&o(y).length&&(!i.busy()||i.parked())){u(y,"timeout",`That ${c(y.approvals[0])} request expired, so nothing was done.`);break}await ie()}}finally{t===k&&(t=null,s()),n.splice(n.indexOf(y),1)}if(w.aborted)return null;if(y.outcome)return y.outcome;if(k.failed)return{status:"failed",text:`The ${c(y.approvals[0])} request didn't complete.`};let G=z(),O=v=>G.filter(v).map(M=>E(M.approval.toolName)).join(", "),N=G.some(v=>v.approval?.status==="approved"),B=O(v=>v.approval?.status==="denied"&&!y.replaced.has(v.id)),W=O(v=>y.replaced.has(v.id)),U=O(v=>v.approval?.status==="timeout"),de=[N?p(k.ids):"",B&&`The user declined the ${B} request in the chat, so ${N?"that part was not done":"nothing was done"}.`,W&&`The earlier ${W} request was replaced by the new one; it was not done.`,U&&`The ${U} request timed out, so it was not done.`].filter(Boolean).join(`
|
|
14
|
-
|
|
15
|
-
`);return{status:N?"completed":B?"denied":W?"cancelled":U?"timeout":"completed",text:de}}}}return!A.failed&&i.parked()||re.some(h=>h.agentMetadata?.awaitingLocalTool&&!h.agentMetadata.askUserQuestionAnswered&&!h.toolCall?.name?.startsWith("webmcp:"))?{status:A.failed?"failed":"completed",text:`${T}
|
|
16
|
-
|
|
17
|
-
${Ne}`.trim()}:{status:!A.failed&&T?"completed":"failed",text:T}}}}var xe=(i,e,t,s)=>{let n=i.session;try{i.keyed=t?new t({find:o=>n.messages.find(c=>c.id===o),inject:o=>n.injectMessage(o),upsert:o=>n.upsertMessage(o),settle:o=>{n.messages=n.messages.map(c=>o.has(c.id)?{...c,streaming:!1,voiceProcessing:!1}:c),n.callbacks.onMessagesChanged([...n.messages])},setStreaming:o=>{(o||!i.busy())&&i.setStreaming(o)},markSpoken:o=>{n.ttsSpokenMessageIds.add(o)}}):null,s&&e.setSessionBridge&&e.setSessionBridge(s({messages:()=>n.messages,busy:()=>i.busy(),parked:()=>n.webMcpApprovalResolvers.size>0,claim:(o,c)=>i.keyed?.claimUserTurn(o,c)??null,send:(o,c)=>n.sendMessage(o,{viaVoice:!0,voiceTurn:{userMessageId:c}}),track:o=>{i.setDelegation(o)},unspoken:o=>{for(let c of o)n.ttsSpokenMessageIds.delete(c);n.streaming||n.speakLatestAssistantMessage(o)},decide:o=>{if(n.webMcpApprovalResolvers.has(o))return n.resolveWebMcpApproval(o,"denied");let c=n.messages.find(u=>u.id===o)?.approval;c?.status==="pending"&&n.resolveApproval(c,"denied")}}));let r=i.generation(),d=()=>i.provider()===e&&r===i.generation(),a=(n.config.voiceRecognition??{}).processingErrorText??"Voice processing failed. Please try again.";e.onResult(o=>{d()&&o.provider!=="runtype"&&o.text&&o.text.trim()&&n.sendMessage(o.text,{viaVoice:!0})}),e.onTranscript&&e.onTranscript((o,c,u,p)=>{if(d()){if(p?.turnId){i.keyed?.apply(o,c,u,p.turnId,p.startMs,p.caption);return}if(o==="user"){if(i.pendingUser)n.upsertMessage({id:i.pendingUser,role:"user",content:c,createdAt:new Date().toISOString(),streaming:!1,voiceProcessing:!u});else{let f=n.injectMessage({role:"user",content:c,streaming:!1,voiceProcessing:!u});i.pendingUser=f.id}if(u){i.turns().start(p?.turnId),i.pendingUser=null;let f=n.injectMessage({role:"assistant",content:"",streaming:!0,voiceProcessing:!0});i.pendingAssistant=f.id,i.setStreaming(!0)}}else{if(!i.turns().accepts(p?.turnId))return;if(i.pendingAssistant)n.upsertMessage({id:i.pendingAssistant,role:"assistant",content:c,createdAt:new Date().toISOString(),streaming:!u,voiceProcessing:!u});else{let f=n.injectMessage({role:"assistant",content:c,streaming:!u,voiceProcessing:!u});i.pendingAssistant=f.id}u&&(i.pendingAssistant&&n.ttsSpokenMessageIds.add(i.pendingAssistant),i.setStreaming(!1),i.pendingAssistant=null)}}}),e.onLevel&&e.onLevel(o=>{d()&&i.setLevel(Number.isFinite(o)?Math.max(0,Math.min(1,o)):0)}),e.onMetrics&&e.onMetrics(o=>{d()&&n.config.voiceRecognition?.onMetrics?.(o)}),e.onError(o=>{d()&&(console.error("Voice error:",o),i.pendingAssistant&&(n.upsertMessage({id:i.pendingAssistant,role:"assistant",content:a,createdAt:new Date().toISOString(),streaming:!1,voiceProcessing:!1}),i.setStreaming(!1),i.pendingUser=null,i.pendingAssistant=null),i.keyed?.fail(a))}),e.onStatusChange(o=>{d()&&(i.setStatus(o),(o==="listening"||o==="idle"||o==="disconnected")&&i.settlePending(o!=="listening"),(o==="idle"||o==="disconnected")&&i.keyed?.settle(),n.callbacks.onVoiceStatusChanged?.(o))}),e.connect()}catch(r){console.error("Failed to setup voice:",r)}};var $e=i=>{let e=a=>{if(i.original)return;let o=i.config().voiceRecognition??{};i.original={backgroundColor:a.style.backgroundColor,color:a.style.color,borderColor:a.style.borderColor,iconName:o.iconName??"mic",iconSize:parseFloat(o.iconSize??"")||i.iconFallbackPx}},t=(a,o,c)=>{let u=a.querySelector("svg");u&&u.remove();let p=i.original?.iconSize??(parseFloat(i.config().voiceRecognition?.iconSize??"")||i.iconFallbackPx),f=i.renderIcon(o,p,c,1.5);f&&a.appendChild(f)},s=a=>{a.classList.remove("persona-voice-recording","persona-voice-processing","persona-voice-speaking")};return{recording:()=>{let a=i.mic();if(!a)return;e(a);let o=i.config().voiceRecognition??{},c=o.recordingBackgroundColor,u=o.recordingIconColor,p=o.recordingBorderColor;if(s(a),a.classList.add("persona-voice-recording"),i.setMicState("recording"),a.style.backgroundColor=c??"var(--persona-voice-recording-bg, #ef4444)",a.style.color=u??"var(--persona-voice-recording-indicator, #ffffff)",u){let f=a.querySelector("svg");f&&f.setAttribute("stroke",u)}p&&(a.style.borderColor=p),a.setAttribute("aria-label","Stop voice recognition")},processing:()=>{let a=i.mic();if(!a)return;e(a);let o=i.config().voiceRecognition??{},c=i.session().getVoiceInterruptionMode(),u=i.original,p=o.processingIconName??"loader",f=o.processingIconColor??u?.color??"",g=o.processingBackgroundColor??u?.backgroundColor??"",m=o.processingBorderColor??u?.borderColor??"";s(a),a.classList.add("persona-voice-processing"),i.setMicState("processing"),a.style.backgroundColor=g,a.style.borderColor=m;let b=f||"currentColor";a.style.color=b,t(a,p,b),a.setAttribute("aria-label","Processing voice input"),c==="none"&&(a.style.cursor="default")},speaking:()=>{let a=i.mic();if(!a)return;e(a);let o=i.config().voiceRecognition??{},c=i.session().getVoiceInterruptionMode(),u=i.original,p=c==="cancel"?"square":c==="barge-in"?"mic":"volume-2",f=o.speakingIconName??p,g=o.speakingIconColor??(c==="barge-in"?o.recordingIconColor??u?.color??"":u?.color??""),m=o.speakingBackgroundColor??(c==="barge-in"?o.recordingBackgroundColor??"var(--persona-voice-recording-bg, #ef4444)":u?.backgroundColor??""),b=o.speakingBorderColor??(c==="barge-in"?o.recordingBorderColor??"":u?.borderColor??"");s(a),a.classList.add("persona-voice-speaking"),i.setMicState("speaking"),a.style.backgroundColor=m,a.style.borderColor=b;let S=g||"currentColor";a.style.color=S,t(a,f,S);let I=c==="cancel"?"Stop playback and re-record":c==="barge-in"?"Speak to interrupt":"Agent is speaking";a.setAttribute("aria-label",I),c==="none"&&(a.style.cursor="default"),c==="barge-in"&&a.classList.add("persona-voice-recording")},reset:()=>{let a=i.mic();if(!a)return;s(a),i.setMicState("idle");let o=i.original;o&&(a.style.backgroundColor=o.backgroundColor??"",a.style.color=o.color??"",a.style.borderColor=o.borderColor??"",t(a,o.iconName,o.color||"currentColor"),i.original=null),a.style.cursor="",a.setAttribute("aria-label","Start voice recognition")}}};export{C as BrowserVoiceProvider,$ as KeyedVoiceTranscript,P as RuntypeVoiceProvider,Q as createBestAvailableVoiceProvider,$e as createMicStateStyles,_ as createVoiceProvider,Ue as createVoiceSessionBridge,Oe as isVoiceSupported,xe as wireSessionVoice};
|