@runtypelabs/persona 4.5.0 → 4.6.1
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/animations/glyph-cycle.d.cts +1 -1
- package/dist/animations/glyph-cycle.d.ts +1 -1
- package/dist/animations/{types-C6tFDxKy.d.cts → types-CSmiKRVa.d.cts} +11 -0
- package/dist/animations/{types-C6tFDxKy.d.ts → types-CSmiKRVa.d.ts} +11 -0
- package/dist/animations/wipe.d.cts +1 -1
- package/dist/animations/wipe.d.ts +1 -1
- package/dist/chunk-DFBSCFYN.js +1 -0
- package/dist/codegen.cjs +4 -4
- package/dist/codegen.js +4 -4
- package/dist/index.cjs +51 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +238 -3
- package/dist/index.d.ts +238 -3
- package/dist/index.global.js +37 -37
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +51 -51
- package/dist/index.js.map +1 -1
- package/dist/launcher.global.js.map +1 -1
- package/dist/markdown-parsers-entry-NVFT3TE6.js +1 -0
- package/dist/runtype-tts-entry-HFUV2UF7.js +1 -0
- package/dist/session-reconnect-U77QFUR7.js +1 -0
- package/dist/smart-dom-reader.d.cts +95 -0
- package/dist/smart-dom-reader.d.ts +95 -0
- package/dist/theme-editor-preview.cjs +48 -48
- package/dist/theme-editor-preview.d.cts +135 -1
- package/dist/theme-editor-preview.d.ts +135 -1
- package/dist/theme-editor-preview.js +48 -48
- package/dist/theme-editor.d.cts +95 -0
- package/dist/theme-editor.d.ts +95 -0
- package/package.json +5 -3
- package/src/client.ts +55 -9
- package/src/generated/runtype-openapi-contract.ts +16 -1
- package/src/reconnect-wake.test.ts +162 -0
- package/src/reconnect.test.ts +430 -0
- package/src/session-reconnect.ts +282 -0
- package/src/session.ts +408 -5
- package/src/types.ts +107 -1
- package/src/ui.stream-animation-update.test.ts +99 -0
- package/src/ui.ts +71 -1
- package/src/utils/constants.ts +3 -1
- package/src/utils/morph.test.ts +47 -0
- package/src/utils/morph.ts +18 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Marked as o}from"marked";import f from"dompurify";export{f as DOMPurify,o as Marked};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as c}from"./chunk-DFBSCFYN.js";function g(o){return o.replace(/\/+$/,"")}var m=class{constructor(e){this.opts=e;this.id="runtype-tts";this.supportsPause=!0;this.player=null;this.playerPromise=null;this.generation=0}ensurePlayer(){var e,t;return(t=this.playerPromise)!=null?t:this.playerPromise=Promise.resolve(this.opts.createPlaybackEngine?this.opts.createPlaybackEngine():new c(24e3,{prebufferMs:(e=this.opts.prebufferMs)!=null?e:200})).then(r=>this.player=r)}speak(e,t){let r=++this.generation;this.run(r,e,t)}async run(e,t,r){var i,a,p,h;try{let n=await this.ensurePlayer();if(e!==this.generation)return;n.flush(),n.resume(),n.onStarted(()=>{var s;e===this.generation&&((s=r.onStart)==null||s.call(r))}),n.onFinished(()=>{var s;e===this.generation&&((s=r.onEnd)==null||s.call(r))});let u=`${g(this.opts.host)}/v1/agents/${encodeURIComponent(this.opts.agentId)}/speak`,y=await fetch(u,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.opts.clientToken}`},body:JSON.stringify({text:t.text,voice:(i=t.voice)!=null?i:this.opts.voice,format:"pcm"})});if(e!==this.generation)return;if(!y.ok||!y.body)throw new Error(await S(y));let v=y.body.getReader();for(;;){let{done:s,value:d}=await v.read();if(e!==this.generation){await v.cancel().catch(()=>{});return}if(s)break;d&&d.byteLength>0&&n.enqueue(d)}n.markStreamEnd()}catch(n){if(e!==this.generation)return;let u=n instanceof Error?n:new Error(String(n));(p=(a=this.opts).onError)==null||p.call(a,u),(h=r.onError)==null||h.call(r,u)}}pause(){var e;(e=this.player)==null||e.pause()}resume(){var e;(e=this.player)==null||e.resume()}stop(){var e;this.generation++,(e=this.player)==null||e.flush()}destroy(){var e;this.generation++,(e=this.player)==null||e.destroy(),this.player=null,this.playerPromise=null}};async function S(o){var e,t;try{let r=await o.json();return r.detail?`${(e=r.error)!=null?e:`Runtype TTS ${o.status}`}: ${r.detail}`:(t=r.error)!=null?t:`Runtype TTS request failed (${o.status})`}catch{return`Runtype TTS request failed (${o.status})`}}var f=class{constructor(e,t,r={}){this.primary=e;this.fallback=t;this.options=r;this.id="fallback";this.active=e}get supportsPause(){return this.active.supportsPause}speak(e,t){this.active=this.primary;let r=!1;this.primary.speak(e,{onStart:()=>{var i;r=!0,(i=t.onStart)==null||i.call(t)},onEnd:()=>{var i;return(i=t.onEnd)==null?void 0:i.call(t)},onError:i=>{var a,p,h;if(r){(a=t.onError)==null||a.call(t,i);return}(h=(p=this.options).onFallback)==null||h.call(p,i),this.active=this.fallback,this.fallback.speak(e,t)}})}pause(){this.active.pause()}resume(){this.active.resume()}stop(){this.active.stop()}destroy(){var e,t,r,i;(t=(e=this.primary).destroy)==null||t.call(e),(i=(r=this.fallback).destroy)==null||i.call(r)}};export{f as FallbackSpeechEngine,m as RuntypeSpeechEngine};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var k=[1e3,2e3,4e3,8e3,8e3];function T(e){let t=0,r=null,i=null,g=!1,b=()=>{if(i&&(clearTimeout(i),i=null),r){let n=r;r=null,n()}},v=()=>{let n=e.getStatus();n!=="resuming"&&n!=="paused"||b()},p=()=>{typeof document!="undefined"&&document.visibilityState==="hidden"||v()},R=()=>{v()},C=()=>{g||(typeof document!="undefined"&&document.addEventListener("visibilitychange",p),typeof window!="undefined"&&window.addEventListener("online",R),g=!0)},m=()=>{g&&(typeof document!="undefined"&&document.removeEventListener("visibilitychange",p),typeof window!="undefined"&&window.removeEventListener("online",R),g=!1)},M=n=>new Promise(s=>{r=s,i=setTimeout(()=>{i=null,r=null,s()},n)}),E=()=>{var d;let n=e.getResumable();e.clearResumable(),e.setReconnecting(!1),t=0,m(),e.setAbortController(null);let s=!1;for(let c of e.getMessages())c.streaming&&(c.streaming=!1,s=!0);let l=e.buildErrorContent("Connection lost and the response could not be resumed.");l?e.appendMessage({id:`reconnect-failed-${(d=n==null?void 0:n.executionId)!=null?d:e.nextSequence()}`,role:"assistant",content:l,createdAt:new Date().toISOString(),streaming:!1,sequence:e.nextSequence()}):s&&e.notifyMessagesChanged(),e.setStreaming(!1),e.setStatus("idle"),e.onError(new Error("Durable session reconnect failed."))},x=async()=>{var d,c,y,S,w,A;let n=(c=(d=e.config.reconnect)==null?void 0:d.backoffMs)!=null?c:k,s=(S=(y=e.config.reconnect)==null?void 0:y.maxAttempts)!=null?S:n.length,l=e.config.reconnectStream;if(!l){e.setReconnecting(!1);return}for(;e.getResumable()&&t<s;){t+=1,e.setStatus("resuming");let o=e.getResumable(),I=o.lastEventId,u=new AbortController;e.setAbortController(u),e.emitReconnect({phase:"resuming",handle:o,attempt:t});let f=null;try{let a=await l({executionId:o.executionId,after:o.lastEventId,signal:u.signal});a&&a.ok&&a.body&&(f=a.body)}catch{f=null}if(u.signal.aborted)return;if(f){let a=(w=e.getMessages().find(W=>W.id===o.assistantMessageId))==null?void 0:w.content,L=typeof a=="string"?a:"";try{await e.resumeConnect(f,o.assistantMessageId,L)}catch{}if(u.signal.aborted)return;if(!e.getResumable()){e.setReconnecting(!1),t=0,m(),e.emitReconnect({phase:"resumed",handle:o});return}e.getResumable().lastEventId!==I&&(t=0)}if(e.getResumable()&&t<s&&(e.setStatus("paused"),await M((A=n[Math.min(t-1,n.length-1)])!=null?A:1e3),u.signal.aborted))return}e.getResumable()&&E()};return{begin(){t=0,C(),x()},teardown(){i&&(clearTimeout(i),i=null),r=null,t=0,m()},wake:b}}export{T as createReconnectController};
|
|
@@ -1052,6 +1052,7 @@ type RuntypeExecutionStreamEvent = ({
|
|
|
1052
1052
|
};
|
|
1053
1053
|
type: "execution_complete";
|
|
1054
1054
|
}) | ({
|
|
1055
|
+
blockReason?: string;
|
|
1055
1056
|
code?: string;
|
|
1056
1057
|
completedAt?: string;
|
|
1057
1058
|
error: string | {
|
|
@@ -1306,6 +1307,7 @@ type RuntypeExecutionStreamEvent = ({
|
|
|
1306
1307
|
startedAt?: string;
|
|
1307
1308
|
subagent?: {
|
|
1308
1309
|
agentName?: string;
|
|
1310
|
+
parentToolCallId?: string;
|
|
1309
1311
|
toolName: string;
|
|
1310
1312
|
};
|
|
1311
1313
|
timeout?: number;
|
|
@@ -1322,12 +1324,15 @@ type RuntypeExecutionStreamEvent = ({
|
|
|
1322
1324
|
seq: number;
|
|
1323
1325
|
type: "approval_complete";
|
|
1324
1326
|
}) | ({
|
|
1327
|
+
awaitReason?: string;
|
|
1325
1328
|
awaitedAt?: string;
|
|
1329
|
+
crawlId?: string;
|
|
1326
1330
|
executionId: string;
|
|
1327
1331
|
origin?: "webmcp" | "sdk";
|
|
1328
1332
|
pageOrigin?: string;
|
|
1329
1333
|
parameters?: Record<string, unknown>;
|
|
1330
1334
|
seq: number;
|
|
1335
|
+
stepId?: string;
|
|
1331
1336
|
toolCallId?: string;
|
|
1332
1337
|
toolId?: string;
|
|
1333
1338
|
toolName?: string;
|
|
@@ -1396,6 +1401,7 @@ type RuntypeFlowSSEEvent = {
|
|
|
1396
1401
|
totalTokensUsed?: number;
|
|
1397
1402
|
type: "flow_complete";
|
|
1398
1403
|
} | ({
|
|
1404
|
+
blockReason?: string;
|
|
1399
1405
|
code?: string;
|
|
1400
1406
|
error: string | {
|
|
1401
1407
|
code: string;
|
|
@@ -1416,13 +1422,18 @@ type RuntypeFlowSSEEvent = {
|
|
|
1416
1422
|
type: "flow_error";
|
|
1417
1423
|
upgradeUrl?: string;
|
|
1418
1424
|
}) | ({
|
|
1425
|
+
approvalId?: string;
|
|
1426
|
+
awaitReason?: string;
|
|
1419
1427
|
awaitedAt: string;
|
|
1428
|
+
crawlId?: string;
|
|
1420
1429
|
executionId?: string;
|
|
1421
1430
|
flowId: string;
|
|
1422
1431
|
origin?: "webmcp" | "sdk";
|
|
1423
1432
|
pageOrigin?: string;
|
|
1424
1433
|
parameters?: Record<string, unknown>;
|
|
1425
1434
|
seq?: number;
|
|
1435
|
+
stepId?: string;
|
|
1436
|
+
timeout?: number;
|
|
1426
1437
|
toolCallId?: string;
|
|
1427
1438
|
toolId?: string;
|
|
1428
1439
|
toolName?: string;
|
|
@@ -1962,6 +1973,27 @@ type AgentWidgetWebMcpConfig = {
|
|
|
1962
1973
|
*/
|
|
1963
1974
|
onConfirm?: WebMcpConfirmHandler;
|
|
1964
1975
|
};
|
|
1976
|
+
/**
|
|
1977
|
+
* The coordinates needed to resume a durable agent turn after the SSE
|
|
1978
|
+
* connection drops (any resumable, server-persisted execution, e.g. Claude
|
|
1979
|
+
* Managed agents or async/background runs). Held on the session while a
|
|
1980
|
+
* resumable stream is in flight
|
|
1981
|
+
* and surfaced to the host via {@link AgentWidgetConfig.onExecutionState} so it
|
|
1982
|
+
* can persist `{ executionId, lastEventId }` next to its own `conversationId`
|
|
1983
|
+
* for the tab-reload path.
|
|
1984
|
+
*
|
|
1985
|
+
* `conversationId` is intentionally absent: it is host-owned (it lives in the
|
|
1986
|
+
* host's `reconnectStream`/`customFetch` closure; the widget never sees it).
|
|
1987
|
+
*/
|
|
1988
|
+
type ResumableHandle = {
|
|
1989
|
+
/** The durable turn to reconnect to (from `agentMetadata.executionId`). */
|
|
1990
|
+
executionId: string;
|
|
1991
|
+
/** Highest SSE `id:` seq applied: the `?after=` reconnect cursor. */
|
|
1992
|
+
lastEventId: string;
|
|
1993
|
+
/** The open assistant message being streamed into, kept open on resume. */
|
|
1994
|
+
assistantMessageId: string;
|
|
1995
|
+
status: 'running';
|
|
1996
|
+
};
|
|
1965
1997
|
/**
|
|
1966
1998
|
* Metadata attached to messages created during agent execution.
|
|
1967
1999
|
*/
|
|
@@ -3278,6 +3310,10 @@ type AgentWidgetStatusIndicatorConfig = {
|
|
|
3278
3310
|
connectingText?: string;
|
|
3279
3311
|
connectedText?: string;
|
|
3280
3312
|
errorText?: string;
|
|
3313
|
+
/** Status text while a dropped durable stream is awaiting reconnect. */
|
|
3314
|
+
pausedText?: string;
|
|
3315
|
+
/** Status text while a reconnect attempt is in flight. */
|
|
3316
|
+
resumingText?: string;
|
|
3281
3317
|
};
|
|
3282
3318
|
type AgentWidgetVoiceRecognitionConfig = {
|
|
3283
3319
|
enabled?: boolean;
|
|
@@ -5359,6 +5395,65 @@ type AgentWidgetConfig = {
|
|
|
5359
5395
|
* ```
|
|
5360
5396
|
*/
|
|
5361
5397
|
customFetch?: AgentWidgetCustomFetch;
|
|
5398
|
+
/**
|
|
5399
|
+
* Durable-session reconnect transport (host-owned, symmetric to
|
|
5400
|
+
* {@link customFetch}). When a durable agent stream drops mid-turn (any
|
|
5401
|
+
* resumable, server-persisted execution, e.g. Claude Managed agents or
|
|
5402
|
+
* async/background runs), the widget calls this to fetch the read-only
|
|
5403
|
+
* reconnect stream and pipes its body through the normal event pipeline to
|
|
5404
|
+
* resume from where it left off.
|
|
5405
|
+
*
|
|
5406
|
+
* The host closure owns `agentId` / `conversationId` / base URL / auth and
|
|
5407
|
+
* builds the events request, e.g.:
|
|
5408
|
+
*
|
|
5409
|
+
* ```typescript
|
|
5410
|
+
* reconnectStream: ({ executionId, after, signal }) =>
|
|
5411
|
+
* fetch(
|
|
5412
|
+
* `${baseUrl}/v1/agents/${agentId}/executions/${executionId}` +
|
|
5413
|
+
* `/events?conversationId=${conversationId}&after=${after}`,
|
|
5414
|
+
* { headers: { Authorization: `Bearer ${token}`, "X-Persona-Version": ver }, signal }
|
|
5415
|
+
* )
|
|
5416
|
+
* ```
|
|
5417
|
+
*
|
|
5418
|
+
* Resolve with a `text/event-stream` `Response`. Throw or resolve non-ok to
|
|
5419
|
+
* signal "this attempt failed" (the widget backs off and retries, then gives
|
|
5420
|
+
* up after the bounded attempts). Reconnect only ever arms on the durable
|
|
5421
|
+
* lane (streams carrying SSE `id:` lines); without this hook a drop finalizes
|
|
5422
|
+
* exactly as before.
|
|
5423
|
+
*/
|
|
5424
|
+
reconnectStream?: (ctx: {
|
|
5425
|
+
executionId: string;
|
|
5426
|
+
after: string;
|
|
5427
|
+
signal: AbortSignal;
|
|
5428
|
+
}) => Promise<Response>;
|
|
5429
|
+
/**
|
|
5430
|
+
* Tuning for the auto-reconnect backoff. Defaults to ~5 attempts over ~30s
|
|
5431
|
+
* (`backoffMs: [1000, 2000, 4000, 8000, 8000]`).
|
|
5432
|
+
*/
|
|
5433
|
+
reconnect?: {
|
|
5434
|
+
/** Max reconnect attempts before giving up and finalizing. @default backoffMs.length */
|
|
5435
|
+
maxAttempts?: number;
|
|
5436
|
+
/** Per-attempt delay (ms) before each retry. @default [1000, 2000, 4000, 8000, 8000] */
|
|
5437
|
+
backoffMs?: number[];
|
|
5438
|
+
};
|
|
5439
|
+
/**
|
|
5440
|
+
* Called whenever the durable resume handle changes: created when a durable
|
|
5441
|
+
* turn starts streaming, updated as the cursor advances (throttled), and
|
|
5442
|
+
* `null` when the turn finishes, errors, or is torn down. Persist
|
|
5443
|
+
* `{ executionId, lastEventId }` next to your `conversationId` and pass it
|
|
5444
|
+
* back via {@link resume} on the next mount to survive a tab reload.
|
|
5445
|
+
*/
|
|
5446
|
+
onExecutionState?: (handle: ResumableHandle | null) => void;
|
|
5447
|
+
/**
|
|
5448
|
+
* Resume a durable turn on boot (tab-reload path). When present alongside
|
|
5449
|
+
* {@link reconnectStream}, the widget enters `resuming` immediately on mount
|
|
5450
|
+
* and reconnects from `after`, replaying everything past the cursor into the
|
|
5451
|
+
* restored conversation.
|
|
5452
|
+
*/
|
|
5453
|
+
resume?: {
|
|
5454
|
+
executionId: string;
|
|
5455
|
+
after: string;
|
|
5456
|
+
};
|
|
5362
5457
|
/**
|
|
5363
5458
|
* Custom SSE event parser for non-standard streaming response formats.
|
|
5364
5459
|
*
|
|
@@ -1052,6 +1052,7 @@ type RuntypeExecutionStreamEvent = ({
|
|
|
1052
1052
|
};
|
|
1053
1053
|
type: "execution_complete";
|
|
1054
1054
|
}) | ({
|
|
1055
|
+
blockReason?: string;
|
|
1055
1056
|
code?: string;
|
|
1056
1057
|
completedAt?: string;
|
|
1057
1058
|
error: string | {
|
|
@@ -1306,6 +1307,7 @@ type RuntypeExecutionStreamEvent = ({
|
|
|
1306
1307
|
startedAt?: string;
|
|
1307
1308
|
subagent?: {
|
|
1308
1309
|
agentName?: string;
|
|
1310
|
+
parentToolCallId?: string;
|
|
1309
1311
|
toolName: string;
|
|
1310
1312
|
};
|
|
1311
1313
|
timeout?: number;
|
|
@@ -1322,12 +1324,15 @@ type RuntypeExecutionStreamEvent = ({
|
|
|
1322
1324
|
seq: number;
|
|
1323
1325
|
type: "approval_complete";
|
|
1324
1326
|
}) | ({
|
|
1327
|
+
awaitReason?: string;
|
|
1325
1328
|
awaitedAt?: string;
|
|
1329
|
+
crawlId?: string;
|
|
1326
1330
|
executionId: string;
|
|
1327
1331
|
origin?: "webmcp" | "sdk";
|
|
1328
1332
|
pageOrigin?: string;
|
|
1329
1333
|
parameters?: Record<string, unknown>;
|
|
1330
1334
|
seq: number;
|
|
1335
|
+
stepId?: string;
|
|
1331
1336
|
toolCallId?: string;
|
|
1332
1337
|
toolId?: string;
|
|
1333
1338
|
toolName?: string;
|
|
@@ -1396,6 +1401,7 @@ type RuntypeFlowSSEEvent = {
|
|
|
1396
1401
|
totalTokensUsed?: number;
|
|
1397
1402
|
type: "flow_complete";
|
|
1398
1403
|
} | ({
|
|
1404
|
+
blockReason?: string;
|
|
1399
1405
|
code?: string;
|
|
1400
1406
|
error: string | {
|
|
1401
1407
|
code: string;
|
|
@@ -1416,13 +1422,18 @@ type RuntypeFlowSSEEvent = {
|
|
|
1416
1422
|
type: "flow_error";
|
|
1417
1423
|
upgradeUrl?: string;
|
|
1418
1424
|
}) | ({
|
|
1425
|
+
approvalId?: string;
|
|
1426
|
+
awaitReason?: string;
|
|
1419
1427
|
awaitedAt: string;
|
|
1428
|
+
crawlId?: string;
|
|
1420
1429
|
executionId?: string;
|
|
1421
1430
|
flowId: string;
|
|
1422
1431
|
origin?: "webmcp" | "sdk";
|
|
1423
1432
|
pageOrigin?: string;
|
|
1424
1433
|
parameters?: Record<string, unknown>;
|
|
1425
1434
|
seq?: number;
|
|
1435
|
+
stepId?: string;
|
|
1436
|
+
timeout?: number;
|
|
1426
1437
|
toolCallId?: string;
|
|
1427
1438
|
toolId?: string;
|
|
1428
1439
|
toolName?: string;
|
|
@@ -1962,6 +1973,27 @@ type AgentWidgetWebMcpConfig = {
|
|
|
1962
1973
|
*/
|
|
1963
1974
|
onConfirm?: WebMcpConfirmHandler;
|
|
1964
1975
|
};
|
|
1976
|
+
/**
|
|
1977
|
+
* The coordinates needed to resume a durable agent turn after the SSE
|
|
1978
|
+
* connection drops (any resumable, server-persisted execution, e.g. Claude
|
|
1979
|
+
* Managed agents or async/background runs). Held on the session while a
|
|
1980
|
+
* resumable stream is in flight
|
|
1981
|
+
* and surfaced to the host via {@link AgentWidgetConfig.onExecutionState} so it
|
|
1982
|
+
* can persist `{ executionId, lastEventId }` next to its own `conversationId`
|
|
1983
|
+
* for the tab-reload path.
|
|
1984
|
+
*
|
|
1985
|
+
* `conversationId` is intentionally absent: it is host-owned (it lives in the
|
|
1986
|
+
* host's `reconnectStream`/`customFetch` closure; the widget never sees it).
|
|
1987
|
+
*/
|
|
1988
|
+
type ResumableHandle = {
|
|
1989
|
+
/** The durable turn to reconnect to (from `agentMetadata.executionId`). */
|
|
1990
|
+
executionId: string;
|
|
1991
|
+
/** Highest SSE `id:` seq applied: the `?after=` reconnect cursor. */
|
|
1992
|
+
lastEventId: string;
|
|
1993
|
+
/** The open assistant message being streamed into, kept open on resume. */
|
|
1994
|
+
assistantMessageId: string;
|
|
1995
|
+
status: 'running';
|
|
1996
|
+
};
|
|
1965
1997
|
/**
|
|
1966
1998
|
* Metadata attached to messages created during agent execution.
|
|
1967
1999
|
*/
|
|
@@ -3278,6 +3310,10 @@ type AgentWidgetStatusIndicatorConfig = {
|
|
|
3278
3310
|
connectingText?: string;
|
|
3279
3311
|
connectedText?: string;
|
|
3280
3312
|
errorText?: string;
|
|
3313
|
+
/** Status text while a dropped durable stream is awaiting reconnect. */
|
|
3314
|
+
pausedText?: string;
|
|
3315
|
+
/** Status text while a reconnect attempt is in flight. */
|
|
3316
|
+
resumingText?: string;
|
|
3281
3317
|
};
|
|
3282
3318
|
type AgentWidgetVoiceRecognitionConfig = {
|
|
3283
3319
|
enabled?: boolean;
|
|
@@ -5359,6 +5395,65 @@ type AgentWidgetConfig = {
|
|
|
5359
5395
|
* ```
|
|
5360
5396
|
*/
|
|
5361
5397
|
customFetch?: AgentWidgetCustomFetch;
|
|
5398
|
+
/**
|
|
5399
|
+
* Durable-session reconnect transport (host-owned, symmetric to
|
|
5400
|
+
* {@link customFetch}). When a durable agent stream drops mid-turn (any
|
|
5401
|
+
* resumable, server-persisted execution, e.g. Claude Managed agents or
|
|
5402
|
+
* async/background runs), the widget calls this to fetch the read-only
|
|
5403
|
+
* reconnect stream and pipes its body through the normal event pipeline to
|
|
5404
|
+
* resume from where it left off.
|
|
5405
|
+
*
|
|
5406
|
+
* The host closure owns `agentId` / `conversationId` / base URL / auth and
|
|
5407
|
+
* builds the events request, e.g.:
|
|
5408
|
+
*
|
|
5409
|
+
* ```typescript
|
|
5410
|
+
* reconnectStream: ({ executionId, after, signal }) =>
|
|
5411
|
+
* fetch(
|
|
5412
|
+
* `${baseUrl}/v1/agents/${agentId}/executions/${executionId}` +
|
|
5413
|
+
* `/events?conversationId=${conversationId}&after=${after}`,
|
|
5414
|
+
* { headers: { Authorization: `Bearer ${token}`, "X-Persona-Version": ver }, signal }
|
|
5415
|
+
* )
|
|
5416
|
+
* ```
|
|
5417
|
+
*
|
|
5418
|
+
* Resolve with a `text/event-stream` `Response`. Throw or resolve non-ok to
|
|
5419
|
+
* signal "this attempt failed" (the widget backs off and retries, then gives
|
|
5420
|
+
* up after the bounded attempts). Reconnect only ever arms on the durable
|
|
5421
|
+
* lane (streams carrying SSE `id:` lines); without this hook a drop finalizes
|
|
5422
|
+
* exactly as before.
|
|
5423
|
+
*/
|
|
5424
|
+
reconnectStream?: (ctx: {
|
|
5425
|
+
executionId: string;
|
|
5426
|
+
after: string;
|
|
5427
|
+
signal: AbortSignal;
|
|
5428
|
+
}) => Promise<Response>;
|
|
5429
|
+
/**
|
|
5430
|
+
* Tuning for the auto-reconnect backoff. Defaults to ~5 attempts over ~30s
|
|
5431
|
+
* (`backoffMs: [1000, 2000, 4000, 8000, 8000]`).
|
|
5432
|
+
*/
|
|
5433
|
+
reconnect?: {
|
|
5434
|
+
/** Max reconnect attempts before giving up and finalizing. @default backoffMs.length */
|
|
5435
|
+
maxAttempts?: number;
|
|
5436
|
+
/** Per-attempt delay (ms) before each retry. @default [1000, 2000, 4000, 8000, 8000] */
|
|
5437
|
+
backoffMs?: number[];
|
|
5438
|
+
};
|
|
5439
|
+
/**
|
|
5440
|
+
* Called whenever the durable resume handle changes: created when a durable
|
|
5441
|
+
* turn starts streaming, updated as the cursor advances (throttled), and
|
|
5442
|
+
* `null` when the turn finishes, errors, or is torn down. Persist
|
|
5443
|
+
* `{ executionId, lastEventId }` next to your `conversationId` and pass it
|
|
5444
|
+
* back via {@link resume} on the next mount to survive a tab reload.
|
|
5445
|
+
*/
|
|
5446
|
+
onExecutionState?: (handle: ResumableHandle | null) => void;
|
|
5447
|
+
/**
|
|
5448
|
+
* Resume a durable turn on boot (tab-reload path). When present alongside
|
|
5449
|
+
* {@link reconnectStream}, the widget enters `resuming` immediately on mount
|
|
5450
|
+
* and reconnects from `after`, replaying everything past the cursor into the
|
|
5451
|
+
* restored conversation.
|
|
5452
|
+
*/
|
|
5453
|
+
resume?: {
|
|
5454
|
+
executionId: string;
|
|
5455
|
+
after: string;
|
|
5456
|
+
};
|
|
5362
5457
|
/**
|
|
5363
5458
|
* Custom SSE event parser for non-standard streaming response formats.
|
|
5364
5459
|
*
|