@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.
Files changed (42) hide show
  1. package/dist/animations/glyph-cycle.d.cts +1 -1
  2. package/dist/animations/glyph-cycle.d.ts +1 -1
  3. package/dist/animations/{types-C6tFDxKy.d.cts → types-CSmiKRVa.d.cts} +11 -0
  4. package/dist/animations/{types-C6tFDxKy.d.ts → types-CSmiKRVa.d.ts} +11 -0
  5. package/dist/animations/wipe.d.cts +1 -1
  6. package/dist/animations/wipe.d.ts +1 -1
  7. package/dist/chunk-DFBSCFYN.js +1 -0
  8. package/dist/codegen.cjs +4 -4
  9. package/dist/codegen.js +4 -4
  10. package/dist/index.cjs +51 -51
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.cts +238 -3
  13. package/dist/index.d.ts +238 -3
  14. package/dist/index.global.js +37 -37
  15. package/dist/index.global.js.map +1 -1
  16. package/dist/index.js +51 -51
  17. package/dist/index.js.map +1 -1
  18. package/dist/launcher.global.js.map +1 -1
  19. package/dist/markdown-parsers-entry-NVFT3TE6.js +1 -0
  20. package/dist/runtype-tts-entry-HFUV2UF7.js +1 -0
  21. package/dist/session-reconnect-U77QFUR7.js +1 -0
  22. package/dist/smart-dom-reader.d.cts +95 -0
  23. package/dist/smart-dom-reader.d.ts +95 -0
  24. package/dist/theme-editor-preview.cjs +48 -48
  25. package/dist/theme-editor-preview.d.cts +135 -1
  26. package/dist/theme-editor-preview.d.ts +135 -1
  27. package/dist/theme-editor-preview.js +48 -48
  28. package/dist/theme-editor.d.cts +95 -0
  29. package/dist/theme-editor.d.ts +95 -0
  30. package/package.json +5 -3
  31. package/src/client.ts +55 -9
  32. package/src/generated/runtype-openapi-contract.ts +16 -1
  33. package/src/reconnect-wake.test.ts +162 -0
  34. package/src/reconnect.test.ts +430 -0
  35. package/src/session-reconnect.ts +282 -0
  36. package/src/session.ts +408 -5
  37. package/src/types.ts +107 -1
  38. package/src/ui.stream-animation-update.test.ts +99 -0
  39. package/src/ui.ts +71 -1
  40. package/src/utils/constants.ts +3 -1
  41. package/src/utils/morph.test.ts +47 -0
  42. package/src/utils/morph.ts +18 -0
@@ -783,6 +783,7 @@ type RuntypeExecutionStreamEvent = ({
783
783
  };
784
784
  type: "execution_complete";
785
785
  }) | ({
786
+ blockReason?: string;
786
787
  code?: string;
787
788
  completedAt?: string;
788
789
  error: string | {
@@ -1037,6 +1038,7 @@ type RuntypeExecutionStreamEvent = ({
1037
1038
  startedAt?: string;
1038
1039
  subagent?: {
1039
1040
  agentName?: string;
1041
+ parentToolCallId?: string;
1040
1042
  toolName: string;
1041
1043
  };
1042
1044
  timeout?: number;
@@ -1053,12 +1055,15 @@ type RuntypeExecutionStreamEvent = ({
1053
1055
  seq: number;
1054
1056
  type: "approval_complete";
1055
1057
  }) | ({
1058
+ awaitReason?: string;
1056
1059
  awaitedAt?: string;
1060
+ crawlId?: string;
1057
1061
  executionId: string;
1058
1062
  origin?: "webmcp" | "sdk";
1059
1063
  pageOrigin?: string;
1060
1064
  parameters?: Record<string, unknown>;
1061
1065
  seq: number;
1066
+ stepId?: string;
1062
1067
  toolCallId?: string;
1063
1068
  toolId?: string;
1064
1069
  toolName?: string;
@@ -1127,6 +1132,7 @@ type RuntypeFlowSSEEvent = {
1127
1132
  totalTokensUsed?: number;
1128
1133
  type: "flow_complete";
1129
1134
  } | ({
1135
+ blockReason?: string;
1130
1136
  code?: string;
1131
1137
  error: string | {
1132
1138
  code: string;
@@ -1147,13 +1153,18 @@ type RuntypeFlowSSEEvent = {
1147
1153
  type: "flow_error";
1148
1154
  upgradeUrl?: string;
1149
1155
  }) | ({
1156
+ approvalId?: string;
1157
+ awaitReason?: string;
1150
1158
  awaitedAt: string;
1159
+ crawlId?: string;
1151
1160
  executionId?: string;
1152
1161
  flowId: string;
1153
1162
  origin?: "webmcp" | "sdk";
1154
1163
  pageOrigin?: string;
1155
1164
  parameters?: Record<string, unknown>;
1156
1165
  seq?: number;
1166
+ stepId?: string;
1167
+ timeout?: number;
1157
1168
  toolCallId?: string;
1158
1169
  toolId?: string;
1159
1170
  toolName?: string;
@@ -1693,6 +1704,27 @@ type AgentWidgetWebMcpConfig = {
1693
1704
  */
1694
1705
  onConfirm?: WebMcpConfirmHandler;
1695
1706
  };
1707
+ /**
1708
+ * The coordinates needed to resume a durable agent turn after the SSE
1709
+ * connection drops (any resumable, server-persisted execution, e.g. Claude
1710
+ * Managed agents or async/background runs). Held on the session while a
1711
+ * resumable stream is in flight
1712
+ * and surfaced to the host via {@link AgentWidgetConfig.onExecutionState} so it
1713
+ * can persist `{ executionId, lastEventId }` next to its own `conversationId`
1714
+ * for the tab-reload path.
1715
+ *
1716
+ * `conversationId` is intentionally absent: it is host-owned (it lives in the
1717
+ * host's `reconnectStream`/`customFetch` closure; the widget never sees it).
1718
+ */
1719
+ type ResumableHandle = {
1720
+ /** The durable turn to reconnect to (from `agentMetadata.executionId`). */
1721
+ executionId: string;
1722
+ /** Highest SSE `id:` seq applied: the `?after=` reconnect cursor. */
1723
+ lastEventId: string;
1724
+ /** The open assistant message being streamed into, kept open on resume. */
1725
+ assistantMessageId: string;
1726
+ status: 'running';
1727
+ };
1696
1728
  /**
1697
1729
  * Metadata attached to messages created during agent execution.
1698
1730
  */
@@ -1975,6 +2007,22 @@ type AgentWidgetControllerEventMap = {
1975
2007
  approval: AgentWidgetApproval;
1976
2008
  decision: string;
1977
2009
  };
2010
+ /** A durable stream dropped; the widget is about to reconnect. */
2011
+ "stream:paused": {
2012
+ executionId: string;
2013
+ after: string;
2014
+ };
2015
+ /** A reconnect attempt is in flight (`attempt` is 1-based). */
2016
+ "stream:resuming": {
2017
+ executionId: string;
2018
+ after: string;
2019
+ attempt: number;
2020
+ };
2021
+ /** The durable turn resumed and reached its terminal after a reconnect. */
2022
+ "stream:resumed": {
2023
+ executionId: string;
2024
+ after: string;
2025
+ };
1978
2026
  };
1979
2027
  /**
1980
2028
  * Layout for the artifact split / drawer (CSS lengths unless noted).
@@ -3083,6 +3131,10 @@ type AgentWidgetStatusIndicatorConfig = {
3083
3131
  connectingText?: string;
3084
3132
  connectedText?: string;
3085
3133
  errorText?: string;
3134
+ /** Status text while a dropped durable stream is awaiting reconnect. */
3135
+ pausedText?: string;
3136
+ /** Status text while a reconnect attempt is in flight. */
3137
+ resumingText?: string;
3086
3138
  };
3087
3139
  type AgentWidgetVoiceRecognitionConfig = {
3088
3140
  enabled?: boolean;
@@ -5173,6 +5225,65 @@ type AgentWidgetConfig = {
5173
5225
  * ```
5174
5226
  */
5175
5227
  customFetch?: AgentWidgetCustomFetch;
5228
+ /**
5229
+ * Durable-session reconnect transport (host-owned, symmetric to
5230
+ * {@link customFetch}). When a durable agent stream drops mid-turn (any
5231
+ * resumable, server-persisted execution, e.g. Claude Managed agents or
5232
+ * async/background runs), the widget calls this to fetch the read-only
5233
+ * reconnect stream and pipes its body through the normal event pipeline to
5234
+ * resume from where it left off.
5235
+ *
5236
+ * The host closure owns `agentId` / `conversationId` / base URL / auth and
5237
+ * builds the events request, e.g.:
5238
+ *
5239
+ * ```typescript
5240
+ * reconnectStream: ({ executionId, after, signal }) =>
5241
+ * fetch(
5242
+ * `${baseUrl}/v1/agents/${agentId}/executions/${executionId}` +
5243
+ * `/events?conversationId=${conversationId}&after=${after}`,
5244
+ * { headers: { Authorization: `Bearer ${token}`, "X-Persona-Version": ver }, signal }
5245
+ * )
5246
+ * ```
5247
+ *
5248
+ * Resolve with a `text/event-stream` `Response`. Throw or resolve non-ok to
5249
+ * signal "this attempt failed" (the widget backs off and retries, then gives
5250
+ * up after the bounded attempts). Reconnect only ever arms on the durable
5251
+ * lane (streams carrying SSE `id:` lines); without this hook a drop finalizes
5252
+ * exactly as before.
5253
+ */
5254
+ reconnectStream?: (ctx: {
5255
+ executionId: string;
5256
+ after: string;
5257
+ signal: AbortSignal;
5258
+ }) => Promise<Response>;
5259
+ /**
5260
+ * Tuning for the auto-reconnect backoff. Defaults to ~5 attempts over ~30s
5261
+ * (`backoffMs: [1000, 2000, 4000, 8000, 8000]`).
5262
+ */
5263
+ reconnect?: {
5264
+ /** Max reconnect attempts before giving up and finalizing. @default backoffMs.length */
5265
+ maxAttempts?: number;
5266
+ /** Per-attempt delay (ms) before each retry. @default [1000, 2000, 4000, 8000, 8000] */
5267
+ backoffMs?: number[];
5268
+ };
5269
+ /**
5270
+ * Called whenever the durable resume handle changes: created when a durable
5271
+ * turn starts streaming, updated as the cursor advances (throttled), and
5272
+ * `null` when the turn finishes, errors, or is torn down. Persist
5273
+ * `{ executionId, lastEventId }` next to your `conversationId` and pass it
5274
+ * back via {@link resume} on the next mount to survive a tab reload.
5275
+ */
5276
+ onExecutionState?: (handle: ResumableHandle | null) => void;
5277
+ /**
5278
+ * Resume a durable turn on boot (tab-reload path). When present alongside
5279
+ * {@link reconnectStream}, the widget enters `resuming` immediately on mount
5280
+ * and reconnects from `after`, replaying everything past the cursor into the
5281
+ * restored conversation.
5282
+ */
5283
+ resume?: {
5284
+ executionId: string;
5285
+ after: string;
5286
+ };
5176
5287
  /**
5177
5288
  * Custom SSE event parser for non-standard streaming response formats.
5178
5289
  *
@@ -5715,9 +5826,27 @@ type AgentWidgetEvent = {
5715
5826
  } | {
5716
5827
  type: "status";
5717
5828
  status: "connecting" | "connected" | "error" | "idle";
5829
+ /**
5830
+ * Set on the `idle` emitted from a graceful execution terminal
5831
+ * (`execution_complete`). Distinguishes a real finish from the plain
5832
+ * `idle` the dispatch wrappers emit in their `finally` on a dropped
5833
+ * connection. The durable-reconnect drop detection keys off this.
5834
+ */
5835
+ terminal?: boolean;
5718
5836
  } | {
5719
5837
  type: "error";
5720
5838
  error: Error;
5839
+ }
5840
+ /**
5841
+ * Durable-session reconnect cursor. Carries the SSE `id:` line (the durable
5842
+ * row seq) of a fully-parsed frame so the session can track `lastEventId`
5843
+ * and resume from `?after=<id>` after a drop. Only emitted on the durable
5844
+ * lane (any resumable execution that stamps `id:` lines, e.g. Claude Managed
5845
+ * agents or async/background runs).
5846
+ */
5847
+ | {
5848
+ type: "cursor";
5849
+ id: string;
5721
5850
  } | {
5722
5851
  type: "artifact_start";
5723
5852
  id: string;
@@ -5738,7 +5867,7 @@ type AgentWidgetEvent = {
5738
5867
  id: string;
5739
5868
  };
5740
5869
 
5741
- type AgentWidgetSessionStatus = "idle" | "connecting" | "connected" | "error";
5870
+ type AgentWidgetSessionStatus = "idle" | "connecting" | "connected" | "error" | "paused" | "resuming";
5742
5871
 
5743
5872
  /**
5744
5873
  * Feedback UI components for CSAT and NPS collection
@@ -5795,6 +5924,11 @@ type Controller = {
5795
5924
  clearChat: () => void;
5796
5925
  setMessage: (message: string) => boolean;
5797
5926
  submitMessage: (message?: string) => boolean;
5927
+ /**
5928
+ * Manually retry a dropped durable stream (e.g. from a "Reconnect" button).
5929
+ * No-op unless a resumable durable turn dropped and `reconnectStream` is set.
5930
+ */
5931
+ reconnect: () => void;
5798
5932
  startVoiceRecognition: () => boolean;
5799
5933
  stopVoiceRecognition: () => boolean;
5800
5934
  /**
@@ -783,6 +783,7 @@ type RuntypeExecutionStreamEvent = ({
783
783
  };
784
784
  type: "execution_complete";
785
785
  }) | ({
786
+ blockReason?: string;
786
787
  code?: string;
787
788
  completedAt?: string;
788
789
  error: string | {
@@ -1037,6 +1038,7 @@ type RuntypeExecutionStreamEvent = ({
1037
1038
  startedAt?: string;
1038
1039
  subagent?: {
1039
1040
  agentName?: string;
1041
+ parentToolCallId?: string;
1040
1042
  toolName: string;
1041
1043
  };
1042
1044
  timeout?: number;
@@ -1053,12 +1055,15 @@ type RuntypeExecutionStreamEvent = ({
1053
1055
  seq: number;
1054
1056
  type: "approval_complete";
1055
1057
  }) | ({
1058
+ awaitReason?: string;
1056
1059
  awaitedAt?: string;
1060
+ crawlId?: string;
1057
1061
  executionId: string;
1058
1062
  origin?: "webmcp" | "sdk";
1059
1063
  pageOrigin?: string;
1060
1064
  parameters?: Record<string, unknown>;
1061
1065
  seq: number;
1066
+ stepId?: string;
1062
1067
  toolCallId?: string;
1063
1068
  toolId?: string;
1064
1069
  toolName?: string;
@@ -1127,6 +1132,7 @@ type RuntypeFlowSSEEvent = {
1127
1132
  totalTokensUsed?: number;
1128
1133
  type: "flow_complete";
1129
1134
  } | ({
1135
+ blockReason?: string;
1130
1136
  code?: string;
1131
1137
  error: string | {
1132
1138
  code: string;
@@ -1147,13 +1153,18 @@ type RuntypeFlowSSEEvent = {
1147
1153
  type: "flow_error";
1148
1154
  upgradeUrl?: string;
1149
1155
  }) | ({
1156
+ approvalId?: string;
1157
+ awaitReason?: string;
1150
1158
  awaitedAt: string;
1159
+ crawlId?: string;
1151
1160
  executionId?: string;
1152
1161
  flowId: string;
1153
1162
  origin?: "webmcp" | "sdk";
1154
1163
  pageOrigin?: string;
1155
1164
  parameters?: Record<string, unknown>;
1156
1165
  seq?: number;
1166
+ stepId?: string;
1167
+ timeout?: number;
1157
1168
  toolCallId?: string;
1158
1169
  toolId?: string;
1159
1170
  toolName?: string;
@@ -1693,6 +1704,27 @@ type AgentWidgetWebMcpConfig = {
1693
1704
  */
1694
1705
  onConfirm?: WebMcpConfirmHandler;
1695
1706
  };
1707
+ /**
1708
+ * The coordinates needed to resume a durable agent turn after the SSE
1709
+ * connection drops (any resumable, server-persisted execution, e.g. Claude
1710
+ * Managed agents or async/background runs). Held on the session while a
1711
+ * resumable stream is in flight
1712
+ * and surfaced to the host via {@link AgentWidgetConfig.onExecutionState} so it
1713
+ * can persist `{ executionId, lastEventId }` next to its own `conversationId`
1714
+ * for the tab-reload path.
1715
+ *
1716
+ * `conversationId` is intentionally absent: it is host-owned (it lives in the
1717
+ * host's `reconnectStream`/`customFetch` closure; the widget never sees it).
1718
+ */
1719
+ type ResumableHandle = {
1720
+ /** The durable turn to reconnect to (from `agentMetadata.executionId`). */
1721
+ executionId: string;
1722
+ /** Highest SSE `id:` seq applied: the `?after=` reconnect cursor. */
1723
+ lastEventId: string;
1724
+ /** The open assistant message being streamed into, kept open on resume. */
1725
+ assistantMessageId: string;
1726
+ status: 'running';
1727
+ };
1696
1728
  /**
1697
1729
  * Metadata attached to messages created during agent execution.
1698
1730
  */
@@ -1975,6 +2007,22 @@ type AgentWidgetControllerEventMap = {
1975
2007
  approval: AgentWidgetApproval;
1976
2008
  decision: string;
1977
2009
  };
2010
+ /** A durable stream dropped; the widget is about to reconnect. */
2011
+ "stream:paused": {
2012
+ executionId: string;
2013
+ after: string;
2014
+ };
2015
+ /** A reconnect attempt is in flight (`attempt` is 1-based). */
2016
+ "stream:resuming": {
2017
+ executionId: string;
2018
+ after: string;
2019
+ attempt: number;
2020
+ };
2021
+ /** The durable turn resumed and reached its terminal after a reconnect. */
2022
+ "stream:resumed": {
2023
+ executionId: string;
2024
+ after: string;
2025
+ };
1978
2026
  };
1979
2027
  /**
1980
2028
  * Layout for the artifact split / drawer (CSS lengths unless noted).
@@ -3083,6 +3131,10 @@ type AgentWidgetStatusIndicatorConfig = {
3083
3131
  connectingText?: string;
3084
3132
  connectedText?: string;
3085
3133
  errorText?: string;
3134
+ /** Status text while a dropped durable stream is awaiting reconnect. */
3135
+ pausedText?: string;
3136
+ /** Status text while a reconnect attempt is in flight. */
3137
+ resumingText?: string;
3086
3138
  };
3087
3139
  type AgentWidgetVoiceRecognitionConfig = {
3088
3140
  enabled?: boolean;
@@ -5173,6 +5225,65 @@ type AgentWidgetConfig = {
5173
5225
  * ```
5174
5226
  */
5175
5227
  customFetch?: AgentWidgetCustomFetch;
5228
+ /**
5229
+ * Durable-session reconnect transport (host-owned, symmetric to
5230
+ * {@link customFetch}). When a durable agent stream drops mid-turn (any
5231
+ * resumable, server-persisted execution, e.g. Claude Managed agents or
5232
+ * async/background runs), the widget calls this to fetch the read-only
5233
+ * reconnect stream and pipes its body through the normal event pipeline to
5234
+ * resume from where it left off.
5235
+ *
5236
+ * The host closure owns `agentId` / `conversationId` / base URL / auth and
5237
+ * builds the events request, e.g.:
5238
+ *
5239
+ * ```typescript
5240
+ * reconnectStream: ({ executionId, after, signal }) =>
5241
+ * fetch(
5242
+ * `${baseUrl}/v1/agents/${agentId}/executions/${executionId}` +
5243
+ * `/events?conversationId=${conversationId}&after=${after}`,
5244
+ * { headers: { Authorization: `Bearer ${token}`, "X-Persona-Version": ver }, signal }
5245
+ * )
5246
+ * ```
5247
+ *
5248
+ * Resolve with a `text/event-stream` `Response`. Throw or resolve non-ok to
5249
+ * signal "this attempt failed" (the widget backs off and retries, then gives
5250
+ * up after the bounded attempts). Reconnect only ever arms on the durable
5251
+ * lane (streams carrying SSE `id:` lines); without this hook a drop finalizes
5252
+ * exactly as before.
5253
+ */
5254
+ reconnectStream?: (ctx: {
5255
+ executionId: string;
5256
+ after: string;
5257
+ signal: AbortSignal;
5258
+ }) => Promise<Response>;
5259
+ /**
5260
+ * Tuning for the auto-reconnect backoff. Defaults to ~5 attempts over ~30s
5261
+ * (`backoffMs: [1000, 2000, 4000, 8000, 8000]`).
5262
+ */
5263
+ reconnect?: {
5264
+ /** Max reconnect attempts before giving up and finalizing. @default backoffMs.length */
5265
+ maxAttempts?: number;
5266
+ /** Per-attempt delay (ms) before each retry. @default [1000, 2000, 4000, 8000, 8000] */
5267
+ backoffMs?: number[];
5268
+ };
5269
+ /**
5270
+ * Called whenever the durable resume handle changes: created when a durable
5271
+ * turn starts streaming, updated as the cursor advances (throttled), and
5272
+ * `null` when the turn finishes, errors, or is torn down. Persist
5273
+ * `{ executionId, lastEventId }` next to your `conversationId` and pass it
5274
+ * back via {@link resume} on the next mount to survive a tab reload.
5275
+ */
5276
+ onExecutionState?: (handle: ResumableHandle | null) => void;
5277
+ /**
5278
+ * Resume a durable turn on boot (tab-reload path). When present alongside
5279
+ * {@link reconnectStream}, the widget enters `resuming` immediately on mount
5280
+ * and reconnects from `after`, replaying everything past the cursor into the
5281
+ * restored conversation.
5282
+ */
5283
+ resume?: {
5284
+ executionId: string;
5285
+ after: string;
5286
+ };
5176
5287
  /**
5177
5288
  * Custom SSE event parser for non-standard streaming response formats.
5178
5289
  *
@@ -5715,9 +5826,27 @@ type AgentWidgetEvent = {
5715
5826
  } | {
5716
5827
  type: "status";
5717
5828
  status: "connecting" | "connected" | "error" | "idle";
5829
+ /**
5830
+ * Set on the `idle` emitted from a graceful execution terminal
5831
+ * (`execution_complete`). Distinguishes a real finish from the plain
5832
+ * `idle` the dispatch wrappers emit in their `finally` on a dropped
5833
+ * connection. The durable-reconnect drop detection keys off this.
5834
+ */
5835
+ terminal?: boolean;
5718
5836
  } | {
5719
5837
  type: "error";
5720
5838
  error: Error;
5839
+ }
5840
+ /**
5841
+ * Durable-session reconnect cursor. Carries the SSE `id:` line (the durable
5842
+ * row seq) of a fully-parsed frame so the session can track `lastEventId`
5843
+ * and resume from `?after=<id>` after a drop. Only emitted on the durable
5844
+ * lane (any resumable execution that stamps `id:` lines, e.g. Claude Managed
5845
+ * agents or async/background runs).
5846
+ */
5847
+ | {
5848
+ type: "cursor";
5849
+ id: string;
5721
5850
  } | {
5722
5851
  type: "artifact_start";
5723
5852
  id: string;
@@ -5738,7 +5867,7 @@ type AgentWidgetEvent = {
5738
5867
  id: string;
5739
5868
  };
5740
5869
 
5741
- type AgentWidgetSessionStatus = "idle" | "connecting" | "connected" | "error";
5870
+ type AgentWidgetSessionStatus = "idle" | "connecting" | "connected" | "error" | "paused" | "resuming";
5742
5871
 
5743
5872
  /**
5744
5873
  * Feedback UI components for CSAT and NPS collection
@@ -5795,6 +5924,11 @@ type Controller = {
5795
5924
  clearChat: () => void;
5796
5925
  setMessage: (message: string) => boolean;
5797
5926
  submitMessage: (message?: string) => boolean;
5927
+ /**
5928
+ * Manually retry a dropped durable stream (e.g. from a "Reconnect" button).
5929
+ * No-op unless a resumable durable turn dropped and `reconnectStream` is set.
5930
+ */
5931
+ reconnect: () => void;
5798
5932
  startVoiceRecognition: () => boolean;
5799
5933
  stopVoiceRecognition: () => boolean;
5800
5934
  /**