@genesislcap/ai-assistant 14.436.0 → 14.437.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/main/main.ts CHANGED
@@ -333,22 +333,22 @@ export class FoundationAiAssistant extends GenesisElement {
333
333
  }
334
334
 
335
335
  /**
336
- * In-flight per-call chat-input overrides pushed by `requestSubAgent`
337
- * invocations. Empty means no override is active.
336
+ * In-flight per-call chat-input overrides pushed by `requestSubAgent` or
337
+ * `requestInteraction` calls. Empty means no override is active.
338
338
  */
339
- get subAgentInputOverrides() {
340
- return this._sessionRef?.store.aiAssistant.subAgentInputOverrides ?? [];
339
+ get inputOverrides() {
340
+ return this._sessionRef?.store.aiAssistant.inputOverrides ?? [];
341
341
  }
342
342
 
343
343
  /**
344
344
  * Resolves the effective chat-input behaviour while the assistant is
345
- * executing. Sub-agent overrides take precedence over the agent-level
345
+ * executing. Per-call overrides take precedence over the agent-level
346
346
  * config; among overrides the most restrictive wins (`'hidden'` >
347
347
  * `'disabled'`). Falls back to the active agent's config, then `'disabled'`.
348
348
  */
349
349
  @volatile
350
350
  get effectiveChatInputDuringExecution(): ChatInputDuringExecutionMode {
351
- const overrides = this.subAgentInputOverrides;
351
+ const overrides = this.inputOverrides;
352
352
  if (overrides.some((o) => o.mode === 'hidden')) return 'hidden';
353
353
  if (overrides.some((o) => o.mode === 'disabled')) return 'disabled';
354
354
  return this.activeAgent?.chatInputDuringExecution ?? 'disabled';
@@ -544,9 +544,16 @@ export class FoundationAiAssistant extends GenesisElement {
544
544
  if (!agents?.length) return '';
545
545
  return agents
546
546
  .map((a) => {
547
- const toolNames = Object.keys(a.toolHandlers ?? {})
548
- .sort()
549
- .join('+');
547
+ // Function-form handlers are resolved per turn — their full key set
548
+ // isn't knowable at fingerprint time. A constant marker still
549
+ // distinguishes static-vs-dynamic shape changes; finer-grained
550
+ // detection isn't load-bearing here.
551
+ const toolNames =
552
+ typeof a.toolHandlers === 'function'
553
+ ? '<fn>'
554
+ : Object.keys(a.toolHandlers ?? {})
555
+ .sort()
556
+ .join('+');
550
557
  return `${a.name}[${toolNames}]`;
551
558
  })
552
559
  .join(',');
@@ -656,7 +663,7 @@ export class FoundationAiAssistant extends GenesisElement {
656
663
  chatInputDuringExecution?: ChatInputDuringExecutionMode;
657
664
  };
658
665
  if (!chatInputDuringExecution) return;
659
- this._sessionRef?.actions.aiAssistant.addSubAgentInputOverride({
666
+ this._sessionRef?.actions.aiAssistant.addInputOverride({
660
667
  id: invocationId,
661
668
  mode: chatInputDuringExecution,
662
669
  });
@@ -666,18 +673,39 @@ export class FoundationAiAssistant extends GenesisElement {
666
673
  this.liveSubAgentName = null;
667
674
  const { invocationId } = (e as CustomEvent).detail as { invocationId?: string };
668
675
  if (invocationId) {
669
- this._sessionRef?.actions.aiAssistant.removeSubAgentInputOverride({ id: invocationId });
676
+ this._sessionRef?.actions.aiAssistant.removeInputOverride({ id: invocationId });
677
+ }
678
+ };
679
+ const onInteractionStart = (e: Event) => {
680
+ const { interactionId, chatInputDuringExecution } = (e as CustomEvent).detail as {
681
+ interactionId: string;
682
+ chatInputDuringExecution?: ChatInputDuringExecutionMode;
683
+ };
684
+ if (!chatInputDuringExecution) return;
685
+ this._sessionRef?.actions.aiAssistant.addInputOverride({
686
+ id: interactionId,
687
+ mode: chatInputDuringExecution,
688
+ });
689
+ };
690
+ const onInteractionStop = (e: Event) => {
691
+ const { interactionId } = (e as CustomEvent).detail as { interactionId?: string };
692
+ if (interactionId) {
693
+ this._sessionRef?.actions.aiAssistant.removeInputOverride({ id: interactionId });
670
694
  }
671
695
  };
672
696
  driver.addEventListener('sub-agent-history-updated', onSubAgentHistoryUpdated);
673
697
  driver.addEventListener('sub-agent-start', onSubAgentStart);
674
698
  driver.addEventListener('sub-agent-stop', onSubAgentStop);
699
+ driver.addEventListener('interaction-start', onInteractionStart);
700
+ driver.addEventListener('interaction-stop', onInteractionStop);
675
701
 
676
702
  const cleanups: (() => void)[] = [
677
703
  () => driver.removeEventListener('history-updated', onHistoryUpdated),
678
704
  () => driver.removeEventListener('sub-agent-history-updated', onSubAgentHistoryUpdated),
679
705
  () => driver.removeEventListener('sub-agent-start', onSubAgentStart),
680
706
  () => driver.removeEventListener('sub-agent-stop', onSubAgentStop),
707
+ () => driver.removeEventListener('interaction-start', onInteractionStart),
708
+ () => driver.removeEventListener('interaction-stop', onInteractionStop),
681
709
  ];
682
710
 
683
711
  if (driver instanceof OrchestratingDriver) {
@@ -1149,7 +1177,11 @@ export class FoundationAiAssistant extends GenesisElement {
1149
1177
  agentSummary: this.agents?.map((a) => ({
1150
1178
  ...a,
1151
1179
  toolDefinitions: Array.isArray(a.toolDefinitions)
1152
- ? expandToolTree(a.toolDefinitions, a.toolHandlers ?? {})
1180
+ ? typeof a.toolHandlers === 'function'
1181
+ ? // Static defs + dynamic handlers — can't walk fold tree
1182
+ // because the handler map isn't materialized at log time.
1183
+ a.toolDefinitions
1184
+ : expandToolTree(a.toolDefinitions, a.toolHandlers ?? {})
1153
1185
  : typeof a.toolDefinitions === 'function'
1154
1186
  ? '<dynamic — resolved per turn>'
1155
1187
  : [],
@@ -6,13 +6,14 @@ import type { AiAssistantAnimation, AiAssistantState, SuggestionsState } from '.
6
6
 
7
7
  /**
8
8
  * A single in-flight per-call chat-input override pushed by a `requestSubAgent`
9
- * invocation. Tracked as an array (not a counter) so the slice can survive
10
- * pop-in/pop-out and so a listener that connects mid-execution can compute the
11
- * effective mode without having seen the start event.
9
+ * or `requestInteraction` call. Tracked as an array (not a counter) so the
10
+ * slice can survive pop-in/pop-out and so a listener that connects
11
+ * mid-execution can compute the effective mode without having seen the start
12
+ * event.
12
13
  *
13
14
  * @internal
14
15
  */
15
- export interface SubAgentInputOverride {
16
+ export interface InputOverride {
16
17
  /** Unique per-invocation id, paired with the start/stop events. */
17
18
  id: string;
18
19
  /** The mode requested for this invocation. */
@@ -54,11 +55,12 @@ export interface AiAssistantSessionState {
54
55
  /** Name of the currently-executing sub-agent, or null when idle. */
55
56
  liveSubAgentName: string | null;
56
57
  /**
57
- * In-flight per-call chat-input overrides pushed by `requestSubAgent` calls.
58
- * The most restrictive entry (`'hidden'` > `'disabled'`) wins; an empty list
59
- * means the agent-level `chatInputDuringExecution` applies.
58
+ * In-flight per-call chat-input overrides pushed by `requestSubAgent` or
59
+ * `requestInteraction` calls. The most restrictive entry (`'hidden'` >
60
+ * `'disabled'`) wins; an empty list means the agent-level
61
+ * `chatInputDuringExecution` applies.
60
62
  */
61
- subAgentInputOverrides: SubAgentInputOverride[];
63
+ inputOverrides: InputOverride[];
62
64
  }
63
65
 
64
66
  export const defaultSessionState: AiAssistantSessionState = {
@@ -77,7 +79,7 @@ export const defaultSessionState: AiAssistantSessionState = {
77
79
  inputValue: '',
78
80
  liveSubAgentTrace: [],
79
81
  liveSubAgentName: null,
80
- subAgentInputOverrides: [],
82
+ inputOverrides: [],
81
83
  };
82
84
 
83
85
  export const aiAssistantSlice = createSlice({
@@ -129,13 +131,11 @@ export const aiAssistantSlice = createSlice({
129
131
  setLiveSubAgentName(state, action: PayloadAction<string | null>) {
130
132
  state.liveSubAgentName = action.payload;
131
133
  },
132
- addSubAgentInputOverride(state, action: PayloadAction<SubAgentInputOverride>) {
133
- state.subAgentInputOverrides.push(action.payload);
134
+ addInputOverride(state, action: PayloadAction<InputOverride>) {
135
+ state.inputOverrides.push(action.payload);
134
136
  },
135
- removeSubAgentInputOverride(state, action: PayloadAction<{ id: string }>) {
136
- state.subAgentInputOverrides = state.subAgentInputOverrides.filter(
137
- (o) => o.id !== action.payload.id,
138
- );
137
+ removeInputOverride(state, action: PayloadAction<{ id: string }>) {
138
+ state.inputOverrides = state.inputOverrides.filter((o) => o.id !== action.payload.id);
139
139
  },
140
140
  },
141
141
  selectors: {},