@genesislcap/ai-assistant 15.58.2 → 15.59.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 (58) hide show
  1. package/dist/ai-assistant.api.json +10096 -6986
  2. package/dist/ai-assistant.d.ts +545 -101
  3. package/dist/chat-driver.cjs +624 -207
  4. package/dist/chat-driver.cjs.map +4 -4
  5. package/dist/chat-driver.mjs +624 -207
  6. package/dist/chat-driver.mjs.map +4 -4
  7. package/dist/custom-elements.json +1836 -378
  8. package/dist/dts/components/agent-session/agent-session.d.ts +19 -3
  9. package/dist/dts/components/agent-session/agent-session.d.ts.map +1 -1
  10. package/dist/dts/components/ai-driver/ai-driver.d.ts +120 -10
  11. package/dist/dts/components/ai-driver/ai-driver.d.ts.map +1 -1
  12. package/dist/dts/components/ai-driver/base-driver-decorator.d.ts +103 -0
  13. package/dist/dts/components/ai-driver/base-driver-decorator.d.ts.map +1 -0
  14. package/dist/dts/components/ai-driver/index.d.ts +3 -1
  15. package/dist/dts/components/ai-driver/index.d.ts.map +1 -1
  16. package/dist/dts/components/chat-driver/chat-driver.d.ts +84 -8
  17. package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
  18. package/dist/dts/components/chat-driver/interaction-controller.d.ts +37 -3
  19. package/dist/dts/components/chat-driver/interaction-controller.d.ts.map +1 -1
  20. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +30 -93
  21. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
  22. package/dist/dts/index.d.ts +4 -1
  23. package/dist/dts/index.d.ts.map +1 -1
  24. package/dist/dts/main/main.d.ts +4 -4
  25. package/dist/dts/main/main.d.ts.map +1 -1
  26. package/dist/dts/state/debug-event-log.d.ts +1 -1
  27. package/dist/dts/state/debug-event-log.d.ts.map +1 -1
  28. package/dist/dts/state/interaction-context.d.ts +7 -1
  29. package/dist/dts/state/interaction-context.d.ts.map +1 -1
  30. package/dist/dts/state/persistence/session-persister.d.ts.map +1 -1
  31. package/dist/dts/suggestions/generate-suggestions.d.ts.map +1 -1
  32. package/dist/dts/types/handler-capability.d.ts +28 -0
  33. package/dist/dts/types/handler-capability.d.ts.map +1 -0
  34. package/dist/dts/types/interaction-context.d.ts +16 -0
  35. package/dist/dts/types/interaction-context.d.ts.map +1 -1
  36. package/dist/dts/types/interaction-interceptor.d.ts +109 -0
  37. package/dist/dts/types/interaction-interceptor.d.ts.map +1 -0
  38. package/dist/dts/utils/delegated-message.d.ts +52 -0
  39. package/dist/dts/utils/delegated-message.d.ts.map +1 -0
  40. package/dist/dts/utils/history-transform.d.ts.map +1 -1
  41. package/dist/esm/components/agent-session/agent-session.js +17 -0
  42. package/dist/esm/components/ai-driver/ai-driver.js +21 -1
  43. package/dist/esm/components/ai-driver/base-driver-decorator.js +211 -0
  44. package/dist/esm/components/ai-driver/index.js +2 -1
  45. package/dist/esm/components/chat-driver/chat-driver.js +195 -14
  46. package/dist/esm/components/chat-driver/interaction-controller.js +168 -14
  47. package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +72 -196
  48. package/dist/esm/index.js +1 -0
  49. package/dist/esm/main/main.js +79 -77
  50. package/dist/esm/state/debug-event-log.js +7 -2
  51. package/dist/esm/state/interaction-context.js +11 -0
  52. package/dist/esm/state/persistence/session-persister.js +5 -6
  53. package/dist/esm/suggestions/generate-suggestions.js +8 -1
  54. package/dist/esm/types/handler-capability.js +1 -0
  55. package/dist/esm/types/interaction-interceptor.js +1 -0
  56. package/dist/esm/utils/delegated-message.js +25 -0
  57. package/dist/esm/utils/history-transform.js +12 -1
  58. package/package.json +17 -17
@@ -502,6 +502,12 @@ export declare class AgentSession {
502
502
  * Returns `undefined` when there was no active agent, so a caller can skip its events.
503
503
  */
504
504
  release(): Promise<AgentTransition | undefined>;
505
+ /**
506
+ * Hand a transition to the owner. A throwing listener is logged rather than propagated, for the
507
+ * same reason a throwing hook is: the transition has already happened, and failing the caller
508
+ * would leave it believing it had not.
509
+ */
510
+ private reportTransition;
505
511
  /**
506
512
  * Fire `onDeactivate` on the active agent and abort pending lifecycle work, for session
507
513
  * teardown, so machines release resources cleanly. The session is not reusable afterwards: the
@@ -533,14 +539,24 @@ export declare interface AgentSessionDeps {
533
539
  * after construction on some paths, so a value captured here would pin the wrong one.
534
540
  */
535
541
  sessionKey: () => string;
542
+ /**
543
+ * Called after every real transition (a swap to a different agent, or a release), once the
544
+ * session already reflects it. Not called for a re-activation of the same agent, for the direct
545
+ * {@link AgentSession.setFlowOwner} restore write, or on {@link AgentSession.dispose}.
546
+ *
547
+ * One place for the lifecycle events (GENC-1485): the session is shared between a `ChatDriver`
548
+ * and the `OrchestratingDriver` wrapping it, and either may move it, so the owner learns of a
549
+ * transition here rather than from whichever caller happened to make it.
550
+ */
551
+ onTransition?: (transition: AgentTransition) => void;
536
552
  }
537
553
 
538
554
  /**
539
555
  * What changed when an agent was activated or released.
540
556
  *
541
- * Returned rather than dispatched: the host listens on the `OrchestratingDriver`, not on the
542
- * `ChatDriver` that owns the session, so a self-dispatching session would need telling which
543
- * target to fire on.
557
+ * Returned to the caller, and also reported to the session's owner through
558
+ * {@link AgentSessionDeps.onTransition}, which is how the owning `ChatDriver` raises the lifecycle
559
+ * events whoever triggered the change (GENC-1485).
544
560
  *
545
561
  * @beta
546
562
  */
@@ -557,6 +573,14 @@ export declare interface AgentTransition {
557
573
  flowOwnerChangedTo?: string | null;
558
574
  }
559
575
 
576
+ /**
577
+ * The event types in {@link AiDriverEventMap}, as a runtime list. Built from a record keyed by the
578
+ * map, so adding an event to the map without adding it here is a compile error.
579
+ *
580
+ * @beta
581
+ */
582
+ export declare const AI_DRIVER_EVENT_TYPES: ReadonlyArray<keyof AiDriverEventMap>;
583
+
560
584
  /**
561
585
  * Union of all available animation names, derived from {@link ANIMATION_DEFS}.
562
586
  *
@@ -751,21 +775,22 @@ export declare interface AiDockProvider {
751
775
  }
752
776
 
753
777
  /**
754
- * Common interface implemented by both `ChatDriver` (single-agent) and
755
- * `OrchestratingDriver` (multi-agent). `FoundationAiAssistant` depends only
756
- * on this interface — the concrete class is chosen at startup based on how
757
- * many agents are configured.
778
+ * Common interface implemented by `ChatDriver` (single-agent), `OrchestratingDriver`
779
+ * (multi-agent) and any decorator built on {@link BaseDriverDecorator}. `FoundationAiAssistant`
780
+ * depends only on this interface — the concrete driver is chosen at startup based on how many
781
+ * agents are configured, and may be wrapped.
758
782
  *
759
- * Extends `EventTarget` so consumers can subscribe to `history-updated` events
783
+ * Extends `EventTarget` so consumers can subscribe to the events in {@link AiDriverEventMap}
760
784
  * without knowing the concrete implementation.
761
785
  *
762
786
  * @beta
763
787
  */
764
788
  export declare interface AiDriver extends EventTarget {
765
789
  /**
766
- * Send a user message and run the tool loop to completion.
790
+ * Send a user message and run the tool loop to completion. `options.delegate` sends it on the
791
+ * user's behalf instead (GENC-1660): see {@link SendMessageOptions}.
767
792
  */
768
- sendMessage(input: string, attachments?: ChatAttachment[]): Promise<ChatDriverResult>;
793
+ sendMessage(input: string, attachments?: ChatAttachment[], options?: SendMessageOptions): Promise<ChatDriverResult>;
769
794
  /**
770
795
  * Continue the tool loop from the current history without appending a new
771
796
  * user message. Used by `OrchestratingDriver` on agent handoffs — the
@@ -835,12 +860,17 @@ export declare interface AiDriver extends EventTarget {
835
860
  * than on the next message, then, when `resumeNote` is given and the agent has not opted out,
836
861
  * runs one turn from the restored history with the note in the tail of its first model call.
837
862
  *
863
+ * `agent` is the flow owner's config, for a driver that holds no list of agents to look it up
864
+ * in (GENC-1660): a config cannot be persisted, so after a reload only its name survives, and
865
+ * whoever runs a bare `ChatDriver` is the one that knows which agent it runs. A driver that does
866
+ * hold a list (the orchestrator) looks the owner up itself and ignores this.
867
+ *
838
868
  * Returns the turn's result when one ran, `undefined` otherwise (no flow owner, the owner is not
839
- * configured, or no note). Never throws for those cases.
869
+ * configured or not given, or no note). Never throws for those cases.
840
870
  *
841
871
  * @beta
842
872
  */
843
- resumeRestoredFlow?(resumeNote?: string): Promise<ChatDriverResult | undefined>;
873
+ resumeRestoredFlow?(resumeNote?: string, agent?: AgentConfig): Promise<ChatDriverResult | undefined>;
844
874
  /**
845
875
  * Return the full, unredacted conversation history.
846
876
  */
@@ -914,6 +944,54 @@ export declare interface AiDriver extends EventTarget {
914
944
  * since that ticket's breaking release.
915
945
  */
916
946
  setFlowOwner(name: string | null): void;
947
+ /**
948
+ * The transient flow lock: the name of the stateful agent that owns the current flow, or `null`
949
+ * (GENC-1660). The reading half of {@link AiDriver.setFlowOwner}; changes are announced on
950
+ * `flow-owner-changed`. Lets a decorator scope its behaviour to a flow without reaching for a
951
+ * concrete driver.
952
+ *
953
+ * Optional, so a third-party driver need not implement it; every shipped driver does.
954
+ *
955
+ * @beta
956
+ */
957
+ getFlowOwner?(): string | null;
958
+ /**
959
+ * Install an {@link InteractionInterceptor}: told about every interaction this driver opens,
960
+ * with its live context, and able to claim it and answer it instead of the person (GENC-1660).
961
+ * Interceptors are asked outermost first and the first claim wins. Returns a remover.
962
+ *
963
+ * Optional, so a third-party driver need not implement it; every shipped driver does.
964
+ *
965
+ * @beta
966
+ */
967
+ addInteractionInterceptor?(interceptor: InteractionInterceptor): () => void;
968
+ /**
969
+ * Show a widget in the transcript OUTSIDE any tool loop, and resolve with its result
970
+ * (GENC-1660): `requestInteraction` for something that is not a tool handler. How a decorator
971
+ * asks the person something of its own, such as what to do after a turn failed.
972
+ *
973
+ * It takes the one interaction slot like any other, so a turn that requests an interaction
974
+ * while it is open throws. Pass `options.signal` to close it — unanswered, like a timeout — when
975
+ * the moment passes. Interceptors are offered it like any other, with the active agent (if any)
976
+ * as its owner.
977
+ *
978
+ * Optional, so a third-party driver need not implement it; every shipped driver does.
979
+ *
980
+ * @beta
981
+ */
982
+ presentInteraction?<T = InteractionResult>(componentName: string, data: unknown, options?: InteractionRequestOptions): Promise<T>;
983
+ /**
984
+ * Add a named capability to every tool handler's context, under `context.capabilities[name]`
985
+ * (GENC-1660). How a decorator gives the working agent's handlers something to call — the
986
+ * autopilot's `mode` / `setMode`, say — without the agent knowing the decorator exists.
987
+ * `factory` builds the value per handler call, from who is calling; sub-agents' handlers see
988
+ * their root's capabilities. Returns a remover.
989
+ *
990
+ * Optional, so a third-party driver need not implement it; every shipped driver does.
991
+ *
992
+ * @beta
993
+ */
994
+ provideHandlerCapability?(name: string, factory: HandlerCapabilityFactory): () => void;
917
995
  /**
918
996
  * Headroom the next turn could need, and which agent set that requirement
919
997
  * (GENC-1582). `undefined` when no agent the turn could land on declares a
@@ -1031,6 +1109,53 @@ export declare interface AiDriver extends EventTarget {
1031
1109
  cancel?(): void;
1032
1110
  }
1033
1111
 
1112
+ /**
1113
+ * Every event an {@link AiDriver} can dispatch, by type (GENC-1660).
1114
+ *
1115
+ * The list a decorator forwards: {@link BaseDriverDecorator} re-dispatches each of these from its
1116
+ * inner driver, so an event missing here is an event a host behind a decorator never sees. That is
1117
+ * the failure the orchestrator's hand-written proxy list had twice (`external-cost-recorded`, then
1118
+ * the lifecycle events a bare `ChatDriver` never raised). Details typed `unknown` are forwarded
1119
+ * as-is and not yet described here.
1120
+ *
1121
+ * @beta
1122
+ */
1123
+ export declare interface AiDriverEventMap {
1124
+ /** The transcript changed. Detail: the full history. */
1125
+ 'history-updated': CustomEvent<ReadonlyArray<ChatMessage>>;
1126
+ /** A sub-agent's own transcript changed. */
1127
+ 'sub-agent-history-updated': CustomEvent<unknown>;
1128
+ /** A sub-agent run started. */
1129
+ 'sub-agent-start': CustomEvent<unknown>;
1130
+ /** A sub-agent run ended. */
1131
+ 'sub-agent-stop': CustomEvent<unknown>;
1132
+ /** A blocking interaction that overrides the chat input opened. */
1133
+ 'interaction-start': CustomEvent<unknown>;
1134
+ /** That interaction settled. */
1135
+ 'interaction-stop': CustomEvent<{
1136
+ interactionId: string;
1137
+ }>;
1138
+ /** The provider resolved for a turn changed. */
1139
+ 'provider-changed': CustomEvent<{
1140
+ name: string;
1141
+ }>;
1142
+ /** Spend was recorded against an already-resolved interaction. */
1143
+ 'external-cost-recorded': CustomEvent<{
1144
+ interactionId: string;
1145
+ costUsd: number;
1146
+ }>;
1147
+ /** The active agent changed. Detail: the new agent, or `undefined` after a release. */
1148
+ 'agent-changed': CustomEvent<AgentConfig | undefined>;
1149
+ /** A stateful agent released its flow. Detail: the released agent. */
1150
+ 'agent-released': CustomEvent<AgentConfig>;
1151
+ /** The flow-owner lock changed. Detail: the new owner's name, or `null` when cleared. */
1152
+ 'flow-owner-changed': CustomEvent<string | null>;
1153
+ /** Routing started (the classifier is about to run). Orchestrator only. */
1154
+ 'orchestrating-start': CustomEvent<undefined>;
1155
+ /** Routing finished and an agent is installed. Orchestrator only. */
1156
+ 'orchestrating-stop': CustomEvent<undefined>;
1157
+ }
1158
+
1034
1159
  /**
1035
1160
  * Optional app-registered policy for which cloud vendor backs the tier-shaped
1036
1161
  * provider registry slots (`low` / `high` / …). Apps inject a concrete
@@ -1525,6 +1650,97 @@ declare interface BaseAgentConfig {
1525
1650
  contextReserve?: ContextReserveInput;
1526
1651
  }
1527
1652
 
1653
+ /**
1654
+ * The base of every driver decorator (GENC-1660): an {@link AiDriver} that wraps another and
1655
+ * passes every member, and every event in {@link AiDriverEventMap}, through to it.
1656
+ *
1657
+ * A decorator extends this and overrides only what it changes, so decorators stack in any order
1658
+ * and a member or event added to `AiDriver` reaches the host through every layer by default.
1659
+ * `OrchestratingDriver` is one; it used to forward by hand, and twice a member it did not forward
1660
+ * silently did nothing for every multi-agent host (`recordExternalCost`, then
1661
+ * `getHistoryForPersistence`).
1662
+ *
1663
+ * Abstract with no abstract members, so it cannot be constructed on its own: a decorator that
1664
+ * changes nothing is not one.
1665
+ *
1666
+ * Optional `AiDriver` members are implemented here unconditionally, as a forward that falls back
1667
+ * to the "not supported" answer when the inner driver lacks them. A host that feature-detects with
1668
+ * `?.` therefore always finds them, and gets the same answer it would from the inner driver.
1669
+ *
1670
+ * @beta
1671
+ */
1672
+ export declare abstract class BaseDriverDecorator<TInner extends AiDriver = AiDriver> extends EventTarget implements AiDriver {
1673
+ protected readonly inner: TInner;
1674
+ /** Undoes this layer's hold on its inner driver; see {@link BaseDriverDecorator.detach}. */
1675
+ private readonly detachers;
1676
+ protected constructor(inner: TInner);
1677
+ /**
1678
+ * Let go of the inner driver WITHOUT disposing it: stop forwarding its events, and undo whatever
1679
+ * a subclass registered through {@link BaseDriverDecorator.onDetach} (its interceptors, its
1680
+ * capabilities, its own listeners). For dropping or replacing a decorator while the driver it
1681
+ * wrapped lives on — otherwise the old layer keeps re-dispatching every event and is never
1682
+ * collected. Idempotent. `dispose()` detaches too.
1683
+ */
1684
+ detach(): void;
1685
+ /** Register something {@link BaseDriverDecorator.detach} must undo. */
1686
+ protected onDetach(undo: () => void): void;
1687
+ sendMessage(input: string, attachments?: ChatAttachment[], options?: SendMessageOptions): Promise<ChatDriverResult>;
1688
+ continueFromHistory(transientPrimer?: ChatMessage[], options?: ContinueFromHistoryOptions): Promise<ChatDriverResult>;
1689
+ resolveInteraction(interactionId: string, result: unknown): void;
1690
+ recordExternalCost(interactionId: string, costUsd: number): boolean;
1691
+ getInteractionContext(interactionId: string): InteractionContext | undefined;
1692
+ loadHistory(messages: ChatMessage[]): void;
1693
+ primeRestoredAgentState(snapshots: Record<string, unknown>): void;
1694
+ canRestoreFlowOwner(agentName: string): boolean;
1695
+ canResumeRestoredFlow(agentName: string): boolean;
1696
+ resumeRestoredFlow(resumeNote?: string, agent?: AgentConfig): Promise<ChatDriverResult | undefined>;
1697
+ getRawHistory(): readonly ChatMessage[];
1698
+ getHistoryForPersistence(): ChatMessage[];
1699
+ getCondensePoliciesForPersistence(messages: readonly ChatMessage[]): PersistedCondensePolicy[];
1700
+ restoreCondensePolicies(entries: readonly unknown[] | undefined): {
1701
+ restored: number;
1702
+ awaitingReactivation: number;
1703
+ };
1704
+ getActiveAgent(): AgentConfig | undefined;
1705
+ setPinnedAgent(name: string | null): void;
1706
+ setFlowOwner(name: string | null): void;
1707
+ getFlowOwner(): string | null;
1708
+ /**
1709
+ * Forwarded, so an interceptor installed on any layer lands on the driver that opens the
1710
+ * interactions. A decorator that answers interactions installs its own on `this.inner`.
1711
+ */
1712
+ addInteractionInterceptor(interceptor: InteractionInterceptor): () => void;
1713
+ presentInteraction<T = InteractionResult>(componentName: string, data: unknown, options?: InteractionRequestOptions): Promise<T>;
1714
+ provideHandlerCapability(name: string, factory: HandlerCapabilityFactory): () => void;
1715
+ getContextReserve(): ContextReserveResolution | undefined;
1716
+ getPreambleTokens(): number | undefined;
1717
+ setContextGuard(policy?: ContextGuardPolicy): void;
1718
+ compact(options?: CompactionPlanOptions): Promise<ChatMessage | null>;
1719
+ getCompactionPlan(options?: CompactionPlanOptions): CompactionProjection | null;
1720
+ canCompact(options?: CompactionPlanOptions): boolean;
1721
+ isBusy(): boolean;
1722
+ getSuggestions(history: ChatMessage[], prompt: string, count: number, allAgentInfo?: AllAgentSummary[]): Promise<string[]>;
1723
+ getTurnSnapshots(): ReadonlyArray<TurnSnapshot>;
1724
+ /**
1725
+ * The inner driver's entries. Diagnostics compose down the stack: a decorator with entries of
1726
+ * its own overrides this and appends them to `super.getExternalDiagnostics()`.
1727
+ */
1728
+ getExternalDiagnostics(): ReadonlyArray<DiagnosticEntry>;
1729
+ getActiveProviderName(): string;
1730
+ dispose(): void | Promise<void>;
1731
+ cancel(): void;
1732
+ /**
1733
+ * Every driver in the stack, outermost first: `driver`, then each inner driver down to the one
1734
+ * that is not a decorator.
1735
+ *
1736
+ * For diagnostics and labelling only: behaviour must go through `AiDriver` members, which every
1737
+ * layer forwards, never through a concrete class found here.
1738
+ *
1739
+ * @internal
1740
+ */
1741
+ static layers(driver: AiDriver): AiDriver[];
1742
+ }
1743
+
1528
1744
  /**
1529
1745
  * Id of the blocked banner, referenced by the composer controls'
1530
1746
  * `aria-describedby`. Shadow-DOM-scoped, so a fixed string cannot collide with
@@ -1822,6 +2038,13 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
1822
2038
  private unlinkLifecycleFromMessage?;
1823
2039
  /** A sub-agent runs inside its parent's message: the parent's `turnSignal`, handed down. */
1824
2040
  private inheritedTurnSignal?;
2041
+ /** Capabilities provided on this driver by decorators (GENC-1660). Only the root's are used. */
2042
+ private readonly handlerCapabilities;
2043
+ /**
2044
+ * For a sub-agent's driver, the driver that invoked it: its capabilities, flow owner and owner
2045
+ * path are the ones this driver's handlers see, so a capability reaches sub-agents unchanged.
2046
+ */
2047
+ private capabilityParent?;
1825
2048
  /**
1826
2049
  * Active agent's provider selector (static name or per-turn resolver).
1827
2050
  * `undefined` means "use the registry default".
@@ -1926,6 +2149,11 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
1926
2149
  * the point: two would let `getActiveAgent()` disagree between the outer and inner driver.
1927
2150
  * `@internal` rather than private so that reach is legal without six delegating one-liners.
1928
2151
  *
2152
+ * **This driver raises the lifecycle events for every transition of the session**, whoever made
2153
+ * it: itself, through {@link ChatDriver.activateAgent} or a release, or the orchestrator reaching
2154
+ * through (GENC-1485). Before, only the orchestrator dispatched them, so a host on a bare
2155
+ * `ChatDriver` never learned its flow owner.
2156
+ *
1929
2157
  * @internal
1930
2158
  */
1931
2159
  readonly agentSession: AgentSession;
@@ -2199,6 +2427,30 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
2199
2427
  * @beta
2200
2428
  */
2201
2429
  activateAgent(config: AgentConfig): Promise<void>;
2430
+ /**
2431
+ * {@inheritDoc AiDriver.resumeRestoredFlow}
2432
+ *
2433
+ * This driver holds no list of agents, so it resumes only the `agent` it is handed (GENC-1660):
2434
+ * whoever runs a bare `ChatDriver` knows which agent that is, and after a reload only the name
2435
+ * survived. Without one it does nothing, as a driver without this member did before; given one
2436
+ * that is not the restored flow owner, it refuses.
2437
+ *
2438
+ * For headless callers: the shipped host restores and resumes through `OrchestratingDriver`,
2439
+ * and a bare `ChatDriver` does not answer `canRestoreFlowOwner`, so the host never plans a resume
2440
+ * for one.
2441
+ *
2442
+ * The orchestrator does not delegate here, because it installs a decorated config of its own;
2443
+ * this is the bare-driver path.
2444
+ *
2445
+ * @beta
2446
+ */
2447
+ resumeRestoredFlow(resumeNote?: string, agent?: AgentConfig): Promise<ChatDriverResult | undefined>;
2448
+ /**
2449
+ * Raise the host-facing lifecycle events for one session transition (GENC-1485), in the order
2450
+ * the orchestrator raised them before it stopped doing so itself: the flow lock first, then the
2451
+ * release, then the active agent.
2452
+ */
2453
+ private dispatchAgentTransition;
2202
2454
  /**
2203
2455
  * {@inheritDoc AiDriver.getActiveAgent}
2204
2456
  *
@@ -2226,6 +2478,12 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
2226
2478
  * @beta
2227
2479
  */
2228
2480
  setFlowOwner(name: string | null): void;
2481
+ /**
2482
+ * {@inheritDoc AiDriver.getFlowOwner}
2483
+ *
2484
+ * @beta
2485
+ */
2486
+ getFlowOwner(): string | null;
2229
2487
  /**
2230
2488
  * Install `config` as the active agent **without firing lifecycle hooks**.
2231
2489
  *
@@ -2528,7 +2786,38 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
2528
2786
  * and `presentation` to control whether the host wraps the widget in a chat
2529
2787
  * bubble and/or shows the "Assistant" label.
2530
2788
  */
2531
- requestInteraction<T>(componentName: string, data: any, options?: InteractionRequestOptions, onOpened?: (interactionId: string) => void): Promise<T>;
2789
+ requestInteraction<T>(componentName: string, data: any, options?: InteractionRequestOptions, onOpened?: (interactionId: string) => void, innerPath?: readonly string[], onSettled?: (settled: InteractionSettled) => void): Promise<T>;
2790
+ /**
2791
+ * {@inheritDoc AiDriver.addInteractionInterceptor}
2792
+ *
2793
+ * Consulted only on the root driver, where every interaction opens: a sub-agent's request
2794
+ * travels up to its root, carrying its owner path, and is offered there once.
2795
+ *
2796
+ * @beta
2797
+ */
2798
+ addInteractionInterceptor(interceptor: InteractionInterceptor): () => void;
2799
+ /**
2800
+ * {@inheritDoc AiDriver.presentInteraction}
2801
+ *
2802
+ * @beta
2803
+ */
2804
+ presentInteraction<T = InteractionResult>(componentName: string, data: unknown, options?: InteractionRequestOptions): Promise<T>;
2805
+ /**
2806
+ * {@inheritDoc AiDriver.provideHandlerCapability}
2807
+ *
2808
+ * Throws if `name` is already provided: two decorators answering to one name would leave a
2809
+ * handler unable to tell which it is talking to.
2810
+ *
2811
+ * @beta
2812
+ */
2813
+ provideHandlerCapability(name: string, factory: HandlerCapabilityFactory): () => void;
2814
+ /**
2815
+ * The capabilities this driver's handlers see, and who they see them as: the root's factories,
2816
+ * the root's flow owner, and the owner path from the root down to this driver's agent.
2817
+ */
2818
+ private capabilityScope;
2819
+ /** Build `context.capabilities` for one handler call, or `undefined` when nothing is provided. */
2820
+ private buildCapabilities;
2532
2821
  /**
2533
2822
  * Record what came of an interaction, after it resolved, on its history message
2534
2823
  * (`interaction.outcome`): handed to its widget and persisted with the session, never sent to a
@@ -2583,7 +2872,7 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
2583
2872
  * can continue an existing conversation. Call this before the first user message.
2584
2873
  */
2585
2874
  loadHistory(messages: ChatMessage[]): void;
2586
- sendMessage(userInput: string, attachments?: ChatAttachment[]): Promise<ChatDriverResult>;
2875
+ sendMessage(userInput: string, attachments?: ChatAttachment[], options?: SendMessageOptions): Promise<ChatDriverResult>;
2587
2876
  /**
2588
2877
  * Builds the context object passed to every tool handler call.
2589
2878
  * Centralised here so fold shortcut dispatch and the main tool loop use the
@@ -2714,10 +3003,10 @@ export declare interface ChatDriverConfig {
2714
3003
  * Leave acting on `releaseAgent` to the owner of this driver.
2715
3004
  *
2716
3005
  * Set by `OrchestratingDriver` for its inner driver, which performs the release itself after the
2717
- * turn so it can fire the host-facing `agent-released` / `agent-changed` / `flow-owner-changed`
2718
- * events. Both drivers share one `AgentSession`, so releasing here first would empty it and make
2719
- * the orchestrator's own release a silent no-op — leaving the host with a locked picker and a
2720
- * stale active agent.
3006
+ * turn, because a release ends its handoff loop and it reads the flag to know. Both drivers share
3007
+ * one `AgentSession`, and releasing here first would clear the flag before the orchestrator saw
3008
+ * it. The host-facing `agent-released` / `agent-changed` / `flow-owner-changed` events fire from
3009
+ * the session's transition either way (GENC-1485).
2721
3010
  *
2722
3011
  * Left unset, a driver releases its own agent, which is what a bare `ChatDriver` needs: nothing
2723
3012
  * else is watching the flag.
@@ -3112,6 +3401,14 @@ export declare interface DebugLog {
3112
3401
  */
3113
3402
  export declare const DEFAULT_ANIMATIONS: AiAssistantAnimation[];
3114
3403
 
3404
+ /**
3405
+ * How a delegated `user` message is framed for the model when its sender gives no phrase. Names no
3406
+ * decorator, so the model has none to repeat.
3407
+ *
3408
+ * @beta
3409
+ */
3410
+ export declare const DEFAULT_DELEGATE_FRAMING = "Sent on the user's behalf.";
3411
+
3115
3412
  /**
3116
3413
  * Identity helper that infers the narrowest possible type for an agent config,
3117
3414
  * preserving string literal types (including `name`) without requiring `as const`.
@@ -3156,6 +3453,36 @@ export declare function defineAgent<const T extends AgentConfig>(config: T): T;
3156
3453
  */
3157
3454
  export declare function defineStatefulAgent<S>(opts: StatefulAgentInit<S>): AgentConfig;
3158
3455
 
3456
+ /**
3457
+ * What the working agent is told about an interaction an interceptor answered (GENC-1660): added
3458
+ * to the result of the tool call that requested it, as `decidedOnUsersBehalf` on an object result
3459
+ * or as a line appended to a text one.
3460
+ *
3461
+ * Built only from what the platform already holds — the claimant's framing, and the choice and
3462
+ * narration it recorded — so the text the person saw and the text the agent is told about are the
3463
+ * same string. It never names the claimant, so the agent has nothing to repeat about one.
3464
+ *
3465
+ * @beta
3466
+ */
3467
+ export declare interface DelegatedDecision {
3468
+ /** The claimant's {@link InteractionInterceptor.decisionFraming}, e.g. "Decided on the user's behalf". */
3469
+ readonly framing: string;
3470
+ /** What was chosen, as recorded by the claimant. */
3471
+ readonly choice?: string;
3472
+ /** What the person was shown about it, verbatim, as the assistant's own words. */
3473
+ readonly shownToUser?: string;
3474
+ }
3475
+
3476
+ /**
3477
+ * A message written or sent on the user's behalf by a driver decorator (GENC-1660). See
3478
+ * `ChatMessage.delegate`.
3479
+ *
3480
+ * @beta
3481
+ */
3482
+ export declare type DelegatedMessage = ChatMessage & {
3483
+ delegate: string;
3484
+ };
3485
+
3159
3486
  /**
3160
3487
  * One entry in the diagnostics stream — the debug-log timeline-entry union
3161
3488
  * (`message` / `turn` / `event`, as `getDebugLog()` builds) plus a point-in-time
@@ -4162,11 +4489,11 @@ export declare class FoundationAiAssistant extends GenesisElement {
4162
4489
  showingSplash: boolean;
4163
4490
  private driver?;
4164
4491
  /**
4165
- * This element's driver as an orchestrator, or `undefined` when the session is running a bare
4166
- * `ChatDriver`. The only place in this element that narrows the type; the test itself lives in
4167
- * `asOrchestrator`, shared with the session persister.
4492
+ * Which kind of driver this element runs, for the `driver.created` / `assistant.connected` log
4493
+ * lines only. Looks through any decorators (GENC-1660): behaviour goes through `AiDriver`
4494
+ * members, which every layer forwards, so this is the one place the concrete class matters.
4168
4495
  */
4169
- private get orchestrator();
4496
+ private get driverKind();
4170
4497
  private driverCleanup?;
4171
4498
  private loadingTimer;
4172
4499
  private unsubBus?;
@@ -5249,6 +5576,35 @@ export declare type GenesisWriteReviewCompletedEventDetail = InteractionResult<G
5249
5576
  */
5250
5577
  export declare function getAiPopoutManager(): FoundationAiPopoutManager | undefined;
5251
5578
 
5579
+ /**
5580
+ * Builds a capability's value for one tool-handler call (GENC-1660). Called per call, so it can
5581
+ * reflect the moment; it should be cheap and must not throw (a throw is logged and the capability
5582
+ * left out of that call). Returning `undefined` leaves the capability out, which is how a decorator
5583
+ * says "not available here".
5584
+ *
5585
+ * @beta
5586
+ */
5587
+ export declare type HandlerCapabilityFactory = (scope: HandlerCapabilityScope) => unknown;
5588
+
5589
+ /**
5590
+ * Who a handler capability is being built for (GENC-1660): the tool handler about to run.
5591
+ *
5592
+ * @beta
5593
+ */
5594
+ export declare interface HandlerCapabilityScope {
5595
+ /**
5596
+ * The agents from the root down to the one whose handler is running, outermost first — e.g.
5597
+ * `['bootstrap', 'brief-critic']` for a sub-agent's handler. The same shape as
5598
+ * `InteractionOpened.ownerPath`, so a decorator scopes the two the same way.
5599
+ */
5600
+ readonly ownerPath: readonly string[];
5601
+ /**
5602
+ * The root driver's flow owner when the handler runs, or `null`. A sub-agent has no flow of its
5603
+ * own, so it sees its root's: a capability scoped to a flow applies to the flow's sub-agents.
5604
+ */
5605
+ readonly flowOwner: string | null;
5606
+ }
5607
+
5252
5608
  /**
5253
5609
  * A single in-flight per-call chat-input override pushed by a `requestSubAgent`
5254
5610
  * or `requestInteraction` call. Tracked as an array (not a counter) so the
@@ -5303,6 +5659,15 @@ export declare type InteractionCompletedEventDetail = ChatInteractionEventsMap['
5303
5659
  export declare interface InteractionContext<TState extends object = Record<string, unknown>> {
5304
5660
  /** Stable id of the interaction this context belongs to. */
5305
5661
  readonly interactionId: string;
5662
+ /**
5663
+ * Who holds this pending interaction right now: `'user'`, or the id of the interceptor that
5664
+ * claimed it, e.g. `'autopilot'` (GENC-1660). `'user'` unless something claimed it.
5665
+ *
5666
+ * Reactive through {@link InteractionContext.subscribe}: a change calls `notify()`, so a view
5667
+ * must re-read it on every notification rather than once on mount, or it would stay hidden after
5668
+ * a hand-back. Only the claimant changes it, through its `InteractionHold`.
5669
+ */
5670
+ readonly heldBy: InteractionHolder;
5306
5671
  /**
5307
5672
  * Durable, remount-surviving source of truth for the interaction — a socket
5308
5673
  * handle, the current phase, a half-typed draft. A plain object, deliberately
@@ -5355,11 +5720,120 @@ export declare interface InteractionContext<TState extends object = Record<strin
5355
5720
  */
5356
5721
  export declare type InteractionCostEventDetail = ChatInteractionEventsMap['interaction-cost'];
5357
5722
 
5723
+ /**
5724
+ * The handle an interceptor uses to move a pending interaction between the person and itself
5725
+ * (GENC-1660): to the person when it hands back or is paused, back to itself when resumed.
5726
+ *
5727
+ * Every interceptor is offered one, but only the claimant's works: on any other interceptor's
5728
+ * handle, and after the interaction ends, its members do nothing and return `false`. A claim is
5729
+ * granted only once `onInteractionOpened` has returned `'claim'` (it may yet be refused), so the
5730
+ * claimant's own handle does nothing until then either: act on it afterwards. Views read the
5731
+ * result as `ctx.heldBy`; they never change it.
5732
+ *
5733
+ * @beta
5734
+ */
5735
+ export declare interface InteractionHold {
5736
+ /**
5737
+ * Give the interaction to the person (`'user'`) or back to the claimant (`'claimant'`). Notifies
5738
+ * the context's subscribers and records `interaction.held`. Returns whether it applied.
5739
+ */
5740
+ set(holder: 'user' | 'claimant'): boolean;
5741
+ /**
5742
+ * Say what the claimant decided, before it settles the interaction, so the tool that asked is
5743
+ * told honestly (GENC-1660). When the interaction then resolves while the claimant holds it, the
5744
+ * driver adds a {@link DelegatedDecision} built from this to that tool's result, so the working
5745
+ * agent learns the choice was made on the user's behalf and what the user was shown about it.
5746
+ *
5747
+ * Optional to call: without it the record carries only the framing. Later calls replace earlier
5748
+ * ones. Returns `false`, recording nothing, unless this interceptor holds the interaction.
5749
+ */
5750
+ recordDecision(decision: {
5751
+ choice?: string;
5752
+ shownToUser?: string;
5753
+ }): boolean;
5754
+ /**
5755
+ * Settle the interaction AS the claimant (GENC-1660). The only route that stamps the claimant as
5756
+ * `answeredBy`: an answer through the host's `resolveInteraction` — a click — is the person's,
5757
+ * whoever held the interaction at the time, so attribution never depends on a view honouring
5758
+ * `heldBy`. Returns `false`, settling nothing, unless this interceptor holds it right now.
5759
+ */
5760
+ resolve(result: unknown): boolean;
5761
+ }
5762
+
5763
+ /**
5764
+ * Who holds a pending interaction: the person, or the id of the interceptor that claimed it
5765
+ * (GENC-1660). See {@link InteractionContext.heldBy}.
5766
+ *
5767
+ * @beta
5768
+ */
5769
+ export declare type InteractionHolder = 'user' | (string & {});
5770
+
5771
+ /**
5772
+ * Something that is told about every interaction a driver opens, and may answer it instead of the
5773
+ * person (GENC-1660). Installed with `AiDriver.addInteractionInterceptor`, typically by a driver
5774
+ * decorator such as an autopilot or a test harness.
5775
+ *
5776
+ * Interceptors are asked outermost first. The first to claim an interaction holds it; the rest
5777
+ * observe — they see the same context but their `hold` does nothing. Nobody can claim a `userOnly`
5778
+ * interaction. A throwing interceptor is logged and treated as abstaining.
5779
+ *
5780
+ * @beta
5781
+ */
5782
+ export declare interface InteractionInterceptor {
5783
+ /** The holder id this interceptor's claims are recorded under, e.g. `'autopilot'`. Not `'user'`. */
5784
+ readonly id: string;
5785
+ /**
5786
+ * How a {@link DelegatedDecision} it settled opens, as the working agent reads it. Must not name
5787
+ * the interceptor. Defaults to "Decided on the user's behalf"; an autopilot grounded in a brief
5788
+ * would say "Decided on the user's behalf, from their brief".
5789
+ */
5790
+ readonly decisionFraming?: string;
5791
+ /** Return `'claim'` to hold the interaction, or nothing to leave it with the person. */
5792
+ onInteractionOpened(opened: InteractionOpened): 'claim' | undefined | void;
5793
+ }
5794
+
5795
+ /**
5796
+ * A new interaction, as offered to each installed interceptor (GENC-1660).
5797
+ *
5798
+ * Offered once, at the root driver, after its context exists and before its message is appended,
5799
+ * so the first render of its widget already knows who holds it.
5800
+ *
5801
+ * @beta
5802
+ */
5803
+ export declare interface InteractionOpened {
5804
+ readonly interactionId: string;
5805
+ readonly componentName: string;
5806
+ /** The `data` the widget was requested with. */
5807
+ readonly data: unknown;
5808
+ /**
5809
+ * The agents that asked for it, outermost first: the root's active agent, then each sub-agent
5810
+ * the request travelled up through — e.g. `['bootstrap', 'brief-critic']`. The last entry is the
5811
+ * agent whose tool handler called `requestInteraction`.
5812
+ */
5813
+ readonly ownerPath: readonly string[];
5814
+ /** Set from `InteractionRequestOptions.userOnly`: nobody may claim it. */
5815
+ readonly userOnly: boolean;
5816
+ /** The interaction's live context, the same object its widget is handed. */
5817
+ readonly ctx: InteractionContext;
5818
+ /** See {@link InteractionHold}. Works only for the interceptor whose claim was granted. */
5819
+ readonly hold: InteractionHold;
5820
+ }
5821
+
5358
5822
  /**
5359
5823
  * Opens an interaction somewhere else — the parent driver, for a sub-agent's — and tells
5360
- * `onOpened` its id.
5824
+ * `onOpened` its id. `ownerPath` is the agents the request has already come up through, outermost
5825
+ * first, so the root can tell interceptors who asked (GENC-1660).
5826
+ */
5827
+ declare type InteractionRequester = <T>(componentName: string, data: any, options?: InteractionRequestOptions, onOpened?: (interactionId: string) => void, ownerPath?: readonly string[], onSettled?: (settled: InteractionSettled) => void) => Promise<T>;
5828
+
5829
+ /**
5830
+ * Who answered an interaction, as its requester is told (GENC-1660). `answeredBy` is absent when it
5831
+ * closed unanswered (a timeout or a stop); `decision` is present when an interceptor answered.
5361
5832
  */
5362
- declare type InteractionRequester = <T>(componentName: string, data: any, options?: InteractionRequestOptions, onOpened?: (interactionId: string) => void) => Promise<T>;
5833
+ declare interface InteractionSettled {
5834
+ readonly answeredBy?: string;
5835
+ readonly decision?: DelegatedDecision;
5836
+ }
5363
5837
 
5364
5838
  /**
5365
5839
  * A message's interaction widget, in the wrapper that mounts it. Everything the widget is shown
@@ -5373,6 +5847,14 @@ export declare const interactionWrapperTemplate: ViewTemplate<ChatMessage, Found
5373
5847
  /** True when the assistant is active in the layout panel (docked) rather than the bubble. */
5374
5848
  export declare function isAiAssistantDocked(): boolean;
5375
5849
 
5850
+ /**
5851
+ * Whether `message` was written or sent on the user's behalf. A delegated message renders as the
5852
+ * assistant, whatever its role.
5853
+ *
5854
+ * @beta
5855
+ */
5856
+ export declare const isDelegated: (message: ChatMessage) => message is DelegatedMessage;
5857
+
5376
5858
  /**
5377
5859
  * The interchangeable "assistant is working" loading-indicator styles. At most
5378
5860
  * one of these may be enabled at a time — enabling one disables the other.
@@ -5454,12 +5936,19 @@ export declare const NOOP_ACTIVITY_BUS: ActivityBus;
5454
5936
  * and `ChatDriver`, classifying each user message and routing it to the right
5455
5937
  * specialist — each with its own focused system prompt, tools, and primer.
5456
5938
  *
5939
+ * A {@link BaseDriverDecorator} over the `ChatDriver` it constructs (GENC-1485, GENC-1660): every
5940
+ * `AiDriver` member and event it does not override passes straight through. Its inner driver is
5941
+ * always one it built, never a composition choice, because routing reaches `ChatDriver`-only
5942
+ * members (`installAgent`, `agentSession`, `getHistory`, `setProviderHistoryTransform`, the
5943
+ * release flag and the `report…` exits). Other decorators go outside it.
5944
+ *
5457
5945
  * @beta
5458
5946
  */
5459
- export declare class OrchestratingDriver extends EventTarget implements AiDriver {
5947
+ export declare class OrchestratingDriver extends BaseDriverDecorator<ChatDriver> {
5460
5948
  private readonly providerRegistry;
5461
5949
  private readonly agents;
5462
- private readonly chatDriver;
5950
+ /** The inner driver this one built and routes onto. */
5951
+ private get chatDriver();
5463
5952
  private readonly specialists;
5464
5953
  private readonly fallback?;
5465
5954
  private readonly maxHandoffs;
@@ -5516,80 +6005,14 @@ export declare class OrchestratingDriver extends EventTarget implements AiDriver
5516
6005
  /** AI service error copy, passed through to the inner ChatDriver (GENC-1611). */
5517
6006
  aiServiceErrorMessages?: Partial<Record<AIServiceRefusal, string>>;
5518
6007
  });
5519
- resolveInteraction(interactionId: string, result: unknown): void;
5520
- /** Delegated for the same reason as `resolveInteraction`: the history that owns the
5521
- * interaction — and therefore the cost — lives on the wrapped driver, not here. */
5522
- recordExternalCost(interactionId: string, costUsd: number): boolean;
5523
- getInteractionContext(interactionId: string): InteractionContext | undefined;
5524
- isBusy(): boolean;
5525
- /** Currently active provider name from the underlying ChatDriver. */
5526
- getActiveProviderName(): string;
5527
- /**
5528
- * Pins routing to a specific agent by name. While pinned, the classifier is
5529
- * skipped and the continuation tool is hidden from the agent's tool list, so
5530
- * the agent cannot quietly hand back to the orchestrator. Pass `null` to
5531
- * return to automatic routing.
5532
- */
5533
- setPinnedAgent(name: string | null): void;
5534
6008
  /**
5535
- * Set the flow-owner lock — used to restore state from Redux on driver
5536
- * reconstruction (agents-array changes, pop-in/pop-out). Not intended for
5537
- * external callers to manipulate routing; that's what `setPinnedAgent` is
5538
- * for.
6009
+ * Build the inner driver, after validating the agents' providers, so a bad config throws before
6010
+ * a driver exists to subscribe to the registry. Static because it runs before `super()`.
5539
6011
  */
5540
- setFlowOwner(name: string | null): void;
5541
- loadHistory(messages: ChatMessage[]): void;
5542
- getRawHistory(): readonly ChatMessage[];
5543
- /**
5544
- * Delegates to the inner {@link ChatDriver} — condensation policies are registered there, so it
5545
- * is the only object that knows which payloads the model has stopped seeing (GENC-1566).
5546
- *
5547
- * **This forward is the whole feature, for any multi-agent host.** `AiDriver` declares
5548
- * `getHistoryForPersistence` optional, and `SessionPersister` calls it through `?.`, falling back
5549
- * to {@link OrchestratingDriver.getRawHistory}. This class does NOT extend `ChatDriver` — it
5550
- * wraps one — so without an explicit forward the optional call resolves to `undefined` and every
5551
- * host on an orchestrating driver silently keeps persisting the full payloads. Measured exactly
5552
- * that way on a Create run: 10 `context.condensed` events fired, and the session still stored
5553
- * the two largest `read_context` results at 26,907 and 23,060 chars. The method existed, the
5554
- * tests passed, and the feature did nothing.
5555
- */
5556
- getHistoryForPersistence(): ChatMessage[];
5557
- /**
5558
- * Delegates to the inner {@link ChatDriver}, which owns the condensation registry and clocks
5559
- * (GENC-1632). The forward matters for the same reason as `getHistoryForPersistence` above: the
5560
- * persister reaches it through `?.`, so a missing forward would compile, pass the ChatDriver
5561
- * tests, and do nothing for every orchestrated host — which is every host with an agents array.
5562
- */
5563
- getCondensePoliciesForPersistence(messages: readonly ChatMessage[]): PersistedCondensePolicy[];
5564
- /**
5565
- * Delegates to the inner {@link ChatDriver} (GENC-1632). The deferred activation stamp it
5566
- * performs is taken by the inner driver's `installAgent`, which this driver's own
5567
- * `installAgent` always reaches, so nothing extra is needed here.
5568
- */
5569
- restoreCondensePolicies(entries: readonly unknown[] | undefined): {
5570
- restored: number;
5571
- awaitingReactivation: number;
5572
- };
5573
- /** {@inheritDoc AiDriver.setContextGuard} */
5574
- setContextGuard(policy?: ContextGuardPolicy): void;
5575
- /** {@inheritDoc AiDriver.compact} */
5576
- compact(options?: CompactionPlanOptions): Promise<ChatMessage | null>;
5577
- /** {@inheritDoc AiDriver.canCompact} */
5578
- canCompact(options?: CompactionPlanOptions): boolean;
5579
- /** {@inheritDoc AiDriver.getPreambleTokens} */
5580
- getPreambleTokens(): number | undefined;
5581
- /** {@inheritDoc AiDriver.getCompactionPlan} */
5582
- getCompactionPlan(options?: CompactionPlanOptions): CompactionProjection | null;
5583
- /** Delegates to the inner {@link ChatDriver} — turns are captured there. */
5584
- getTurnSnapshots(): ReadonlyArray<TurnSnapshot>;
5585
- /** Delegates to the inner {@link ChatDriver} — interactions resolve there, so it holds the buffer. */
5586
- getExternalDiagnostics(): ReadonlyArray<DiagnosticEntry>;
6012
+ private static createInner;
5587
6013
  getSuggestions(history: ChatMessage[], prompt: string, count: number, allAgentInfo?: AllAgentSummary[]): Promise<string[]>;
5588
- sendMessage(input: string, attachments?: ChatAttachment[]): Promise<ChatDriverResult>;
6014
+ sendMessage(input: string, attachments?: ChatAttachment[], options?: SendMessageOptions): Promise<ChatDriverResult>;
5589
6015
  private runOrchestratedTurn;
5590
- continueFromHistory(transientPrimer?: ChatMessage[], options?: ContinueFromHistoryOptions): Promise<ChatDriverResult>;
5591
- /** {@inheritDoc AiDriver.primeRestoredAgentState} */
5592
- primeRestoredAgentState(snapshots: Record<string, unknown>): void;
5593
6016
  /** {@inheritDoc AiDriver.canRestoreFlowOwner} */
5594
6017
  canRestoreFlowOwner(agentName: string): boolean;
5595
6018
  /** {@inheritDoc AiDriver.canResumeRestoredFlow} */
@@ -5601,6 +6024,10 @@ export declare class OrchestratingDriver extends EventTarget implements AiDriver
5601
6024
  * to classify, and a restored lock already says which agent owns the flow. `continueFromHistory`
5602
6025
  * on its own would not do — it neither routes nor installs, so it would run on whatever agent
5603
6026
  * happened to be installed (none, straight after a reload).
6027
+ *
6028
+ * Looks the owner up in its own agents list, so the `agent` argument is not needed and is
6029
+ * ignored; and does not delegate to the inner driver's resume, which would install the agent
6030
+ * undecorated.
5604
6031
  */
5605
6032
  resumeRestoredFlow(resumeNote?: string): Promise<ChatDriverResult | undefined>;
5606
6033
  /**
@@ -5609,13 +6036,11 @@ export declare class OrchestratingDriver extends EventTarget implements AiDriver
5609
6036
  * Two cases, because routing has two modes and they need opposite answers.
5610
6037
  */
5611
6038
  getContextReserve(): ContextReserveResolution | undefined;
5612
- /** {@inheritDoc AiDriver.getActiveAgent} */
5613
- getActiveAgent(): AgentConfig | undefined;
5614
6039
  private installAgent;
5615
6040
  /**
5616
- * Release the current stateful agent: fire `onDeactivate`, clear the
5617
- * flow-owner lock, dispatch events so the host (and Redux) reflect the
5618
- * unlocked state. Called automatically when a tool handler invokes
6041
+ * Release the current stateful agent: fire `onDeactivate` and clear the flow-owner lock. The
6042
+ * inner driver raises the events from the session's transition, so the host (and Redux) reflect
6043
+ * the unlocked state (GENC-1485). Called automatically when a tool handler invokes
5619
6044
  * `context.releaseAgent`.
5620
6045
  *
5621
6046
  * The user-pin (`pinnedAgentName`) is intentionally *not* cleared — a user
@@ -6022,6 +6447,25 @@ export declare type RoutingDecision =
6022
6447
  /** A pin or an active flow owned the turn; the classifier was skipped. */
6023
6448
  | 'pinned';
6024
6449
 
6450
+ /**
6451
+ * Options for `AiDriver.sendMessage` (GENC-1660).
6452
+ *
6453
+ * @beta
6454
+ */
6455
+ export declare interface SendMessageOptions {
6456
+ /**
6457
+ * Send the message on the user's behalf, as this decorator (e.g. `'autopilot'`). The platform
6458
+ * stamps it on the stored message as `delegate`, so it renders as the assistant and the model
6459
+ * reads it framed.
6460
+ */
6461
+ delegate?: string;
6462
+ /**
6463
+ * The phrase the model reads in front of a delegated message. Defaults to
6464
+ * {@link DEFAULT_DELEGATE_FRAMING}. Ignored unless `delegate` is set.
6465
+ */
6466
+ delegateFraming?: string;
6467
+ }
6468
+
6025
6469
  /**
6026
6470
  * `detail` of the `AiAssistantEvent.SessionCleared` event. Captured *before*
6027
6471
  * teardown so a host can tidy up whatever the active agent was working on