@genesislcap/ai-assistant 15.60.0 → 15.62.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.
Files changed (134) hide show
  1. package/dist/ai-assistant.api.json +18231 -11171
  2. package/dist/ai-assistant.d.ts +1235 -9
  3. package/dist/chat-driver.cjs +658 -50
  4. package/dist/chat-driver.cjs.map +4 -4
  5. package/dist/chat-driver.mjs +657 -50
  6. package/dist/chat-driver.mjs.map +4 -4
  7. package/dist/custom-elements.json +4419 -377
  8. package/dist/dts/autopilot/autopilot-driver.d.ts +278 -0
  9. package/dist/dts/autopilot/autopilot-driver.d.ts.map +1 -0
  10. package/dist/dts/autopilot/autopilot-session.d.ts +163 -0
  11. package/dist/dts/autopilot/autopilot-session.d.ts.map +1 -0
  12. package/dist/dts/autopilot/autopilot-tools.d.ts +15 -0
  13. package/dist/dts/autopilot/autopilot-tools.d.ts.map +1 -0
  14. package/dist/dts/autopilot/decision-message.d.ts +62 -0
  15. package/dist/dts/autopilot/decision-message.d.ts.map +1 -0
  16. package/dist/dts/autopilot/hand-back/hand-back.controller.d.ts +69 -0
  17. package/dist/dts/autopilot/hand-back/hand-back.controller.d.ts.map +1 -0
  18. package/dist/dts/autopilot/hand-back/hand-back.d.ts +22 -0
  19. package/dist/dts/autopilot/hand-back/hand-back.d.ts.map +1 -0
  20. package/dist/dts/autopilot/index.d.ts +4 -0
  21. package/dist/dts/autopilot/index.d.ts.map +1 -0
  22. package/dist/dts/channel/ai-activity-bus.d.ts.map +1 -1
  23. package/dist/dts/channel/ai-activity-channel.d.ts +17 -0
  24. package/dist/dts/channel/ai-activity-channel.d.ts.map +1 -1
  25. package/dist/dts/channel/autopilot-needs-user.d.ts +8 -0
  26. package/dist/dts/channel/autopilot-needs-user.d.ts.map +1 -0
  27. package/dist/dts/components/agent-picker/agent-picker.constants.d.ts +10 -0
  28. package/dist/dts/components/agent-picker/agent-picker.constants.d.ts.map +1 -1
  29. package/dist/dts/components/agent-picker/agent-picker.d.ts +4 -0
  30. package/dist/dts/components/agent-picker/agent-picker.d.ts.map +1 -1
  31. package/dist/dts/components/agent-picker/agent-picker.template.d.ts.map +1 -1
  32. package/dist/dts/components/ai-driver/ai-driver.d.ts +34 -1
  33. package/dist/dts/components/ai-driver/ai-driver.d.ts.map +1 -1
  34. package/dist/dts/components/ai-driver/base-driver-decorator.d.ts +3 -1
  35. package/dist/dts/components/ai-driver/base-driver-decorator.d.ts.map +1 -1
  36. package/dist/dts/components/chat-bubble/chat-bubble.d.ts +21 -0
  37. package/dist/dts/components/chat-bubble/chat-bubble.d.ts.map +1 -1
  38. package/dist/dts/components/chat-bubble/chat-bubble.styles.d.ts.map +1 -1
  39. package/dist/dts/components/chat-bubble/chat-bubble.template.d.ts.map +1 -1
  40. package/dist/dts/components/chat-driver/chat-driver.d.ts +5 -1
  41. package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
  42. package/dist/dts/components/chat-driver/interaction-controller.d.ts +27 -3
  43. package/dist/dts/components/chat-driver/interaction-controller.d.ts.map +1 -1
  44. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.d.ts +10 -2
  45. package/dist/dts/components/chat-interaction-wrapper/chat-interaction-wrapper.d.ts.map +1 -1
  46. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +9 -1
  47. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
  48. package/dist/dts/config/config.d.ts +183 -0
  49. package/dist/dts/config/config.d.ts.map +1 -1
  50. package/dist/dts/config/define-stateful-agent.d.ts +31 -1
  51. package/dist/dts/config/define-stateful-agent.d.ts.map +1 -1
  52. package/dist/dts/index.d.ts +7 -3
  53. package/dist/dts/index.d.ts.map +1 -1
  54. package/dist/dts/main/main.d.ts +128 -5
  55. package/dist/dts/main/main.d.ts.map +1 -1
  56. package/dist/dts/main/main.styles.d.ts.map +1 -1
  57. package/dist/dts/main/main.template.d.ts +2 -2
  58. package/dist/dts/main/main.template.d.ts.map +1 -1
  59. package/dist/dts/react.d.ts +10 -0
  60. package/dist/dts/state/debug-event-log.d.ts +1 -1
  61. package/dist/dts/state/debug-event-log.d.ts.map +1 -1
  62. package/dist/dts/state/decision-surface.d.ts +46 -0
  63. package/dist/dts/state/decision-surface.d.ts.map +1 -0
  64. package/dist/dts/state/interaction-context.d.ts +21 -1
  65. package/dist/dts/state/interaction-context.d.ts.map +1 -1
  66. package/dist/dts/state/interaction-registry.d.ts +63 -0
  67. package/dist/dts/state/interaction-registry.d.ts.map +1 -0
  68. package/dist/dts/state/persistence/session-persister.d.ts.map +1 -1
  69. package/dist/dts/state/persistence/session-snapshot.d.ts +21 -0
  70. package/dist/dts/state/persistence/session-snapshot.d.ts.map +1 -1
  71. package/dist/dts/state/run-steps.d.ts +66 -0
  72. package/dist/dts/state/run-steps.d.ts.map +1 -0
  73. package/dist/dts/types/ai-chat-widget.d.ts +7 -1
  74. package/dist/dts/types/ai-chat-widget.d.ts.map +1 -1
  75. package/dist/dts/types/interaction-context.d.ts +66 -1
  76. package/dist/dts/types/interaction-context.d.ts.map +1 -1
  77. package/dist/dts/types/interaction-interceptor.d.ts +60 -2
  78. package/dist/dts/types/interaction-interceptor.d.ts.map +1 -1
  79. package/dist/dts/types/interaction-surface.d.ts +195 -0
  80. package/dist/dts/types/interaction-surface.d.ts.map +1 -0
  81. package/dist/dts/utils/context-tokens.d.ts +6 -0
  82. package/dist/dts/utils/context-tokens.d.ts.map +1 -1
  83. package/dist/dts/utils/delegated-message.d.ts +13 -0
  84. package/dist/dts/utils/delegated-message.d.ts.map +1 -1
  85. package/dist/dts/utils/history-transform.d.ts.map +1 -1
  86. package/dist/dts/utils/preserved-user-messages.d.ts +21 -0
  87. package/dist/dts/utils/preserved-user-messages.d.ts.map +1 -0
  88. package/dist/esm/autopilot/autopilot-driver.js +906 -0
  89. package/dist/esm/autopilot/autopilot-session.js +449 -0
  90. package/dist/esm/autopilot/autopilot-tools.js +68 -0
  91. package/dist/esm/autopilot/decision-message.js +206 -0
  92. package/dist/esm/autopilot/hand-back/hand-back.controller.js +47 -0
  93. package/dist/esm/autopilot/hand-back/hand-back.js +129 -0
  94. package/dist/esm/autopilot/index.js +4 -0
  95. package/dist/esm/channel/ai-activity-bus.js +7 -0
  96. package/dist/esm/channel/autopilot-needs-user.js +26 -0
  97. package/dist/esm/components/agent-picker/agent-picker.constants.js +10 -0
  98. package/dist/esm/components/agent-picker/agent-picker.js +11 -1
  99. package/dist/esm/components/agent-picker/agent-picker.template.js +2 -4
  100. package/dist/esm/components/ai-driver/ai-driver.js +2 -0
  101. package/dist/esm/components/ai-driver/base-driver-decorator.js +8 -0
  102. package/dist/esm/components/chat-bubble/chat-bubble.js +45 -0
  103. package/dist/esm/components/chat-bubble/chat-bubble.styles.js +26 -0
  104. package/dist/esm/components/chat-bubble/chat-bubble.template.js +13 -0
  105. package/dist/esm/components/chat-driver/chat-driver.js +53 -18
  106. package/dist/esm/components/chat-driver/interaction-controller.js +297 -12
  107. package/dist/esm/components/chat-interaction-wrapper/chat-interaction-wrapper.js +16 -2
  108. package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +28 -11
  109. package/dist/esm/config/define-stateful-agent.js +34 -29
  110. package/dist/esm/index.js +3 -0
  111. package/dist/esm/main/main.js +334 -15
  112. package/dist/esm/main/main.styles.js +126 -0
  113. package/dist/esm/main/main.template.js +116 -11
  114. package/dist/esm/state/debug-event-log.js +28 -1
  115. package/dist/esm/state/decision-surface.js +209 -0
  116. package/dist/esm/state/interaction-context.js +89 -1
  117. package/dist/esm/state/interaction-registry.js +33 -0
  118. package/dist/esm/state/persistence/session-persister.js +23 -11
  119. package/dist/esm/state/persistence/session-snapshot.js +1 -1
  120. package/dist/esm/state/run-steps.js +77 -0
  121. package/dist/esm/types/interaction-surface.js +1 -0
  122. package/dist/esm/utils/context-tokens.js +23 -9
  123. package/dist/esm/utils/delegated-message.js +15 -0
  124. package/dist/esm/utils/history-transform.js +18 -7
  125. package/dist/esm/utils/preserved-user-messages.js +31 -0
  126. package/dist/react.cjs +7 -0
  127. package/dist/react.mjs +6 -0
  128. package/docs/styling.md +1 -1
  129. package/package.json +17 -17
  130. package/sandbox/README.md +38 -2
  131. package/sandbox/autopilot.ts +358 -0
  132. package/sandbox/controls.ts +24 -1
  133. package/sandbox/fixtures.ts +2 -0
  134. package/sandbox/sandbox.ts +188 -1
@@ -25,6 +25,7 @@ import type { CondensePolicy } from '@genesislcap/foundation-ai';
25
25
  import { Container } from '@genesislcap/web-core';
26
26
  import { ElementStyles } from '@genesislcap/web-core';
27
27
  import { GenesisElement } from '@genesislcap/web-core';
28
+ import { InteractionEdit } from '@genesislcap/foundation-ai';
28
29
  import type { InteractionRequestOptions } from '@genesislcap/foundation-ai';
29
30
  import type { InteractionResult } from '@genesislcap/foundation-ai';
30
31
  import { InterfaceSymbol } from '@microsoft/fast-foundation';
@@ -186,6 +187,23 @@ export declare interface AgenticActivityEvents {
186
187
  'chat-popout': undefined;
187
188
  /** Fired when the user clicks the collapse button — moves assistant from layout back to bubble. State lives in the session store, not in this event. */
188
189
  'chat-popin': undefined;
190
+ /**
191
+ * Whether something waits on the person in a session while its autopilot is available
192
+ * (GENC-1660 §4.10): an interaction it handed back, or the turn-level hand-back. The collapsed
193
+ * assistant shows a badge while it is true, since under "Build it for me" the chat is likely out
194
+ * of view. Fired on change; read the current value with `autopilotNeedsUser`.
195
+ */
196
+ 'autopilot-needs-user': {
197
+ sessionKey: string;
198
+ needsUser: boolean;
199
+ };
200
+ /**
201
+ * The person opened the collapsed assistant from its "needs you" badge: the assistant for
202
+ * `sessionKey` (any, when absent) brings what waits on them into view.
203
+ */
204
+ 'autopilot-show-waiting': {
205
+ sessionKey?: string;
206
+ };
189
207
  /**
190
208
  * Fired immediately before the tool loop begins running for the current turn — after the busy
191
209
  * flag is set and the user message (if any) has been appended, but before the first
@@ -388,6 +406,10 @@ export declare class AgentPicker extends GenesisElement {
388
406
  pinnedAgentName: string | null;
389
407
  /** When true, rows show a neutral dot instead of the per-agent brand tint. */
390
408
  disablePinColours: boolean;
409
+ /** The orchestration row's name, from `chatConfig.picker.orchestrationMenuLabel` (resolved by the host). */
410
+ orchestrationLabel: string;
411
+ /** The orchestration row's hint, from `chatConfig.picker.orchestrationDescription` (resolved by the host). */
412
+ orchestrationDescription: string;
391
413
  /** Top-level agents that opted in to manual selection. */
392
414
  get selectableAgents(): AgentConfig[];
393
415
  /** Whether the picker should render at all. */
@@ -687,6 +709,12 @@ export declare type AiChatInteraction<TData = unknown, TResult = unknown> = {
687
709
  * Display-only: the widget shows it, and it is never sent to a model.
688
710
  */
689
711
  outcome?: unknown;
712
+ /**
713
+ * The edits a claimant (an autopilot, say) made to the widget before it was settled, in
714
+ * order, whoever settled it. Absent when there were none. Lets the resolved view mark what
715
+ * was changed for the person rather than by them; display-only.
716
+ */
717
+ edits?: readonly InteractionEdit[];
690
718
  };
691
719
 
692
720
  export declare class AiChatMarkdown extends GenesisElement {
@@ -956,6 +984,23 @@ export declare interface AiDriver extends EventTarget {
956
984
  * @beta
957
985
  */
958
986
  getFlowOwner?(): string | null;
987
+ /**
988
+ * The checkpoint of the long action in flight, or the one a reload cut and nothing has taken over
989
+ * yet (GENC-1660 §4.12), for the host to save with the session.
990
+ *
991
+ * Optional, so a third-party driver need not implement it; every shipped driver does.
992
+ *
993
+ * @beta
994
+ */
995
+ getInteractionCheckpoint?(): PersistedInteractionCheckpoint | undefined;
996
+ /**
997
+ * Bring back a checkpoint saved with the session. Its interaction was cut by the reload, so it
998
+ * waits for the first request of the same widget type, which takes it over if the registration's
999
+ * `sameWork` agrees; it is dropped when the flow ends.
1000
+ *
1001
+ * @beta
1002
+ */
1003
+ restoreInteractionCheckpoint?(saved: PersistedInteractionCheckpoint | undefined): void;
959
1004
  /**
960
1005
  * Install an {@link InteractionInterceptor}: told about every interaction this driver opens,
961
1006
  * with its live context, and able to claim it and answer it instead of the person (GENC-1660).
@@ -1140,11 +1185,27 @@ export declare interface AiDriverEventMap {
1140
1185
  'provider-changed': CustomEvent<{
1141
1186
  name: string;
1142
1187
  }>;
1188
+ /**
1189
+ * An interaction settled, by whatever route — a widget, a controller's `ctx.resolve`, a claimant,
1190
+ * a timeout (GENC-1660). Detail: its id, and `answeredBy` when someone answered it (absent for a
1191
+ * timeout or a stop).
1192
+ */
1193
+ 'interaction-settled': CustomEvent<{
1194
+ interactionId: string;
1195
+ answeredBy?: string;
1196
+ }>;
1143
1197
  /** Spend was recorded against an already-resolved interaction. */
1144
1198
  'external-cost-recorded': CustomEvent<{
1145
1199
  interactionId: string;
1146
1200
  costUsd: number;
1147
1201
  }>;
1202
+ /**
1203
+ * A long action saved its checkpoint (GENC-1660 §4.12). No message changed, so the host saves the
1204
+ * session on this rather than waiting for the transcript to move.
1205
+ */
1206
+ 'checkpoint-saved': CustomEvent<{
1207
+ interactionId: string;
1208
+ }>;
1148
1209
  /** The active agent changed. Detail: the new agent, or `undefined` after a release. */
1149
1210
  'agent-changed': CustomEvent<AgentConfig | undefined>;
1150
1211
  /** A stateful agent released its flow. Detail: the released agent. */
@@ -1361,6 +1422,467 @@ export declare interface AssistantAppSettingsToggle {
1361
1422
  */
1362
1423
  export declare const assistantSettingsSectionTitleStyles: ElementStyles;
1363
1424
 
1425
+ /**
1426
+ * The holder id the autopilot claims interactions as.
1427
+ *
1428
+ * @beta
1429
+ */
1430
+ export declare const AUTOPILOT_CLAIMANT = "autopilot";
1431
+
1432
+ /**
1433
+ * The tag of the turn-level hand-back widget (GENC-1660 §4.10): what the autopilot shows when a
1434
+ * working turn ends needing the person, and there is no widget to hand over.
1435
+ *
1436
+ * @beta
1437
+ */
1438
+ export declare const AUTOPILOT_HAND_BACK = "ai-autopilot-hand-back";
1439
+
1440
+ /**
1441
+ * An {@link AutopilotConfig} bound to its agent's live state — what `AgentConfig.autopilot` holds
1442
+ * (GENC-1660). `state()` is `undefined` while the agent is not active.
1443
+ *
1444
+ * @beta
1445
+ */
1446
+ export declare interface AutopilotBinding {
1447
+ readonly config: AutopilotConfig<unknown>;
1448
+ state(): unknown;
1449
+ }
1450
+
1451
+ /**
1452
+ * What a working agent's tool handlers get as `context.capabilities.autopilot` (GENC-1660): the
1453
+ * mode of their own flow, and a way to set it — e.g. after the user picks "Build it for me".
1454
+ * Absent when the flow has no autopilot, so a handler feature-detects and does not offer the choice.
1455
+ *
1456
+ * @beta
1457
+ */
1458
+ export declare interface AutopilotCapability {
1459
+ readonly mode: AutopilotMode;
1460
+ setMode(mode: 'paused' | 'running'): void;
1461
+ }
1462
+
1463
+ /**
1464
+ * An autopilot definition, generic over the state `S` of the agent it serves (GENC-1660). An
1465
+ * ordinary agent definition run the other way round: it is sent each decision the agent asks of
1466
+ * the user, and answers it, or hands it back.
1467
+ *
1468
+ * `S` appears only as a resolver parameter, so a definition whose resolvers take `unknown` (a
1469
+ * shared const) is assignable to every agent's `AutopilotConfig<S>`. Keep no mutable state in a
1470
+ * shared definition or its closures: one is used by every agent that references it.
1471
+ *
1472
+ * @beta
1473
+ */
1474
+ export declare interface AutopilotConfig<S = unknown> {
1475
+ /**
1476
+ * Whether the autopilot can be switched on right now, given the agent's live state — e.g. "the
1477
+ * brief is approved", for an autopilot grounded in a brief. Default: whenever the agent's flow is
1478
+ * active.
1479
+ */
1480
+ availableWhen?: (ctx: {
1481
+ state: S;
1482
+ }) => boolean;
1483
+ /** Per widget component name; unlisted widgets are `'human-first'`. */
1484
+ widgetPolicy?: Readonly<Record<string, AutopilotWidgetPolicy>>;
1485
+ /** The autopilot's grounding. Keep it byte-stable for the run, so its cache prefix holds. */
1486
+ systemPrompt: string | ((ctx: SystemPromptContext & {
1487
+ state: S;
1488
+ }) => string | Promise<string>);
1489
+ /** What is true now (step guidance, a project snapshot). Rebuilt every call, never stored. */
1490
+ tailContext?: string | ((ctx: SystemPromptContext & {
1491
+ state: S;
1492
+ }) => string | Promise<string>);
1493
+ /** Which registered provider it uses. Defaults to the registry default. */
1494
+ provider?: string | ((ctx: SystemPromptContext & {
1495
+ state: S;
1496
+ }) => string | Promise<string>);
1497
+ /** Read-only tools it may use to check a fact, beside the three the platform adds. */
1498
+ tools?: {
1499
+ definitions: ChatToolDefinition[];
1500
+ handlers: ChatToolHandlers;
1501
+ };
1502
+ /**
1503
+ * How the working agent is told a decision was made for the user, e.g. "Decided on the user's
1504
+ * behalf, from their brief". Must not name the autopilot.
1505
+ */
1506
+ decisionFraming?: string;
1507
+ /**
1508
+ * How the working agent is told that the user finished a widget the autopilot had already
1509
+ * changed, e.g. "Changed on the user's behalf from their brief, before the user answered; the user
1510
+ * then finished it, confirming the changes". Must say the changes came first and that finishing
1511
+ * confirmed them; must not name the autopilot. Defaults to the platform's wording.
1512
+ */
1513
+ editFraming?: string;
1514
+ /** Overrides for the UI's words. */
1515
+ copy?: Partial<AutopilotCopy>;
1516
+ /** Model calls per decision before it is handed back; `> 0`, or the default is used. Default 6. */
1517
+ maxIterationsPerDecision?: number;
1518
+ /**
1519
+ * Written answers (`reply`) allowed per step before `reply` is withdrawn, so refining a proposal
1520
+ * cannot loop with the working agent re-proposing it. `>= 0` (0 never offers one), or the
1521
+ * default is used. Default 2. Enforced by the platform, not asked of the model: past the limit it
1522
+ * can only accept or hand back.
1523
+ */
1524
+ maxRefinements?: number;
1525
+ /**
1526
+ * What counts as one step for {@link AutopilotConfig.maxRefinements}, e.g. the machine's phase
1527
+ * and substate. The count resets when it changes. Default: the widget's component name, which is
1528
+ * coarser but never unsafe.
1529
+ */
1530
+ stepKey?: (ctx: {
1531
+ state: S;
1532
+ }) => string;
1533
+ /**
1534
+ * What one decision may cost, in USD, before it is handed back; `> 0`. Unset (or not `> 0`): no
1535
+ * cap (the session's budget wall still stops everything). Set it from measured decision costs,
1536
+ * e.g. 3x the p95.
1537
+ */
1538
+ maxDecisionCostUsd?: number;
1539
+ /**
1540
+ * How long the autopilot's work on a claimed interaction may go quiet before it is handed back,
1541
+ * in ms; `> 0`, or the default is used. Quiet means either no ready surface and no heartbeat
1542
+ * (`ctx.notify()`), or a decision of its own still running with no model call landing and no
1543
+ * heartbeat — a stalled model call, which has no timeout of its own. A decision handed back this
1544
+ * way is stopped. Must outlast the slowest honest wait, such as a compile. Default 10 minutes.
1545
+ */
1546
+ watchdogMs?: number;
1547
+ /**
1548
+ * How large the autopilot's own history may grow, in characters, before it is rebuilt from a
1549
+ * short-form digest of what the person saw (recent entries verbatim, older answered widgets as
1550
+ * one line, and only the newest entries that fit in half of this). `> 0`, or the default is used.
1551
+ * A safety net, not expected to fire on an ordinary run. Default 120,000 (roughly 30k tokens).
1552
+ */
1553
+ historyBudgetChars?: number;
1554
+ }
1555
+
1556
+ /**
1557
+ * The words the autopilot UI shows (GENC-1660). Supplied by the autopilot's config, because the
1558
+ * host is platform code and must not carry any one app's wording; every field has a default.
1559
+ *
1560
+ * @beta
1561
+ */
1562
+ export declare interface AutopilotCopy {
1563
+ /** The slim bar's status while running, e.g. "Building from your plan…". */
1564
+ running: string;
1565
+ /** While paused by the user. */
1566
+ paused: string;
1567
+ /** While the autopilot waits on one answer it handed back. */
1568
+ selfPaused: string;
1569
+ /** In front of a hand-back reason, in the widget's banner, e.g. "I need your input on this one:". */
1570
+ handBackLead: string;
1571
+ /** The toggle pill's label and its accessible name, e.g. "Autopilot". */
1572
+ toggleLabel: string;
1573
+ /**
1574
+ * What the autopilot does, in a sentence: in the toggle's tooltip, after what clicking does.
1575
+ * The place to name what it decides from, e.g. "…from your plan".
1576
+ */
1577
+ description: string;
1578
+ /**
1579
+ * What clicking the toggle does while it is on, at the head of its tooltip, e.g. "Pause
1580
+ * autopilot"; also the turn-level hand-back's pause button. The toggle's accessible name is
1581
+ * always `toggleLabel`: it is a pressed/not-pressed toggle, so its name does not change with it.
1582
+ */
1583
+ pauseLabel: string;
1584
+ /** What clicking the toggle does while it is off, at the head of its tooltip, e.g. "Resume autopilot". */
1585
+ resumeLabel: string;
1586
+ /**
1587
+ * What clicking the toggle does while the autopilot waits on a question it handed back, at the
1588
+ * head of its tooltip, e.g. "Resume autopilot and force it to decide this one": resuming forces it
1589
+ * to take the question back and decide it, with no way to hand it back again, so say so.
1590
+ */
1591
+ resumeDecideLabel: string;
1592
+ /** The hand-back banner's button that keeps the autopilot paused after the answer. */
1593
+ keepPausedLabel: string;
1594
+ /** The tooltip on the autopilot mark, beside anything done in autopilot mode. */
1595
+ markLabel: string;
1596
+ /**
1597
+ * The turn-level hand-back's message when the working agent stopped at its call limit, e.g. "I've
1598
+ * done a lot in one go, so I've stopped to check in. Shall I carry on?".
1599
+ */
1600
+ checkInMessage: string;
1601
+ /** The turn-level hand-back's button that carries the working agent on, e.g. "Carry on". */
1602
+ carryOnLabel: string;
1603
+ /** The turn-level hand-back's message when the conversation has grown too long to carry on. */
1604
+ tooLongMessage: string;
1605
+ /** The turn-level hand-back's button that compacts the conversation, then carries on. */
1606
+ compactLabel: string;
1607
+ /** The turn-level hand-back's message when the working agent's turn failed. */
1608
+ failedMessage: string;
1609
+ /** The turn-level hand-back's button that runs the failed step again, e.g. "Try again". */
1610
+ tryAgainLabel: string;
1611
+ /** The turn-level hand-back's button that sends the person's own written answer, e.g. "Send". */
1612
+ sendLabel: string;
1613
+ /** The hand-back reason when a decision passed its spend cap (`maxDecisionCostUsd`). */
1614
+ budgetReason: string;
1615
+ /** The hand-back reason when a decision failed with an error. */
1616
+ errorReason: string;
1617
+ /** The hand-back reason when a decision ended without acting or handing back. */
1618
+ noDecisionReason: string;
1619
+ /** The hand-back reason when the watchdog found the autopilot's work gone quiet (`watchdogMs`). */
1620
+ watchdogReason: string;
1621
+ }
1622
+
1623
+ /**
1624
+ * Autopilot (GENC-1660): a driver decorator that answers the questions a working agent asks the
1625
+ * user, on their behalf, grounded in the agent's autopilot config (for bootstrap, the brief).
1626
+ *
1627
+ * Neither side calls the other. The working agent asks as it always does; this driver claims the
1628
+ * interactions its policy allows, while it is running for that flow, and answers each in one short
1629
+ * turn on the flow's `AutopilotSession`. It plugs in only through the generic extension points
1630
+ * — an interaction interceptor, a handler capability and the flow lifecycle — so the core knows
1631
+ * nothing about it, and it wraps any `AiDriver`.
1632
+ *
1633
+ * @beta
1634
+ */
1635
+ export declare class AutopilotDriver extends BaseDriverDecorator implements AutopilotHost {
1636
+ private readonly agents;
1637
+ private readonly providerRegistry;
1638
+ private readonly sessionKey;
1639
+ private readonly listeners;
1640
+ private readonly sessions;
1641
+ /** The flow the mode applies to: set when it is first switched, cleared when that flow ends. */
1642
+ private onFor;
1643
+ private mode;
1644
+ private pauseState?;
1645
+ private held?;
1646
+ /** Written answers given on the current step, for the refinement limit. */
1647
+ private refinements?;
1648
+ /** The watchdog's next check, while a claimed interaction is pending. */
1649
+ private watchdog?;
1650
+ /** What sessions that have ended did, kept for the debug log. */
1651
+ private readonly endedDiagnostics;
1652
+ /** Written answers sent in a row; see `MAX_CONSECUTIVE_REPLIES`. */
1653
+ private consecutiveReplies;
1654
+ /** Set while the turn-level hand-back waits on the person. */
1655
+ private turnHandBack?;
1656
+ /** A mode restored with the session, waiting for its flow to become the owner again. */
1657
+ private restored?;
1658
+ /**
1659
+ * Bumped on every pause and resume, and when its sessions end. A written answer is sent only if
1660
+ * none came between asking for it and its landing: one started before a pause is stale after it,
1661
+ * even once resumed.
1662
+ */
1663
+ private generation;
1664
+ /** Working turns this driver has started that have not ended yet; see `working`. */
1665
+ private turnsInFlight;
1666
+ /** Written questions being answered right now; see `working`. */
1667
+ private answersInFlight;
1668
+ constructor(inner: AiDriver, options: AutopilotDriverOptions);
1669
+ get state(): AutopilotHostState;
1670
+ get copy(): AutopilotCopy;
1671
+ subscribe(listener: () => void): () => void;
1672
+ pause(): void;
1673
+ resume(): void;
1674
+ stop(): void;
1675
+ /** The mode to save with the session, while it is set for the current flow. */
1676
+ getPersistedMode(): PersistedAutopilotMode | undefined;
1677
+ /**
1678
+ * Bring back a saved mode. It applies once its flow is the owner again — at once if it already
1679
+ * is, otherwise when the restored flow re-activates. Restoring starts nothing: the autopilot acts
1680
+ * only on live events, such as the working agent's own resume asking a question (§4.10, S3).
1681
+ */
1682
+ restorePersistedMode(saved: PersistedAutopilotMode | undefined): void;
1683
+ private adoptRestored;
1684
+ keepPaused(interactionId: string): void;
1685
+ sendMessage(input: string, attachments?: ChatAttachment[], options?: SendMessageOptions): Promise<ChatDriverResult>;
1686
+ continueFromHistory(transientPrimer?: ChatMessage[], options?: ContinueFromHistoryOptions): Promise<ChatDriverResult>;
1687
+ resumeRestoredFlow(resumeNote?: string, agent?: AgentConfig): Promise<ChatDriverResult | undefined>;
1688
+ /**
1689
+ * Run a working turn, counted for `working` from the moment it is asked for: the wrapped driver
1690
+ * may not say it is busy until some way in. The caller notifies once it has acted on the end.
1691
+ */
1692
+ private whileWorking;
1693
+ /**
1694
+ * Act on how a working turn ended, without holding up whoever awaited it, then notify: idle
1695
+ * unless that started something (an answer, a hand-back), which it does before this returns.
1696
+ */
1697
+ private afterTurn;
1698
+ private onTurnEnded;
1699
+ /** {@link AutopilotDriver.answer}, from a caller that does not wait for it. */
1700
+ private answerInBackground;
1701
+ /**
1702
+ * Answer a written question the working agent ended its turn on, and send the answer on the
1703
+ * user's behalf, with what writing it cost booked on that message (§4.2).
1704
+ *
1705
+ * Sent only if the question still stands when the answer lands: no pause or resume since it was
1706
+ * asked (Pause stops it, and the question is the person's to answer by typing), the flow still
1707
+ * running, the working agent idle, and the question still the last thing it said. Otherwise the
1708
+ * answer goes nowhere — not sent, not counted, not recorded as acted — and its cost is recorded as
1709
+ * dropped, as it is whenever no reply is sent to carry it.
1710
+ */
1711
+ private answer;
1712
+ /**
1713
+ * Spend on a written answer that no reply carries into the session total — it was handed back,
1714
+ * stopped, or went stale — recorded so it is never lost silently.
1715
+ */
1716
+ private dropCost;
1717
+ /** The working agent's last visible words, when its turn ended on them. */
1718
+ private lastQuestion;
1719
+ /**
1720
+ * The turn-level hand-back (§4.10): a working turn ended needing the person and there is no
1721
+ * widget to hand over, so the autopilot shows its own, `userOnly`, and acts on the choice.
1722
+ */
1723
+ private presentHandBack;
1724
+ /**
1725
+ * The inner driver's diagnostics, then everything the autopilot did (§4.8): diagnostics compose
1726
+ * down the decorator stack, so they reach the downloaded and the persisted debug log through the
1727
+ * host's existing external-diagnostics channel.
1728
+ */
1729
+ getExternalDiagnostics(): ReadonlyArray<DiagnosticEntry>;
1730
+ /**
1731
+ * Close every session, keeping what it did for the debug log. An answer one was still writing is
1732
+ * stale from here: it is never sent, and its cost is recorded as dropped when it lands.
1733
+ */
1734
+ private endSessions;
1735
+ dispose(): Promise<void>;
1736
+ private onInteractionOpened;
1737
+ /** Run one decision on the flow's session, and act on how it ended. */
1738
+ private decide;
1739
+ /** The step a decision belongs to, for the refinement limit (§4.4). */
1740
+ private stepKey;
1741
+ /** Whether a written answer is still allowed on this step. The count resets when the step changes. */
1742
+ private mayRefine;
1743
+ private countRefinement;
1744
+ /** Written answers allowed per step: the config's when it is a whole number `>= 0`. */
1745
+ private refinementLimit;
1746
+ /**
1747
+ * The watchdog (§4.2, critique S5): a claimed interaction whose work has gone quiet for longer
1748
+ * than `watchdogMs` is handed back rather than left to hang silently. Quiet is either no surface
1749
+ * ready to act on and no heartbeat, or the autopilot's own decision still running with no model
1750
+ * call landing and no heartbeat — a stalled model call, which nothing else times out. It checks a
1751
+ * few times per window, and stops when the interaction settles.
1752
+ */
1753
+ private armWatchdog;
1754
+ private disarmWatchdog;
1755
+ private onDecided;
1756
+ /**
1757
+ * The autopilot's self-pause, for one interaction (§4.10): the person gets it, with the reason as
1758
+ * the banner, and the autopilot carries on by itself once they answer. Only while it is still
1759
+ * the autopilot's to hand back — not settled, not already with the person — and its decision
1760
+ * stops with it, so a decision still running spends nothing more on an interaction it no longer
1761
+ * holds. Every caller (a decision's own hand-back, a failed decision, the watchdog) gets both.
1762
+ */
1763
+ private handBack;
1764
+ /**
1765
+ * On detach: hand a claimed interaction the autopilot still holds to the person, stopping its
1766
+ * decision, so the driver it wrapped lives on with nothing held by an autopilot that is gone.
1767
+ */
1768
+ private releaseHeld;
1769
+ /** A claimed interaction settled, whoever settled it. */
1770
+ private onSettled;
1771
+ private onFlowOwnerChanged;
1772
+ private capabilityFor;
1773
+ private flowOwner;
1774
+ private bindingFor;
1775
+ private isAvailable;
1776
+ private copyFor;
1777
+ private sessionFor;
1778
+ private record;
1779
+ private notify;
1780
+ }
1781
+
1782
+ /**
1783
+ * Options for {@link AutopilotDriver}.
1784
+ *
1785
+ * @beta
1786
+ */
1787
+ export declare interface AutopilotDriverOptions {
1788
+ /** The agents the host configured; an agent's `autopilot` key is what this driver runs. */
1789
+ readonly agents: readonly AgentConfig[];
1790
+ /** The registry the autopilot's own driver resolves its provider from. */
1791
+ readonly providerRegistry: AIProviderRegistry;
1792
+ /** The working session's debug-log key. */
1793
+ readonly sessionKey?: string;
1794
+ }
1795
+
1796
+ /**
1797
+ * The turn-level hand-back's view (GENC-1660 §4.10): the message, the working agent's question if
1798
+ * there was one, and the choices. It only renders: choosing calls the controller, which resolves.
1799
+ * Always the person's to answer (`userOnly`), so it never hides itself.
1800
+ *
1801
+ * @beta
1802
+ */
1803
+ export declare class AutopilotHandBack extends GenesisElement {
1804
+ interactionId: string;
1805
+ interaction?: AiChatInteraction<HandBackData, HandBackResult['payload']>;
1806
+ draft: string;
1807
+ get data(): HandBackData | undefined;
1808
+ /** What was chosen, once resolved. */
1809
+ get answer(): string | undefined;
1810
+ private get controller();
1811
+ choose(option: string): void;
1812
+ reply(): void;
1813
+ }
1814
+
1815
+ /**
1816
+ * The contract the autopilot UI is built against (GENC-1660 §4.10): the slim bar, its buttons, the
1817
+ * banner's "Keep paused", and the badge. The host installs `AutopilotDriver` itself, so it reads it
1818
+ * as this; nothing about it travels through `AiDriver`.
1819
+ *
1820
+ * @beta
1821
+ */
1822
+ export declare interface AutopilotHost {
1823
+ readonly state: AutopilotHostState;
1824
+ subscribe(listener: () => void): () => void;
1825
+ /** Pause until resumed. Hands a held interaction to the person on the spot. */
1826
+ pause(): void;
1827
+ /**
1828
+ * Resume. Takes back an interaction that pausing handed over; during the autopilot's own
1829
+ * hand-back it means "decide it yourself".
1830
+ */
1831
+ resume(): void;
1832
+ /** The existing Stop, which also pauses, so what is shown stays honest. */
1833
+ stop(): void;
1834
+ /** The banner's "Keep paused": turn the autopilot's own hand-back into an ordinary pause. */
1835
+ keepPaused(interactionId: string): void;
1836
+ readonly copy: AutopilotCopy;
1837
+ }
1838
+
1839
+ /**
1840
+ * What the autopilot UI reads (GENC-1660 §4.10).
1841
+ *
1842
+ * @beta
1843
+ */
1844
+ export declare interface AutopilotHostState {
1845
+ readonly mode: AutopilotMode;
1846
+ /**
1847
+ * Set while paused. `'this-interaction'` is the autopilot's own hand-back: it resumes by itself
1848
+ * once the person answers `interactionId`, and `reason` is the banner's text.
1849
+ */
1850
+ readonly pause?: {
1851
+ readonly scope: 'until-resumed' | 'this-interaction';
1852
+ readonly interactionId?: string;
1853
+ readonly reason?: string;
1854
+ };
1855
+ /** The slim bar's one-line status. */
1856
+ readonly status: string;
1857
+ /** Whether something waits on the person: drives the "needs you" badge. */
1858
+ readonly needsUser: boolean;
1859
+ /**
1860
+ * Whether something is happening: the working agent is busy, or the autopilot is deciding (a
1861
+ * widget it holds, or a written question it is answering). The slim bar replaces the composer
1862
+ * only while this is set; running but idle — stopped at a wall such as the budget, or at the end
1863
+ * of a turn it had nothing to answer for — the host shows what the agent's own rules show. A host
1864
+ * that hides the built-in composer keeps the slim bar regardless, as its only place for the pill.
1865
+ */
1866
+ readonly working: boolean;
1867
+ }
1868
+
1869
+ /**
1870
+ * The autopilot's mode for the current flow (GENC-1660 §4.10). `'unavailable'`: no autopilot for
1871
+ * this flow, or not yet (e.g. no approved brief). `'paused'`: available but not answering.
1872
+ * `'running'`: answering what its policy allows.
1873
+ *
1874
+ * @beta
1875
+ */
1876
+ export declare type AutopilotMode = 'unavailable' | 'paused' | 'running';
1877
+
1878
+ /**
1879
+ * Whether an autopilot may answer a widget (GENC-1660). `'human-first'` hands it straight to the
1880
+ * person; `'allowed'` lets the autopilot decide. Anything unlisted is `'human-first'`.
1881
+ *
1882
+ * @beta
1883
+ */
1884
+ export declare type AutopilotWidgetPolicy = 'human-first' | 'allowed';
1885
+
1364
1886
  declare interface BaseAgentConfig {
1365
1887
  /**
1366
1888
  * Stable identity for this agent. Used for classifier routing, manual
@@ -1649,6 +2171,14 @@ declare interface BaseAgentConfig {
1649
2171
  * @beta
1650
2172
  */
1651
2173
  contextReserve?: ContextReserveInput;
2174
+ /**
2175
+ * The autopilot that may answer this agent's interactions on the user's behalf (GENC-1660). Set by
2176
+ * `defineStatefulAgent`'s `autopilot` option, which binds the config to the agent's live state;
2177
+ * consumed by `AutopilotDriver`. Never routed to or pinned: it is not an agent in the array.
2178
+ *
2179
+ * @beta
2180
+ */
2181
+ autopilot?: AutopilotBinding;
1652
2182
  }
1653
2183
 
1654
2184
  /**
@@ -1706,6 +2236,8 @@ export declare abstract class BaseDriverDecorator<TInner extends AiDriver = AiDr
1706
2236
  setPinnedAgent(name: string | null): void;
1707
2237
  setFlowOwner(name: string | null): void;
1708
2238
  getFlowOwner(): string | null;
2239
+ getInteractionCheckpoint(): PersistedInteractionCheckpoint | undefined;
2240
+ restoreInteractionCheckpoint(saved: PersistedInteractionCheckpoint | undefined): void;
1709
2241
  /**
1710
2242
  * Forwarded, so an interceptor installed on any layer lands on the driver that opens the
1711
2243
  * interactions. A decorator that answers interactions installs its own on `this.inner`.
@@ -2863,6 +3395,10 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
2863
3395
  * host) to build the widget's pending `interaction` descriptor.
2864
3396
  */
2865
3397
  getInteractionContext(interactionId: string): InteractionContext | undefined;
3398
+ /** {@inheritDoc AiDriver.getInteractionCheckpoint} */
3399
+ getInteractionCheckpoint(): PersistedInteractionCheckpoint | undefined;
3400
+ /** {@inheritDoc AiDriver.restoreInteractionCheckpoint} */
3401
+ restoreInteractionCheckpoint(saved: PersistedInteractionCheckpoint | undefined): void;
2866
3402
  /**
2867
3403
  * Replace the history message owning `interactionId`. `false` when it is no longer in history.
2868
3404
  * Does not announce the change — the interaction paths differ on whether they should.
@@ -3393,6 +3929,79 @@ export declare interface DebugLog {
3393
3929
  meta: unknown;
3394
3930
  }
3395
3931
 
3932
+ /**
3933
+ * What was decided, as handed to a short-form decision's `choose` (GENC-1660).
3934
+ *
3935
+ * @beta
3936
+ */
3937
+ export declare type DecisionAnswer =
3938
+ /** One option, by id. */
3939
+ {
3940
+ readonly kind: 'option';
3941
+ readonly option: string;
3942
+ }
3943
+ /** Several options, by id (a multi-select). */
3944
+ | {
3945
+ readonly kind: 'options';
3946
+ readonly options: readonly string[];
3947
+ }
3948
+ /** A written answer (`freeText`). */
3949
+ | {
3950
+ readonly kind: 'text';
3951
+ readonly text: string;
3952
+ };
3953
+
3954
+ /**
3955
+ * One option of a short-form decision (GENC-1660). A bare string is an option whose id and label are
3956
+ * the same text.
3957
+ *
3958
+ * @beta
3959
+ */
3960
+ export declare type DecisionOption = string | {
3961
+ /**
3962
+ * The stable name of the option's action — what a view passes to `ctx.claimantOwns` to hide
3963
+ * its button. Defaults to `label`.
3964
+ */
3965
+ readonly id?: string;
3966
+ /** The option's text, as the person sees it. */
3967
+ readonly label: string;
3968
+ /**
3969
+ * Whether it can be chosen right now — the button's own guard (e.g. `validated` for a
3970
+ * Continue). Read fresh every time. A disabled option is listed as unavailable and refused.
3971
+ */
3972
+ readonly enabledWhen?: () => boolean;
3973
+ };
3974
+
3975
+ /**
3976
+ * A short-form decision: the surface most widgets need (GENC-1660). Its actions are its options,
3977
+ * all finishing, plus `select` for a multi-select and `reply` for a written answer.
3978
+ *
3979
+ * @beta
3980
+ */
3981
+ export declare interface DecisionSpec {
3982
+ readonly options: readonly DecisionOption[];
3983
+ /** Adds a `select({ options })` action that picks several. */
3984
+ readonly multi?: boolean;
3985
+ /** Adds a `reply({ text })` action: an answer in the chooser's own words. */
3986
+ readonly freeText?: boolean;
3987
+ /**
3988
+ * What a decision needs that the person sees on screen in some other form — e.g.
3989
+ * `{ validated: true }`. A getter, so it is read fresh whenever the decision is described.
3990
+ */
3991
+ readonly facts?: () => Readonly<Record<string, unknown>>;
3992
+ /**
3993
+ * Model-only guidance the person would not see. The decision's own text comes from the
3994
+ * widget's `asText`, which is what the person saw.
3995
+ */
3996
+ readonly prompt?: string;
3997
+ /**
3998
+ * Act on the answer. The SAME method the view's buttons call, so a claimant's answer runs the
3999
+ * code a click runs. Must resolve the interaction (through `ctx.resolve`), now or once its work
4000
+ * is done.
4001
+ */
4002
+ choose(answer: DecisionAnswer): void | Promise<void>;
4003
+ }
4004
+
3396
4005
  /**
3397
4006
  * Animations enabled by default when a consumer opts into the animations
3398
4007
  * feature without specifying an explicit `enabled` list. Keeps the dots loading
@@ -3427,6 +4036,28 @@ export declare const DEFAULT_DELEGATE_FRAMING = "Sent on the user's behalf.";
3427
4036
  */
3428
4037
  export declare function defineAgent<const T extends AgentConfig>(config: T): T;
3429
4038
 
4039
+ /**
4040
+ * Define an autopilot for a stateful agent whose state is `S` (GENC-1660). An identity function
4041
+ * that exists for its type: the resolvers get `S`, and the result goes on `defineStatefulAgent`'s
4042
+ * `autopilot` option.
4043
+ *
4044
+ * @example
4045
+ * ```ts
4046
+ * defineStatefulAgent<BootstrapState>({
4047
+ * name: 'bootstrap',
4048
+ * …,
4049
+ * autopilot: defineAutopilot<BootstrapState>({
4050
+ * availableWhen: ({ state }) => briefApproved(state.machine),
4051
+ * widgetPolicy: { 'planning-question': 'allowed' },
4052
+ * systemPrompt: ({ state }) => `${AUTOPILOT_BASE}\n<brief>${frozenBrief(state)}</brief>`,
4053
+ * }),
4054
+ * });
4055
+ * ```
4056
+ *
4057
+ * @beta
4058
+ */
4059
+ export declare function defineAutopilot<S = unknown>(config: AutopilotConfig<S>): AutopilotConfig<S>;
4060
+
3430
4061
  /**
3431
4062
  * Build an `AgentConfig` whose `systemPrompt`, `toolDefinitions`, and tool
3432
4063
  * handlers all close over a long-lived state object created on activation.
@@ -3459,8 +4090,8 @@ export declare function defineStatefulAgent<S>(opts: StatefulAgentInit<S>): Agen
3459
4090
  * to the result of the tool call that requested it, as `decidedOnUsersBehalf` on an object result
3460
4091
  * or as a line appended to a text one.
3461
4092
  *
3462
- * Built only from what the platform already holds — the claimant's framing, and the choice and
3463
- * narration it recorded — so the text the person saw and the text the agent is told about are the
4093
+ * Built only from what the platform already holds — the claimant's framing, and the choice,
4094
+ * narration and edits it recorded — so the text the person saw and the text the agent is told about are the
3464
4095
  * same string. It never names the claimant, so the agent has nothing to repeat about one.
3465
4096
  *
3466
4097
  * @beta
@@ -3472,6 +4103,34 @@ export declare interface DelegatedDecision {
3472
4103
  readonly choice?: string;
3473
4104
  /** What the person was shown about it, verbatim, as the assistant's own words. */
3474
4105
  readonly shownToUser?: string;
4106
+ /**
4107
+ * What the claimant changed in the widget before it decided, in order, each as the claimant
4108
+ * reported it (`InteractionEdit.choice`): present only when it made edits. Lets the agent know
4109
+ * the interaction was altered, not just answered.
4110
+ */
4111
+ readonly edits?: readonly string[];
4112
+ }
4113
+
4114
+ /**
4115
+ * What the working agent is told when the PERSON settled an interaction an interceptor had already
4116
+ * changed (GENC-1660): added to the result of the tool call that requested it, as
4117
+ * `editedOnUsersBehalf` on an object result or as a line appended to a text one. The edits were
4118
+ * made on the user's behalf before they answered; the user then confirmed them by finishing it, so
4119
+ * the answer itself is theirs and is not a {@link DelegatedDecision}.
4120
+ *
4121
+ * Built, like a decision, only from what the platform holds — the claimant's framing and the edits
4122
+ * it reported — and never names the claimant.
4123
+ *
4124
+ * @beta
4125
+ */
4126
+ export declare interface DelegatedEdits {
4127
+ /**
4128
+ * The claimant's {@link InteractionInterceptor.editFraming}, e.g. "Changed on the user's behalf
4129
+ * before they answered; the user then finished it, confirming the changes".
4130
+ */
4131
+ readonly framing: string;
4132
+ /** What the claimant changed, in order, each as it reported it (`InteractionEdit.choice`). */
4133
+ readonly edits: readonly string[];
3475
4134
  }
3476
4135
 
3477
4136
  /**
@@ -4198,7 +4857,7 @@ export declare class FoundationAiAssistant extends GenesisElement {
4198
4857
  private get transcriptBudgetExhaustedMessage();
4199
4858
  /**
4200
4859
  * Name of the agent the user has pinned via the agent picker. `null` means
4201
- * automatic routing (Auto). Persisted on the session store, so it survives
4860
+ * orchestration: the assistant routes each message. Persisted on the session store, so it survives
4202
4861
  * pop-in/pop-out but resets on page refresh.
4203
4862
  *
4204
4863
  * Only changes on explicit user action (picker click or host's `setAgent`).
@@ -4595,6 +5254,110 @@ export declare class FoundationAiAssistant extends GenesisElement {
4595
5254
  private syncShowHalo;
4596
5255
  /** True when there is a pending (unresolved) interaction. */
4597
5256
  get hasActivePendingInteraction(): boolean;
5257
+ /**
5258
+ * True when the turn is parked on the person: a pending interaction they hold. One a claimant
5259
+ * holds (the autopilot deciding it) is the assistant still working, so the halo and the loading
5260
+ * indicator stay on (GENC-1660 §4.10).
5261
+ */
5262
+ get waitingOnUser(): boolean;
5263
+ /**
5264
+ * An autopilot host supplied from outside, in place of the one this element installs — the
5265
+ * sandbox's stub, or a test's. Without it, the element reads the `AutopilotDriver` it installed
5266
+ * when some agent declares `autopilot`.
5267
+ *
5268
+ * @beta
5269
+ */
5270
+ autopilotHostOverride?: AutopilotHost;
5271
+ /** The autopilot's state and copy, mirrored for the template. Absent with no autopilot. @internal */
5272
+ autopilotState?: AutopilotHostState;
5273
+ /** @internal */
5274
+ autopilotCopy?: AutopilotCopy;
5275
+ /**
5276
+ * A pending interaction being pointed out, after the person opened the collapsed assistant from
5277
+ * its "needs you" badge: its row pulses briefly. @internal
5278
+ */
5279
+ attentionInteractionId?: string;
5280
+ private attentionTimer?;
5281
+ /** Who holds the trailing pending interaction: `'user'` unless a claimant took it. @internal */
5282
+ activeHeldBy: InteractionHolder;
5283
+ private autopilotCleanup?;
5284
+ private heldCleanup?;
5285
+ private heldInteractionId?;
5286
+ /** The autopilot behind the slim bar and the banner, if there is one. */
5287
+ get autopilotHost(): AutopilotHost | undefined;
5288
+ /** Whether the autopilot is available for the current flow, running or paused. @internal */
5289
+ get autopilotAvailable(): boolean;
5290
+ /** Running and not waiting on an answer, so its control pauses it; otherwise it resumes. @internal */
5291
+ get autopilotCanPause(): boolean;
5292
+ /**
5293
+ * What clicking the toggle does, at the head of its tooltip. While it waits on a question it
5294
+ * handed back, Resume is not a plain resume: it takes that question back and decides it, with no
5295
+ * way to hand it back again. @internal
5296
+ */
5297
+ get autopilotToggleAction(): string | undefined;
5298
+ /**
5299
+ * The toggle's tooltip: what clicking does now, then what the autopilot does. The action is here
5300
+ * and not in its accessible name: the toggle is a toggle (`aria-pressed`), so its name stays
5301
+ * `toggleLabel` and its state is announced once, by the pressed state. @internal
5302
+ */
5303
+ get autopilotToggleTitle(): string | undefined;
5304
+ /** Waiting on one answer it handed back. @internal */
5305
+ get autopilotSelfPaused(): boolean;
5306
+ /**
5307
+ * The slim bar takes the composer's place while something is happening and the autopilot runs or
5308
+ * waits on one answer, and otherwise wherever the agent's own rules would hide the composer. Running
5309
+ * but idle — stopped at a wall such as the budget, or at the end of a turn it had nothing to
5310
+ * answer for — shows what those rules show, normally the composer, with the Autopilot pill on among
5311
+ * its pills. It never forces the composer open. A host that hides the built-in composer
5312
+ * (`chatConfig.ui.hideComposer`) has no pills to put it among, so there the slim bar stays up
5313
+ * whenever the autopilot is available, running or paused, idle or not: the person can always see
5314
+ * that it is on, and pause or resume it. @internal
5315
+ */
5316
+ get slimBarVisible(): boolean;
5317
+ /**
5318
+ * What the autopilot's status region announces (GENC-1660 §4.10): the hand-back, with its reason,
5319
+ * while the autopilot waits on an answer; otherwise the slim bar's status while that shows;
5320
+ * otherwise nothing. The region stays mounted and only this text changes, so each change is
5321
+ * announced. @internal
5322
+ */
5323
+ get autopilotAnnouncement(): string;
5324
+ /**
5325
+ * The Autopilot pill among the composer's pills: available, with the composer shown — paused, or
5326
+ * running with nothing happening. Where the host hides the composer, it is in the slim bar
5327
+ * instead (see `slimBarVisible`). @internal
5328
+ */
5329
+ get composerAutopilotVisible(): boolean;
5330
+ autopilotHostOverrideChanged(): void;
5331
+ /** Follow the autopilot host's state, publishing the "needs you" signal for the bubble. */
5332
+ private wireAutopilot;
5333
+ /**
5334
+ * Scroll to the pending interaction that waits on the person, and pulse it, so opening the chat
5335
+ * from the badge lands on it rather than wherever the transcript was left.
5336
+ */
5337
+ private showWaiting;
5338
+ /** How long a pointed-out interaction pulses for. */
5339
+ private static readonly ATTENTION_MS;
5340
+ /**
5341
+ * Follow who holds the trailing pending interaction. A claimant changes it on its context, which
5342
+ * notifies, so the view re-reads it on every notification rather than once (GENC-1660 §4.3).
5343
+ */
5344
+ private syncActiveHold;
5345
+ private readActiveHold;
5346
+ /**
5347
+ * Whether a pending interaction's bubble is drawn at all. A widget registered with
5348
+ * `whileAutopilot: 'hidden'` asks for no chrome while a claimant holds it: the view renders
5349
+ * nothing, so an empty bubble would be left behind. @internal
5350
+ */
5351
+ isHiddenWhileHeld(m: ChatMessage): boolean;
5352
+ /** The hand-back banner's reason, when this interaction is the one the autopilot handed back. @internal */
5353
+ handBackReasonFor(m: ChatMessage): string | undefined;
5354
+ /** Whether to mark a message as done in autopilot mode. @internal */
5355
+ showsDelegateMark(m: ChatMessage): boolean;
5356
+ /** The autopilot mark's tooltip. @internal */
5357
+ get delegateMarkLabel(): string;
5358
+ handleAutopilotPause(): void;
5359
+ handleAutopilotResume(): void;
5360
+ handleKeepPaused(interactionId: string): void;
4598
5361
  showHaloChanged(): void;
4599
5362
  private getActiveToolNames;
4600
5363
  /**
@@ -4764,6 +5527,15 @@ export declare class FoundationAiAssistant extends GenesisElement {
4764
5527
  private syncLoadingIndicator;
4765
5528
  /** Called when the user clicks the popout button. */
4766
5529
  handlePopout(): void;
5530
+ /**
5531
+ * The key this assistant's session is published under (on the activity bus, in the debug log,
5532
+ * in storage): the wired session's once one is active, else the one its attributes imply. Not
5533
+ * always the `session-key` attribute, which can run ahead of a deferred switch and is absent when
5534
+ * the key is derived from `id` and the header title. `undefined` when it has no identity.
5535
+ *
5536
+ * @beta
5537
+ */
5538
+ get stateKey(): string | undefined;
4767
5539
  /** Returns a cache key for this instance, or undefined if the component has no identity. */
4768
5540
  private getStateKey;
4769
5541
  /**
@@ -5143,12 +5915,21 @@ export declare class FoundationAiAssistant extends GenesisElement {
5143
5915
  */
5144
5916
  get pinnedAgentColour(): string | undefined;
5145
5917
  /**
5146
- * Label beside the composer's agent glyph: `AUTO` while the orchestrator is
5147
- * routing, otherwise the pinned agent's name. The name is NOT shortened here —
5918
+ * Label beside the composer's agent glyph: the orchestration label (`Orchestration` unless the
5919
+ * host renames it) while the orchestrator is routing, otherwise the pinned agent's name. The name is NOT shortened here —
5148
5920
  * the button truncates with an ellipsis in CSS, so the full name stays
5149
5921
  * available to a screen reader and to the `title` tooltip.
5150
5922
  */
5151
5923
  get agentButtonLabel(): string;
5924
+ /**
5925
+ * The picker's name for orchestration, from `chatConfig.picker.orchestrationLabel`. Not "Auto":
5926
+ * other tools use that for picking a model tier, and here it is the agent that is chosen.
5927
+ */
5928
+ get orchestrationLabel(): string;
5929
+ /** The same choice's name in the picker menu, from `chatConfig.picker.orchestrationMenuLabel`. */
5930
+ get orchestrationMenuLabel(): string;
5931
+ /** What orchestration does, from `chatConfig.picker.orchestrationDescription`. */
5932
+ get orchestrationDescription(): string;
5152
5933
  /**
5153
5934
  * Placeholder shown in the chat input. Substitutes the pinned agent's name
5154
5935
  * when one is selected so the user has a clearer signal of where their
@@ -5593,6 +6374,62 @@ export declare type GenesisWriteReviewCompletedEventDetail = InteractionResult<G
5593
6374
  */
5594
6375
  export declare function getAiPopoutManager(): FoundationAiPopoutManager | undefined;
5595
6376
 
6377
+ /**
6378
+ * The registration for a component name, or `undefined` when it has none.
6379
+ *
6380
+ * @beta
6381
+ */
6382
+ export declare function getInteractionRegistration(name: string): InteractionRegistration | undefined;
6383
+
6384
+ /**
6385
+ * What the person can choose. `reply` carries their written answer to the working agent's
6386
+ * question; the rest tell the autopilot what to do next.
6387
+ *
6388
+ * @beta
6389
+ */
6390
+ export declare type HandBackChoice = 'carry-on' | 'try-again' | 'compact' | 'pause' | 'reply';
6391
+
6392
+ /**
6393
+ * The hand-back's inputs. Every word it shows comes from here, so it follows the autopilot's
6394
+ * `AutopilotCopy`.
6395
+ *
6396
+ * @beta
6397
+ */
6398
+ export declare interface HandBackData {
6399
+ /** Why the person is needed, in the assistant's voice. */
6400
+ readonly message: string;
6401
+ /** The working agent's question, when the turn ended on one. */
6402
+ readonly question?: string;
6403
+ readonly options: readonly HandBackOption[];
6404
+ /** Whether a written answer is offered (a turn that ended on a question). */
6405
+ readonly freeText?: boolean;
6406
+ /** The label of the button that sends the written answer, with `freeText`. */
6407
+ readonly sendLabel?: string;
6408
+ }
6409
+
6410
+ /**
6411
+ * One choice the hand-back offers.
6412
+ *
6413
+ * @beta
6414
+ */
6415
+ export declare interface HandBackOption {
6416
+ readonly id: HandBackChoice;
6417
+ readonly label: string;
6418
+ }
6419
+
6420
+ /**
6421
+ * What the hand-back resolves with.
6422
+ *
6423
+ * @beta
6424
+ */
6425
+ export declare interface HandBackResult {
6426
+ readonly status: 'approved';
6427
+ readonly payload: {
6428
+ choice: HandBackChoice;
6429
+ text?: string;
6430
+ };
6431
+ }
6432
+
5596
6433
  /**
5597
6434
  * Builds a capability's value for one tool-handler call (GENC-1660). Called per call, so it can
5598
6435
  * reflect the moment; it should be cheap and must not throw (a throw is logged and the capability
@@ -5673,7 +6510,7 @@ export declare type InteractionCompletedEventDetail = ChatInteractionEventsMap['
5673
6510
  *
5674
6511
  * @beta
5675
6512
  */
5676
- export declare interface InteractionContext<TState extends object = Record<string, unknown>> {
6513
+ export declare interface InteractionContext<TState extends object = Record<string, unknown>, TCheckpoint = unknown> {
5677
6514
  /** Stable id of the interaction this context belongs to. */
5678
6515
  readonly interactionId: string;
5679
6516
  /**
@@ -5729,14 +6566,78 @@ export declare interface InteractionContext<TState extends object = Record<strin
5729
6566
  * has already been disposed runs `fn` immediately.
5730
6567
  */
5731
6568
  onDispose(fn: () => void): void;
6569
+ /**
6570
+ * The widget's controller, built by the platform from its registration when the interaction was
6571
+ * requested, before anything rendered. `undefined` for an unregistered widget. One per
6572
+ * interaction for its whole life, so a remounted view picks up the same one.
6573
+ */
6574
+ readonly controller: unknown;
6575
+ /**
6576
+ * Settle the interaction with `result` — the controller's way to resolve, in place of an element
6577
+ * emitting `interaction-completed`, so resolving needs no mounted view. Goes through the same
6578
+ * path, so cost and diagnostics fold in as before. Settles once: later calls do nothing.
6579
+ */
6580
+ resolve(result: unknown): void;
6581
+ /**
6582
+ * Expose what can be decided here (the short form). Called by the controller: in its constructor
6583
+ * for a pure question, or when its gate opens for a widget that works first. Calling again
6584
+ * replaces it.
6585
+ */
6586
+ exposeDecision(decision: DecisionSpec): void;
6587
+ /**
6588
+ * Expose the full form, for a rich widget: a description, views to read, and named actions —
6589
+ * some only edit (and do not settle), some finish. Calling again replaces the surface, as
6590
+ * `exposeDecision` does.
6591
+ */
6592
+ exposeSurface(surface: SurfaceSpec): void;
6593
+ /** The surface the controller exposed, or `undefined` until it exposes one. */
6594
+ readonly surface: InteractionSurface | undefined;
6595
+ /**
6596
+ * Run `fn` once the surface is ready (see `InteractionSurface.isReady`) — or now if
6597
+ * it already is. Readiness is re-checked on every `notify()`, so a gate whose guard turns true
6598
+ * later fires it then. Never runs after the interaction ends. Returns an unsubscribe.
6599
+ */
6600
+ onSurfaceReady(fn: () => void): () => void;
6601
+ /**
6602
+ * Whether a claimant holds the interaction AND `action` is one of its enabled actions right now.
6603
+ * A view hides a button with this, never with `heldBy` alone: a button the controller did not
6604
+ * expose — an error-state Retry, say — is then never hidden, so nothing can strand the journey.
6605
+ */
6606
+ claimantOwns(action: string): boolean;
6607
+ /** When the controller last called `notify()` (or the interaction opened), in epoch ms. A heartbeat. */
6608
+ readonly lastActivityAt: number;
6609
+ /**
6610
+ * What is already done, for long work that should survive a reload: the last checkpoint saved,
6611
+ * or the one the platform handed over — after a restore, the first request for the same widget
6612
+ * type takes over the checkpoint the reload cut, if the registration's `sameWork` agrees.
6613
+ * `undefined` for fresh work. See `runSteps`, which reads and writes it for you.
6614
+ */
6615
+ readonly checkpoint: TCheckpoint | undefined;
6616
+ /**
6617
+ * Save a checkpoint into the session snapshot, so a reload does not lose it. Kept as JSON, so it
6618
+ * must be storable as JSON; keep it small and hold anything large by reference (a job id, a store
6619
+ * key). One per interaction: each save replaces the last. Cleared when the interaction settles,
6620
+ * and when its flow ends.
6621
+ */
6622
+ saveCheckpoint(checkpoint: TCheckpoint): void;
5732
6623
  }
5733
6624
 
6625
+ /**
6626
+ * Builds a widget's controller when its interaction is requested (GENC-1660). DOM-free: it owns the
6627
+ * interaction's state, its surface and resolving it; the view only renders.
6628
+ *
6629
+ * @beta
6630
+ */
6631
+ export declare type InteractionControllerFactory = (data: unknown, ctx: InteractionContext) => unknown;
6632
+
5734
6633
  /**
5735
6634
  * Detail payload for the `interaction-cost` event — a POSITIVE DELTA in USD, not a running total.
5736
6635
  * @public
5737
6636
  */
5738
6637
  export declare type InteractionCostEventDetail = ChatInteractionEventsMap['interaction-cost'];
5739
6638
 
6639
+ export { InteractionEdit }
6640
+
5740
6641
  /**
5741
6642
  * The handle an interceptor uses to move a pending interaction between the person and itself
5742
6643
  * (GENC-1660): to the person when it hands back or is paused, back to itself when resumed.
@@ -5775,6 +6676,28 @@ export declare interface InteractionHold {
5775
6676
  * `heldBy`. Returns `false`, settling nothing, unless this interceptor holds it right now.
5776
6677
  */
5777
6678
  resolve(result: unknown): boolean;
6679
+ /**
6680
+ * Run one of the surface's actions as the claimant (GENC-1660): an option by its id, `select`
6681
+ * with `{ options }`, or `reply` with `{ text }`. It runs the same code the widget's own button
6682
+ * runs, and records the decision for the asking tool — the choice as the person would read it,
6683
+ * and `note`, verbatim, as what they were shown about it — so `recordDecision` is not needed.
6684
+ *
6685
+ * A finishing action settles the interaction AS the claimant, as {@link InteractionHold.resolve}
6686
+ * does, so it is stamped `answeredBy` the claimant.
6687
+ *
6688
+ * Refused, with nothing run, unless this interceptor holds the interaction right now, the
6689
+ * surface has that action, it is enabled and `args` fit it. One action runs at a time: a call
6690
+ * made while an earlier one on the same interaction is still running is refused as `'busy'`, to
6691
+ * be tried again once that one has returned. A refusal lists what is enabled, so the caller can
6692
+ * correct itself. `finished` says whether the interaction settled.
6693
+ *
6694
+ * Handing the interaction to the person (`set('user')`) while a finishing action is still
6695
+ * running does not take that action's credit away: if it settles the interaction, the answer is
6696
+ * the claimant's. If it does not, the interaction is the person's like any other.
6697
+ */
6698
+ invoke(action: string, args?: unknown, options?: {
6699
+ note?: string;
6700
+ }): Promise<InvokeResult>;
5778
6701
  }
5779
6702
 
5780
6703
  /**
@@ -5805,6 +6728,14 @@ export declare interface InteractionInterceptor {
5805
6728
  * would say "Decided on the user's behalf, from their brief".
5806
6729
  */
5807
6730
  readonly decisionFraming?: string;
6731
+ /**
6732
+ * How {@link DelegatedEdits} open, as the working agent reads them: the person finished an
6733
+ * interaction this interceptor had changed first. Must say the changes were made on the user's
6734
+ * behalf before they answered, and that finishing it confirmed them; must not name the
6735
+ * interceptor. Defaults to "Changed on the user's behalf before the user answered; the user then
6736
+ * finished it, confirming the changes".
6737
+ */
6738
+ readonly editFraming?: string;
5808
6739
  /** Return `'claim'` to hold the interaction, or nothing to leave it with the person. */
5809
6740
  onInteractionOpened(opened: InteractionOpened): 'claim' | undefined | void;
5810
6741
  }
@@ -5836,6 +6767,39 @@ export declare interface InteractionOpened {
5836
6767
  readonly hold: InteractionHold;
5837
6768
  }
5838
6769
 
6770
+ /**
6771
+ * How a widget is registered with the platform, once, at start-up (GENC-1660).
6772
+ *
6773
+ * @beta
6774
+ */
6775
+ export declare interface InteractionRegistration {
6776
+ /**
6777
+ * Builds the controller when the interaction is requested, before anything renders. Without
6778
+ * one the widget works exactly as today and is never handed to a claimant.
6779
+ */
6780
+ readonly controller?: InteractionControllerFactory;
6781
+ /** The custom element that renders it. Defaults to the registered name. */
6782
+ readonly view?: string;
6783
+ /**
6784
+ * What the widget shows while a claimant holds it: `'visible'` (the default; it hides only the
6785
+ * buttons the claimant owns) or `'hidden'` (the wrapper drops the bubble chrome too).
6786
+ */
6787
+ readonly whileAutopilot?: 'visible' | 'hidden';
6788
+ /**
6789
+ * The widget as text: what the person saw. Without `result` the pending widget, with it what the
6790
+ * resolved view shows. Used for the visible transcript a claimant reads.
6791
+ */
6792
+ readonly asText?: (data: unknown, result?: unknown) => string;
6793
+ /**
6794
+ * Whether a checkpoint a reload cut (`saved`) is the same work as this new request (`next`, its
6795
+ * data), so the new interaction may take it over and skip what is already done (GENC-1660 §4.12).
6796
+ * Without it, the same widget type is enough. Compare identity only — the fields the work's
6797
+ * output depends on, kept in the checkpoint itself — never the model's prose, which a resumed call
6798
+ * rewrites.
6799
+ */
6800
+ readonly sameWork?: (saved: unknown, next: unknown) => boolean;
6801
+ }
6802
+
5839
6803
  /**
5840
6804
  * Opens an interaction somewhere else — the parent driver, for a sub-agent's — and tells
5841
6805
  * `onOpened` its id. `ownerPath` is the agents the request has already come up through, outermost
@@ -5845,22 +6809,74 @@ declare type InteractionRequester = <T>(componentName: string, data: any, option
5845
6809
 
5846
6810
  /**
5847
6811
  * Who answered an interaction, as its requester is told (GENC-1660). `answeredBy` is absent when it
5848
- * closed unanswered (a timeout or a stop); `decision` is present when an interceptor answered.
6812
+ * closed unanswered (a timeout or a stop); `decision` is present when an interceptor answered;
6813
+ * `edited` is present when the person answered one an interceptor had changed first.
5849
6814
  */
5850
6815
  declare interface InteractionSettled {
5851
6816
  readonly answeredBy?: string;
5852
6817
  readonly decision?: DelegatedDecision;
6818
+ readonly edited?: DelegatedEdits;
6819
+ }
6820
+
6821
+ /**
6822
+ * What can be read from an interaction's surface (GENC-1660): its actions as they stand now, and
6823
+ * its facts. Present once the controller has exposed one.
6824
+ *
6825
+ * @beta
6826
+ */
6827
+ export declare interface InteractionSurface {
6828
+ /** Model-only guidance, from the decision's `prompt`. */
6829
+ readonly prompt?: string;
6830
+ /** Read fresh on every call. */
6831
+ facts(): Readonly<Record<string, unknown>>;
6832
+ /** A full-form surface's description. Absent on a short-form decision. */
6833
+ describe?(): string;
6834
+ /** A full-form surface's views. */
6835
+ readonly views?: readonly string[];
6836
+ /** Read one view of a full-form surface; absent on a short-form decision. */
6837
+ read?(view?: string): unknown;
6838
+ /** Read fresh on every call: `enabled` reflects each option's guard right now. */
6839
+ actions(): readonly SurfaceAction[];
6840
+ /**
6841
+ * Whether a claimant could act on it now. A short-form decision is ready once one of its options
6842
+ * is enabled; a full-form surface once any of its actions is, since editing comes before
6843
+ * finishing (its Save may be disabled until something is edited).
6844
+ */
6845
+ isReady(): boolean;
5853
6846
  }
5854
6847
 
5855
6848
  /**
5856
6849
  * A message's interaction widget, in the wrapper that mounts it. Everything the widget is shown
5857
- * comes from the history message through here, the outcome a tool recorded after the answer
5858
- * included, so a remount, a pop-out and a reload all show the same thing.
6850
+ * comes from the history message through here, the outcome a tool recorded after the answer and the
6851
+ * edits a claimant made included, so a remount, a pop-out and a reload all show the same thing.
5859
6852
  *
5860
6853
  * @internal
5861
6854
  */
5862
6855
  export declare const interactionWrapperTemplate: ViewTemplate<ChatMessage, FoundationAiAssistant>;
5863
6856
 
6857
+ /**
6858
+ * What came of an `InteractionHold.invoke` (GENC-1660). On success, `finished` says whether the
6859
+ * interaction settled and `actions` is what is enabled now; on failure, `error` says why and nothing
6860
+ * ran.
6861
+ *
6862
+ * @beta
6863
+ */
6864
+ export declare type InvokeResult = {
6865
+ readonly ok: true;
6866
+ readonly finished: boolean;
6867
+ readonly actions: readonly SurfaceAction[];
6868
+ /** What an editing action returned (fresh errors, say), for the claimant. */
6869
+ readonly output?: unknown;
6870
+ readonly error?: never;
6871
+ readonly message?: never;
6872
+ } | {
6873
+ readonly ok: false;
6874
+ readonly finished?: never;
6875
+ readonly error: 'not-held' | 'no-surface' | 'unknown-action' | 'disabled' | 'invalid-args' | 'threw' | 'busy';
6876
+ readonly message: string;
6877
+ readonly actions?: readonly SurfaceAction[];
6878
+ };
6879
+
5864
6880
  /** True when the assistant is active in the layout panel (docked) rather than the bubble. */
5865
6881
  export declare function isAiAssistantDocked(): boolean;
5866
6882
 
@@ -6047,6 +7063,14 @@ export declare class OrchestratingDriver extends BaseDriverDecorator<ChatDriver>
6047
7063
  * undecorated.
6048
7064
  */
6049
7065
  resumeRestoredFlow(resumeNote?: string): Promise<ChatDriverResult | undefined>;
7066
+ /**
7067
+ * A continuation outside a routed turn — a decorator carrying the agent on, say — can finish the
7068
+ * flow as surely as a turn can, so a release it requests is acted on here too. Before
7069
+ * (GENC-1660), only `sendMessage` checked, and a flow finished by a continuation stayed locked.
7070
+ */
7071
+ continueFromHistory(transientPrimer?: ChatMessage[], options?: ContinueFromHistoryOptions): Promise<ChatDriverResult>;
7072
+ /** Release the flow if the turn that just ended asked to, and an agent is still active to release. */
7073
+ private releaseIfRequested;
6050
7074
  /**
6051
7075
  * {@inheritDoc AiDriver.getContextReserve}
6052
7076
  *
@@ -6126,6 +7150,17 @@ export declare class OrchestratingDriver extends BaseDriverDecorator<ChatDriver>
6126
7150
  */
6127
7151
  export declare const PERSISTED_SESSION_VERSION = 1;
6128
7152
 
7153
+ /**
7154
+ * The autopilot's mode as saved with the session (GENC-1660 §4.8): which flow it was set for, and
7155
+ * whether it was running. Cleared when that flow ends, so a saved mode never outlives its flow.
7156
+ *
7157
+ * @beta
7158
+ */
7159
+ export declare interface PersistedAutopilotMode {
7160
+ readonly onFor: string;
7161
+ readonly mode: 'running' | 'paused';
7162
+ }
7163
+
6129
7164
  /**
6130
7165
  * A `condenseWhen` policy that had NOT fired when the session was saved, in the shape it is
6131
7166
  * persisted in (GENC-1632).
@@ -6167,6 +7202,17 @@ export declare interface PersistedCondensePolicy {
6167
7202
  };
6168
7203
  }
6169
7204
 
7205
+ /**
7206
+ * A long action's checkpoint as persisted with the session (GENC-1660 §4.12): the widget type it
7207
+ * belongs to, and the value its controller saved.
7208
+ *
7209
+ * @beta
7210
+ */
7211
+ export declare interface PersistedInteractionCheckpoint {
7212
+ readonly componentName: string;
7213
+ readonly value: unknown;
7214
+ }
7215
+
6170
7216
  /**
6171
7217
  * A durable, restorable snapshot of one chat session — the *restorable core* of
6172
7218
  * the debug log (GENC-1351 §5.1/D1), captured losslessly and independently of
@@ -6222,6 +7268,25 @@ export declare interface PersistedSession {
6222
7268
  * predates it ignores it. Omitted rather than written empty when there is nothing to carry.
6223
7269
  */
6224
7270
  condensePolicies?: PersistedCondensePolicy[];
7271
+ /**
7272
+ * The autopilot's mode for the flow it was set for (GENC-1660 §4.8), restored with the session.
7273
+ * Optional and additive like `condensePolicies`: absent when no autopilot was switched for the
7274
+ * current flow, and a snapshot from before it existed restores with the autopilot paused.
7275
+ */
7276
+ autopilot?: {
7277
+ onFor: string;
7278
+ mode: 'running' | 'paused';
7279
+ };
7280
+ /**
7281
+ * The checkpoint of a long action (GENC-1660 §4.12): what a widget's work had already done, so a
7282
+ * reload skips it. Kept here rather than on the interaction message, which a restore trims. On
7283
+ * restore it waits for the first request of the same widget type. Optional and additive, like
7284
+ * `condensePolicies`.
7285
+ */
7286
+ checkpoint?: {
7287
+ componentName: string;
7288
+ value: unknown;
7289
+ };
6225
7290
  /**
6226
7291
  * Interrupted-flow marker (GENC-1351 §5.9). Present when the session was saved
6227
7292
  * while an agent declared its current state non-resumable (`resumable === false`).
@@ -6267,6 +7332,17 @@ declare type ProviderRefusedDetail = NonNullable<Extract<ChatDriverResult, {
6267
7332
  reason: 'done';
6268
7333
  }>['providerRefused']>;
6269
7334
 
7335
+ /**
7336
+ * Register a widget with the platform (GENC-1660): its controller, the element that renders it, how
7337
+ * it behaves while a claimant holds it, and its text form. Once per name, at start-up; a second
7338
+ * registration under the same name replaces the first, with a warning.
7339
+ *
7340
+ * Registering is optional and additive: an unregistered widget works exactly as before.
7341
+ *
7342
+ * @beta
7343
+ */
7344
+ export declare function registerInteraction(name: string, registration: InteractionRegistration): void;
7345
+
6270
7346
  /**
6271
7347
  * Build a {@link TieredAIProviderSwitcher} — which registers the tier-shaped provider
6272
7348
  * registry — and put it on the {@link (AIProviderSwitcher:variable)} token. Call once at app
@@ -6464,6 +7540,23 @@ export declare type RoutingDecision =
6464
7540
  /** A pin or an active flow owned the turn; the classifier was skipped. */
6465
7541
  | 'pinned';
6466
7542
 
7543
+ /**
7544
+ * Run a long action as named steps, checkpointing after each one (GENC-1660 §4.12), so a reload
7545
+ * skips what is already done instead of starting again.
7546
+ *
7547
+ * Starts from the checkpoint the platform handed over, if any — it has already decided, by widget
7548
+ * type and the registration's `sameWork`, that the checkpoint is this work's — or from `initial`, the
7549
+ * identity `sameWork` compares, kept in the checkpoint because the request that cut it is gone.
7550
+ * Each step that is already done is skipped; the rest run in order. `ctx.state.stage` names the step
7551
+ * running, and every step notifies, which is also the watchdog's heartbeat.
7552
+ *
7553
+ * Exported beside the context rather than added to it, so the context's own API stays small.
7554
+ * Throws if `signal` aborts, before or between steps.
7555
+ *
7556
+ * @beta
7557
+ */
7558
+ export declare function runSteps<C extends StepCheckpoint>(ctx: InteractionContext<object, C>, initial: Omit<C, 'done' | 'started'>, steps: readonly Step<C>[], signal?: AbortSignal): Promise<C>;
7559
+
6467
7560
  /**
6468
7561
  * Options for `AiDriver.sendMessage` (GENC-1660).
6469
7562
  *
@@ -6481,6 +7574,12 @@ export declare interface SendMessageOptions {
6481
7574
  * {@link DEFAULT_DELEGATE_FRAMING}. Ignored unless `delegate` is set.
6482
7575
  */
6483
7576
  delegateFraming?: string;
7577
+ /**
7578
+ * What producing the message cost outside the working agent's own model calls — e.g. the model
7579
+ * calls the decorator made to write it — booked on the stored message as `externalCostUsd`, so it
7580
+ * reaches the session total. Ignored unless `delegate` is set and it is a positive, finite number.
7581
+ */
7582
+ externalCostUsd?: number;
6484
7583
  }
6485
7584
 
6486
7585
  /**
@@ -6853,6 +7952,15 @@ export declare interface StatefulAgentInit<S> {
6853
7952
  * reached.
6854
7953
  */
6855
7954
  toolHandlers?: (state: S) => ChatToolHandlers | Promise<ChatToolHandlers>;
7955
+ /**
7956
+ * The autopilot that may answer this agent's interactions on the user's behalf (GENC-1660). Its
7957
+ * resolvers receive this agent's live state, typed. Build it with {@link defineAutopilot}; a
7958
+ * shared definition (a const or a factory) works for any agent.
7959
+ *
7960
+ * Only stateful agents take one: an autopilot is scoped to a flow, and only a stateful agent
7961
+ * owns one.
7962
+ */
7963
+ autopilot?: AutopilotConfig<S>;
6856
7964
  /**
6857
7965
  * Which registered AI provider this agent uses, by name. Either a static
6858
7966
  * string or a function resolved each tool-loop iteration with the current
@@ -6991,6 +8099,45 @@ export declare type StatefulAgentPersistenceContext<S> = Omit<AgentPersistenceCo
6991
8099
  state: S;
6992
8100
  };
6993
8101
 
8102
+ /**
8103
+ * One named step of a long action. A step is either done-or-restart (its output is kept once it
8104
+ * finishes, and a cut one simply runs again) or re-attachable (it saves a job id with `save` before
8105
+ * waiting, and on a re-run finds that id in the checkpoint and reconnects to the job).
8106
+ *
8107
+ * @beta
8108
+ */
8109
+ export declare interface Step<C extends StepCheckpoint> {
8110
+ readonly name: string;
8111
+ /**
8112
+ * Do the step. Returns its outputs, merged into the checkpoint. `save` persists part of an
8113
+ * unfinished step, such as a job id, before a long wait.
8114
+ */
8115
+ run(checkpoint: C, io: {
8116
+ readonly signal?: AbortSignal;
8117
+ save(partial: Partial<C>): void;
8118
+ }): Promise<Partial<C>>;
8119
+ }
8120
+
8121
+ /**
8122
+ * A long action's checkpoint (GENC-1660 §4.12): the steps already done, the steps that started, and
8123
+ * whatever the steps returned or saved. Keep it small, and storable as JSON.
8124
+ *
8125
+ * @beta
8126
+ */
8127
+ export declare type StepCheckpoint = {
8128
+ /** Steps that finished: skipped when the work resumes after a reload. */
8129
+ readonly done: readonly string[];
8130
+ /** Steps that started. One started but not done was cut mid-way, and runs again. */
8131
+ readonly started?: readonly string[];
8132
+ } & Record<string, unknown>;
8133
+
8134
+ /**
8135
+ * How a step went, for the debug log.
8136
+ *
8137
+ * @beta
8138
+ */
8139
+ export declare type StepOutcome = 'started' | 'resumed' | 'done' | 'skipped';
8140
+
6994
8141
  /**
6995
8142
  * A brief, professional fallback agent. States what is available without
6996
8143
  * elaboration. The `{{agents}}` placeholder is replaced at runtime by
@@ -7038,6 +8185,85 @@ export declare type SuggestionsState = {
7038
8185
  message: string;
7039
8186
  };
7040
8187
 
8188
+ /**
8189
+ * One action on a surface, as anyone may read it (GENC-1660).
8190
+ *
8191
+ * @beta
8192
+ */
8193
+ export declare interface SurfaceAction {
8194
+ /** The name to invoke it by: an option's id, or `select` / `reply`. */
8195
+ readonly name: string;
8196
+ /** The text the person sees for it, where it has one. */
8197
+ readonly label?: string;
8198
+ /** Whether running it settles the interaction. Every short-form action does. */
8199
+ readonly finishes: boolean;
8200
+ /** Whether it can be run right now. */
8201
+ readonly enabled: boolean;
8202
+ /**
8203
+ * What its `args` must look like, where it takes any: `options` (a multi-select's picks), `text`
8204
+ * (a written answer) or `fields` (an object, described by `argsSchema`).
8205
+ */
8206
+ readonly args?: 'options' | 'text' | 'fields';
8207
+ /** A full-form action's own description, for the model. Short-form options have none. */
8208
+ readonly description?: string;
8209
+ /** For `fields`: the JSON schema its arguments are checked against. */
8210
+ readonly argsSchema?: Readonly<Record<string, unknown>>;
8211
+ }
8212
+
8213
+ /**
8214
+ * One action of a full-form surface (GENC-1660 §4.2): a named thing a claimant can do, which may or
8215
+ * may not settle the interaction.
8216
+ *
8217
+ * @beta
8218
+ */
8219
+ export declare interface SurfaceActionSpec {
8220
+ /** For the model: what it does, and when to use it. */
8221
+ readonly description: string;
8222
+ /** Whether it settles the interaction. An editing action (`edit_rows`) does not. */
8223
+ readonly finishes?: boolean;
8224
+ /** The button's own guard, read fresh: the claimant can never do what the view would refuse. */
8225
+ readonly enabledWhen?: () => boolean;
8226
+ /**
8227
+ * The JSON schema of its arguments, an object. Its `properties` and `required` are checked before
8228
+ * it runs; a mismatch is refused with the reason, so the model can correct itself.
8229
+ */
8230
+ readonly argsSchema?: Readonly<Record<string, unknown>>;
8231
+ /**
8232
+ * Do it — the SAME code the view's control runs. A finishing action resolves the interaction; an
8233
+ * editing one returns what changed (fresh errors, say), which the claimant is shown.
8234
+ *
8235
+ * A finishing action should settle promptly. While one runs asynchronously, the claimant can run
8236
+ * nothing else, and it keeps the claimant's credit even if the interaction is handed to the person
8237
+ * meanwhile, so the view should block its own controls until it ends: a click that lands then
8238
+ * would be credited to the claimant.
8239
+ */
8240
+ run(args: unknown): unknown | Promise<unknown>;
8241
+ }
8242
+
8243
+ /**
8244
+ * A full-form surface, for a rich widget (GENC-1660 §4.2): something to describe, views to read,
8245
+ * and named actions, some of which only edit.
8246
+ *
8247
+ * Its actions run one at a time. An asynchronous finishing action should settle promptly, and the
8248
+ * view should block its own controls while one runs (see {@link SurfaceActionSpec.run}).
8249
+ *
8250
+ * @beta
8251
+ */
8252
+ export declare interface SurfaceSpec {
8253
+ /** For the model: what this is, and what good looks like. Read fresh. */
8254
+ describe(): string;
8255
+ /** The names of the views `read` answers, e.g. `['summary', 'rows', 'errors']`. */
8256
+ readonly views?: readonly string[];
8257
+ /**
8258
+ * The widget's state as JSON, by view, so a large widget is read a slice at a time. Called with
8259
+ * no view for the default (shown with the decision, so pick something small).
8260
+ */
8261
+ read(view?: string): unknown;
8262
+ readonly actions: Readonly<Record<string, SurfaceActionSpec>>;
8263
+ /** Model-only guidance, beside `describe`. */
8264
+ readonly prompt?: string;
8265
+ }
8266
+
7041
8267
  /**
7042
8268
  * Context passed to the function form of `systemPrompt` / `toolDefinitions`.
7043
8269
  * Resolved each tool-loop iteration so the agent can vary what the LLM sees per turn.