@genesislcap/ai-assistant 14.495.0 → 14.496.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 (36) hide show
  1. package/dist/ai-assistant.api.json +576 -211
  2. package/dist/ai-assistant.d.ts +128 -5
  3. package/dist/chat-driver.cjs +5608 -0
  4. package/dist/chat-driver.cjs.map +7 -0
  5. package/dist/chat-driver.mjs +5566 -0
  6. package/dist/chat-driver.mjs.map +7 -0
  7. package/dist/custom-elements.json +306 -2
  8. package/dist/dts/channel/ai-activity-bus.d.ts +36 -0
  9. package/dist/dts/channel/ai-activity-bus.d.ts.map +1 -1
  10. package/dist/dts/chat-driver-node.d.ts +28 -0
  11. package/dist/dts/chat-driver-node.d.ts.map +1 -0
  12. package/dist/dts/components/chat-driver/chat-driver.d.ts +49 -5
  13. package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
  14. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +3 -0
  15. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
  16. package/dist/dts/config/config.d.ts +37 -2
  17. package/dist/dts/config/config.d.ts.map +1 -1
  18. package/dist/dts/main/main.d.ts.map +1 -1
  19. package/dist/esm/channel/ai-activity-bus.js +48 -12
  20. package/dist/esm/chat-driver-node.js +33 -0
  21. package/dist/esm/components/chat-driver/chat-driver.js +28 -14
  22. package/dist/esm/components/chat-driver/chat-driver.test.js +32 -40
  23. package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +7 -1
  24. package/dist/esm/main/main.js +8 -1
  25. package/dist/esm/main/popout-interaction-gate.test.js +6 -10
  26. package/dist/tsconfig.tsbuildinfo +1 -1
  27. package/package.json +29 -19
  28. package/scripts/build-chat-driver-node.mjs +42 -0
  29. package/src/channel/ai-activity-bus.ts +64 -10
  30. package/src/chat-driver-node.ts +54 -0
  31. package/src/components/chat-driver/chat-driver.test.ts +36 -62
  32. package/src/components/chat-driver/chat-driver.ts +96 -28
  33. package/src/components/orchestrating-driver/orchestrating-driver.ts +10 -11
  34. package/src/config/config.ts +40 -1
  35. package/src/main/main.ts +8 -11
  36. package/src/main/popout-interaction-gate.test.ts +6 -11
@@ -6,6 +6,7 @@ import type { CachePolicy } from '@genesislcap/foundation-ai';
6
6
  import type { ChatAttachment } from '@genesislcap/foundation-ai';
7
7
  import type { ChatConfig } from '@genesislcap/foundation-ai';
8
8
  import type { ChatDriverResult } from '@genesislcap/foundation-ai';
9
+ import type { ChatFallback } from '@genesislcap/foundation-ai';
9
10
  import type { ChatInputDuringExecutionMode } from '@genesislcap/foundation-ai';
10
11
  import type { ChatMessage } from '@genesislcap/foundation-ai';
11
12
  import type { ChatToolChoice } from '@genesislcap/foundation-ai';
@@ -21,6 +22,18 @@ import type { SubAgentFailureReason } from '@genesislcap/foundation-ai';
21
22
  import type { TurnFailureReason } from '@genesislcap/foundation-ai';
22
23
  import { ViewTemplate } from '@genesislcap/web-core';
23
24
 
25
+ /**
26
+ * Minimal activity-bus surface the drivers depend on. `ChatDriver`/`OrchestratingDriver`
27
+ * only ever *publish* — accepting this narrow interface (rather than importing the module
28
+ * singleton) lets a headless/server or unit-test host omit the bus entirely, so no live
29
+ * `BroadcastChannel` is ever opened on that path. See {@link NOOP_ACTIVITY_BUS}.
30
+ *
31
+ * @beta
32
+ */
33
+ export declare interface ActivityBus {
34
+ publish<K extends keyof AgenticActivityEvents>(type: K, detail: AgenticActivityEvents[K]): void;
35
+ }
36
+
24
37
  /** Sentinel value used by the segmented control / select to represent "Auto". */
25
38
  export declare const AGENT_PICKER_AUTO_VALUE = "__auto__";
26
39
 
@@ -51,12 +64,23 @@ export declare type AgentConfig = SpecialistAgentConfig | FallbackAgentConfig;
51
64
  export declare class AgenticActivityBus {
52
65
  private readonly subscribers;
53
66
  private readonly crossTabEvents;
67
+ private readonly channelNameFactory?;
54
68
  private channel?;
69
+ private channelInitialised;
55
70
  /**
56
71
  * @param config - Optional configuration. Omit to create an in-memory-only bus.
57
72
  * @beta
58
73
  */
59
74
  constructor(config?: AgenticActivityBusConfig);
75
+ /**
76
+ * Lazily open the cross-tab `BroadcastChannel` on first use. Deferred (rather than
77
+ * created in the constructor) so that importing this module, or constructing the bus
78
+ * off-browser (Node, tests, headless server), never opens a live channel or reads
79
+ * `sessionStorage` — both would keep a Node event loop alive and hang the process.
80
+ * Cross-tab forwarding is inherently browser-only, so channel creation is gated on a
81
+ * browser environment; elsewhere the bus stays purely in-process.
82
+ */
83
+ private ensureChannel;
60
84
  /**
61
85
  * Subscribe to an event. Returns an unsubscribe function — call it in
62
86
  * `disconnectedCallback` to avoid memory leaks.
@@ -115,6 +139,13 @@ export declare interface AgenticActivityBusConfig {
115
139
  crossTabEvents?: (keyof AgenticActivityEvents)[];
116
140
  /** BroadcastChannel name. Only used when crossTabEvents is non-empty. */
117
141
  channelName?: string;
142
+ /**
143
+ * Lazy alternative to {@link AgenticActivityBusConfig.channelName}: called the first
144
+ * time a cross-tab channel is actually needed, in a browser only. Deferring the name
145
+ * computation keeps side effects (e.g. `sessionStorage` reads) out of module-eval and
146
+ * off the non-browser path. Ignored if `channelName` is also set.
147
+ */
148
+ channelNameFactory?: () => string;
118
149
  }
119
150
 
120
151
  /**
@@ -835,6 +866,25 @@ declare interface BaseAgentConfig {
835
866
  * @beta
836
867
  */
837
868
  tailContext?: TailContextInput;
869
+ /**
870
+ * Structured-output schema for this agent. When resolved to a schema on a turn, the model's
871
+ * final (non-tool) answer is constrained to it instead of free text. Composes with `tools`;
872
+ * resolved per turn like {@link BaseAgentConfig.cachePolicy}, so returning `undefined` on
873
+ * working turns and the schema on the finalize turn gives finalize-turn enforcement for free.
874
+ * See {@link ResponseSchemaInput}.
875
+ *
876
+ * @beta
877
+ */
878
+ responseSchema?: ResponseSchemaInput;
879
+ /**
880
+ * Refusal-fallback chain for this agent (provider-neutral). If the model declines a turn
881
+ * (`stop_reason: 'refusal'` — e.g. Fable 5 safety classifiers), the provider re-runs it on the
882
+ * next listed model. Typical use: a Fable 5 agent with `[{ model: 'claude-opus-4-8' }]`. Static
883
+ * (not per-turn); providers that support it apply it server-side, others ignore it.
884
+ *
885
+ * @beta
886
+ */
887
+ fallbacks?: ChatFallback[];
838
888
  /**
839
889
  * Optional hook consulted when the model calls a tool the driver cannot
840
890
  * dispatch — either a *stale* tool (advertised earlier this activation but
@@ -964,9 +1014,6 @@ export declare type CachePolicyInput = CachePolicy | ((ctx: SystemPromptContext)
964
1014
  */
965
1015
  export declare class ChatDriver extends EventTarget implements AiDriver {
966
1016
  private readonly providerRegistry;
967
- private readonly maxToolIterations;
968
- /** Session identity used to file meta events onto the shared debug-log timeline. */
969
- private readonly sessionKey;
970
1017
  private history;
971
1018
  private busy;
972
1019
  /** Epoch ms when the current turn loop began — drives the `turn.end` duration. */
@@ -1194,6 +1241,16 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
1194
1241
  * the resolved string in a `<system-reminder>` marker and injects it at the message tail.
1195
1242
  */
1196
1243
  private activeTailContextInput?;
1244
+ /**
1245
+ * Active agent's structured-output schema selector (static value or per-turn resolver).
1246
+ * When it resolves to a schema, the model's final answer is constrained to it this turn.
1247
+ */
1248
+ private activeResponseSchemaInput?;
1249
+ /**
1250
+ * Active agent's refusal-fallback chain (static). Passed through to the provider so a refused
1251
+ * turn (e.g. Fable 5) is re-run on the next model server-side.
1252
+ */
1253
+ private activeFallbacks?;
1197
1254
  /**
1198
1255
  * Active agent's unresolved-tool hook, captured from `applyAgent`. Consulted
1199
1256
  * only when a tool call cannot be dispatched (a stale or hallucinated name);
@@ -1238,9 +1295,13 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
1238
1295
  * teardown in `runSubAgent`.
1239
1296
  */
1240
1297
  private unsubscribeRegistry?;
1241
- constructor(providerRegistry: AIProviderRegistry, toolHandlers?: ToolHandlersInput, toolDefinitions?: ToolDefinitionsInput, systemPrompt?: SystemPromptInput, primerHistory?: ChatMessage[], maxToolIterations?: number, maxFoldOperations?: number, maxTurnSnapshots?: number,
1298
+ /** Hard cap on tool-loop iterations. */
1299
+ private readonly maxToolIterations;
1242
1300
  /** Session identity used to file meta events onto the shared debug-log timeline. */
1243
- sessionKey?: string);
1301
+ private readonly sessionKey;
1302
+ /** Injected activity bus; defaults to a no-op off-browser (Node/tests/headless). */
1303
+ private readonly activityBus;
1304
+ constructor(providerRegistry: AIProviderRegistry, config?: ChatDriverConfig);
1244
1305
  /**
1245
1306
  * Tear down the driver: aborts the lifecycle signal so any in-flight provider
1246
1307
  * request (and prompt/tool factories awaiting it) cancels instead of running
@@ -1542,6 +1603,41 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
1542
1603
  private appendToHistory;
1543
1604
  }
1544
1605
 
1606
+ /**
1607
+ * Construction-time configuration for {@link ChatDriver}. Everything except the provider
1608
+ * registry is optional — most fields are also settable per-agent via `applyAgent`, so a
1609
+ * bare `new ChatDriver(registry)` is valid. Mirrors the `(registry, options)` shape of
1610
+ * `OrchestratingDriver`.
1611
+ *
1612
+ * @beta
1613
+ */
1614
+ export declare interface ChatDriverConfig {
1615
+ /** Initial tool handlers (static map or per-turn factory). Default `{}`. */
1616
+ toolHandlers?: ToolHandlersInput;
1617
+ /** Initial tool definitions (static array or per-turn factory). Default `[]`. */
1618
+ toolDefinitions?: ToolDefinitionsInput;
1619
+ /** Initial system prompt (string or per-turn resolver). */
1620
+ systemPrompt?: SystemPromptInput;
1621
+ /** Primer history prepended to the conversation. */
1622
+ primerHistory?: ChatMessage[];
1623
+ /** Hard cap on tool-loop iterations. Default `50`. */
1624
+ maxToolIterations?: number;
1625
+ /** Hard cap on fold operations. Default `5`. */
1626
+ maxFoldOperations?: number;
1627
+ /** Ring-buffer size for per-turn snapshots. Default `400`. */
1628
+ maxTurnSnapshots?: number;
1629
+ /** Session identity used to file meta events onto the shared debug-log timeline. */
1630
+ sessionKey?: string;
1631
+ /**
1632
+ * Activity bus for lifecycle/halo/tool-loop events. Injected by the browser host
1633
+ * (the shared cross-tab singleton); omitted off-browser (Node, tests, headless), where
1634
+ * it defaults to {@link NOOP_ACTIVITY_BUS} so no `BroadcastChannel` is ever opened.
1635
+ */
1636
+ activityBus?: ActivityBus;
1637
+ }
1638
+
1639
+ export { ChatFallback }
1640
+
1545
1641
  /**
1546
1642
  * `detail` of the `AiAssistantEvent.ChatHeaderMouseDown` event.
1547
1643
  *
@@ -2886,6 +2982,14 @@ export declare interface ManualSelectionConfig {
2886
2982
 
2887
2983
  export { ModelTagAppearance }
2888
2984
 
2985
+ /**
2986
+ * No-op {@link ActivityBus}. The default when no bus is injected (Node, tests, headless
2987
+ * server use) — publishing goes nowhere and nothing is left open to tear down.
2988
+ *
2989
+ * @beta
2990
+ */
2991
+ export declare const NOOP_ACTIVITY_BUS: ActivityBus;
2992
+
2889
2993
  /**
2890
2994
  * Orchestrates multiple specialist agents. Sits between `FoundationAiAssistant`
2891
2995
  * and `ChatDriver`, classifying each user message and routing it to the right
@@ -2945,6 +3049,8 @@ export declare class OrchestratingDriver extends EventTarget implements AiDriver
2945
3049
  maxToolIterations?: number;
2946
3050
  maxFoldOperations?: number;
2947
3051
  maxTurnSnapshots?: number;
3052
+ /** Activity bus passed through to the inner ChatDriver (browser host injects the singleton). */
3053
+ activityBus?: ActivityBus;
2948
3054
  });
2949
3055
  resolveInteraction(interactionId: string, result: unknown): void;
2950
3056
  getInteractionContext(interactionId: string): InteractionContext | undefined;
@@ -3129,6 +3235,23 @@ declare interface ResolvedCostHistoryConfig {
3129
3235
  badgeLabel: string;
3130
3236
  }
3131
3237
 
3238
+ /**
3239
+ * Structured-output schema for an agent. When set, the model's final (non-tool) answer is
3240
+ * constrained to this JSON Schema instead of free text. Either a static schema or a function
3241
+ * resolved each tool-loop iteration — return the schema on the turn(s) it should apply and
3242
+ * `undefined` otherwise, so "whole-loop" vs "finalize-turn" enforcement is just what the
3243
+ * resolver returns (e.g. `({ state }) => state.machine.matches('finalizing') ? schema : undefined`).
3244
+ *
3245
+ * Orthogonal to {@link ToolChoiceInput}: an agent can carry both `tools` and a `responseSchema`.
3246
+ * Each provider applies it natively where possible (Anthropic `output_config.format`, Gemini
3247
+ * JSON mode) and degrades gracefully otherwise. The schema is a plain JSON Schema object; keep to
3248
+ * the portable subset providers share (`additionalProperties: false`, explicit `required`, enums,
3249
+ * `anyOf` for nullables — no numeric/string constraints or recursion).
3250
+ *
3251
+ * @beta
3252
+ */
3253
+ export declare type ResponseSchemaInput = object | ((ctx: SystemPromptContext) => object | undefined | Promise<object | undefined>);
3254
+
3132
3255
  /**
3133
3256
  * Restore a foundation-state-machine instance from a snapshot produced by the
3134
3257
  * default serializer (or `machine.getPersistedSnapshot()`). Call inside a