@genesislcap/ai-assistant 15.84.3 → 15.85.0-FUI-2666.2

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 (50) hide show
  1. package/dist/ai-assistant.api.json +2175 -138
  2. package/dist/ai-assistant.d.ts +420 -43
  3. package/dist/chat-driver.cjs +780 -210
  4. package/dist/chat-driver.cjs.map +4 -4
  5. package/dist/chat-driver.mjs +780 -209
  6. package/dist/chat-driver.mjs.map +4 -4
  7. package/dist/custom-elements.json +1514 -424
  8. package/dist/dts/components/agent-session/agent-session.d.ts +50 -2
  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 +59 -1
  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 +13 -1
  13. package/dist/dts/components/ai-driver/base-driver-decorator.d.ts.map +1 -1
  14. package/dist/dts/components/chat-driver/chat-driver.constants.d.ts +0 -8
  15. package/dist/dts/components/chat-driver/chat-driver.constants.d.ts.map +1 -1
  16. package/dist/dts/components/chat-driver/chat-driver.d.ts +74 -15
  17. package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
  18. package/dist/dts/components/orchestrating-driver/hand-off.d.ts +20 -0
  19. package/dist/dts/components/orchestrating-driver/hand-off.d.ts.map +1 -0
  20. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +121 -22
  21. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
  22. package/dist/dts/config/config.d.ts +66 -0
  23. package/dist/dts/config/config.d.ts.map +1 -1
  24. package/dist/dts/main/main.d.ts +3 -0
  25. package/dist/dts/main/main.d.ts.map +1 -1
  26. package/dist/dts/main/main.types.d.ts +6 -0
  27. package/dist/dts/main/main.types.d.ts.map +1 -1
  28. package/dist/dts/react.d.ts +4 -1
  29. package/dist/dts/state/persistence/session-persister.d.ts.map +1 -1
  30. package/dist/dts/state/persistence/session-snapshot.d.ts +33 -1
  31. package/dist/dts/state/persistence/session-snapshot.d.ts.map +1 -1
  32. package/dist/dts/utils/condense-history.d.ts +10 -3
  33. package/dist/dts/utils/condense-history.d.ts.map +1 -1
  34. package/dist/esm/components/agent-session/agent-session.js +128 -7
  35. package/dist/esm/components/ai-driver/ai-driver.js +3 -0
  36. package/dist/esm/components/ai-driver/base-driver-decorator.js +24 -0
  37. package/dist/esm/components/chat-driver/chat-driver.constants.js +0 -8
  38. package/dist/esm/components/chat-driver/chat-driver.js +247 -74
  39. package/dist/esm/components/orchestrating-driver/hand-off.js +59 -0
  40. package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +480 -299
  41. package/dist/esm/main/main.js +32 -6
  42. package/dist/esm/main/main.types.js +6 -0
  43. package/dist/esm/state/debug-event-log.js +1 -1
  44. package/dist/esm/state/persistence/session-persister.js +55 -8
  45. package/dist/esm/state/persistence/session-snapshot.js +12 -6
  46. package/dist/esm/utils/condense-history.js +13 -4
  47. package/dist/react.cjs +16 -1
  48. package/dist/react.mjs +16 -1
  49. package/docs/sub_agent.md +1 -1
  50. package/package.json +17 -17
@@ -90,9 +90,11 @@ export interface CondenseContext {
90
90
  activationEnded: (activation: number) => boolean;
91
91
  /**
92
92
  * Whether a later phase epoch is current than the one a call was made in — the
93
- * `phaseEnd` clock. True once `endPhase()` has been called since the call.
93
+ * `phaseEnd` clock. True once `endPhase()` has been called since the call. `activation` is the
94
+ * call's, for a caller waiting in a hand-off, whose phase another agent's `endPhase()` does not
95
+ * end (GENC-1737).
94
96
  */
95
- phaseEnded: (phaseEpoch: number) => boolean;
97
+ phaseEnded: (phaseEpoch: number, activation: number) => boolean;
96
98
  /**
97
99
  * Collapse in batches of this many model-calls instead of continuously. A positive
98
100
  * integer; decimals are floored and anything below `1` becomes `1`. Omit (or `1`) to
@@ -184,7 +186,12 @@ export declare function toolCallIdsIn(history: readonly ChatMessage[]): Set<stri
184
186
  *
185
187
  * Pure, no writes to the registry — safe on a save path that runs on every autosave.
186
188
  */
187
- export declare function snapshotCondensePolicies(policies: ReadonlyMap<string, RegisteredCondensePolicy>, clocks: CondenseClocks, history: readonly ChatMessage[]): PersistedCondensePolicy[];
189
+ export declare function snapshotCondensePolicies(policies: ReadonlyMap<string, RegisteredCondensePolicy>, clocks: CondenseClocks, history: readonly ChatMessage[],
190
+ /**
191
+ * Activations suspended in a hand-off (GENC-1737), each with the phase epoch it was suspended
192
+ * at: still live, so written as unended, and their phases counted only up to the suspension.
193
+ */
194
+ suspended?: ReadonlyMap<number, number>): PersistedCondensePolicy[];
188
195
  /**
189
196
  * Validate one persisted entry read back from storage. Returns `undefined` for anything that is not
190
197
  * a well-formed {@link PersistedCondensePolicy} — the blob came off a disk or a network, and a
@@ -1 +1 @@
1
- {"version":3,"file":"condense-history.d.ts","sourceRoot":"","sources":["../../../src/utils/condense-history.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"condense-history.d.ts","sourceRoot":"","sources":["../../../src/utils/condense-history.ts"],"names":[],"mappings":"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"}
@@ -8,8 +8,8 @@ const WARN_PREFIX = 'AgentSession';
8
8
  * and the `onActivate` / `onDeactivate` lifecycle around a swap. Either driver can own one.
9
9
  *
10
10
  * Knows nothing about routing, tool surfaces or transcripts — whether an agent is terminal, the
11
- * continuation tool, the handoff marker in history all stay with the orchestrator, which is the
12
- * only thing with agents to route between.
11
+ * hand-off stack, the divider in history all stay with the orchestrator, which is the only thing
12
+ * with agents to route between.
13
13
  *
14
14
  * @beta
15
15
  */
@@ -41,6 +41,17 @@ export class AgentSession {
41
41
  this.restoredStates = {};
42
42
  /** The tail of the activation queue — see {@link AgentSession.activate}. */
43
43
  this.activation = Promise.resolve();
44
+ /**
45
+ * Callers waiting in a hand-off (GENC-1737), oldest first: still live, so never deactivated by
46
+ * the hand-off, and resumed without `onActivate`. Empty after a reload, when a caller has no live
47
+ * state and is activated again from its saved state instead.
48
+ */
49
+ this.suspended = [];
50
+ /**
51
+ * The `data` of the hand-off that activated each agent (GENC-1737), for its tool handlers: kept
52
+ * while it is active or waits as a caller, and dropped when its activation ends.
53
+ */
54
+ this.handOffData = new Map();
44
55
  }
45
56
  /** The active agent, or `undefined` before the first activation and after a release. */
46
57
  getActive() {
@@ -83,6 +94,91 @@ export class AgentSession {
83
94
  hasRestoredState(agentName) {
84
95
  return this.restoredStates[agentName] !== undefined;
85
96
  }
97
+ /** The `data` of the hand-off that activated `agentName`, if one did and carried any. */
98
+ getHandOffData(agentName) {
99
+ return this.handOffData.get(agentName);
100
+ }
101
+ /** Record the `data` a hand-off activated `agentName` with, or restore it; `undefined` drops it. */
102
+ setHandOffData(agentName, data) {
103
+ if (data === undefined)
104
+ this.handOffData.delete(agentName);
105
+ else
106
+ this.handOffData.set(agentName, data);
107
+ }
108
+ /**
109
+ * Drop the flow lock and leave the active agent active (GENC-1737): a plain agent holding it with
110
+ * no hand-off behind it is done once its turn ends.
111
+ */
112
+ dropFlowLock() {
113
+ if (this.flowOwner === null)
114
+ return;
115
+ this.flowOwner = null;
116
+ this.reportTransition({
117
+ previousAgent: this.active,
118
+ switched: false,
119
+ flowOwnerChangedTo: null,
120
+ });
121
+ }
122
+ /** The callers waiting in a hand-off whose state is live, oldest first. */
123
+ getSuspended() {
124
+ return this.suspended;
125
+ }
126
+ /**
127
+ * Make `target` active for a hand-off (GENC-1737), holding the flow lock whatever kind of agent
128
+ * it is, since a waiting caller depends on it. With `suspendCaller` the active agent waits:
129
+ * it is not deactivated and keeps its state. Without it the active agent is deactivated as on
130
+ * any swap: a one-way hand-off from a target, whose waiting caller then waits for the new
131
+ * target. Queued with {@link AgentSession.activate}.
132
+ */
133
+ handOff(target, options) {
134
+ const run = this.activation.then(() => this.activateNow(target, { lock: true, suspendPrevious: options.suspendCaller }));
135
+ this.activation = run.catch(() => undefined);
136
+ return run;
137
+ }
138
+ /**
139
+ * Make a waiting caller active again when its hand-off ends (GENC-1737). One whose state is live
140
+ * resumes without `onActivate`, since it was never deactivated; after a reload it is activated
141
+ * from its saved state like any other agent. `lock` keeps the flow lock on it: it held it before,
142
+ * or another caller is still waiting further down.
143
+ */
144
+ resume(caller, lock) {
145
+ const run = this.activation.then(() => __awaiter(this, void 0, void 0, function* () {
146
+ var _a, _b;
147
+ const index = this.suspended.findIndex((a) => a.name === caller.name);
148
+ if (index === -1)
149
+ return this.activateNow(caller, { lock });
150
+ // The live instance, whose closures hold the state it waited with.
151
+ const [live] = this.suspended.splice(index, 1);
152
+ const transition = { previousAgent: this.active, switched: true };
153
+ recordMetaEvent(this.deps.sessionKey(), 'agent.handoff', {
154
+ from: (_b = (_a = this.active) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : null,
155
+ to: live.name,
156
+ restored: false,
157
+ });
158
+ this.active = live;
159
+ if (lock && this.flowOwner !== caller.name) {
160
+ this.flowOwner = caller.name;
161
+ transition.flowOwnerChangedTo = caller.name;
162
+ }
163
+ this.reportTransition(transition);
164
+ return transition;
165
+ }));
166
+ this.activation = run.catch(() => undefined);
167
+ return run;
168
+ }
169
+ /**
170
+ * Deactivate the callers left waiting by hand-offs that ended without a hand-back, newest first,
171
+ * when no teardown follows to do it (GENC-1737).
172
+ */
173
+ endSuspended() {
174
+ return __awaiter(this, void 0, void 0, function* () {
175
+ for (const caller of this.suspended.splice(0).reverse()) {
176
+ this.handOffData.delete(caller.name);
177
+ // oxlint-disable-next-line no-await-in-loop -- one machine at a time, as a swap does
178
+ yield this.fireDeactivate(caller, 'release');
179
+ }
180
+ });
181
+ }
86
182
  /**
87
183
  * Make `agent` active, firing the lifecycle hooks around the swap: outgoing `onDeactivate`
88
184
  * first, then incoming `onActivate`. Both are awaited so heavy activation work (a machine
@@ -104,8 +200,12 @@ export class AgentSession {
104
200
  this.activation = run.catch(() => undefined);
105
201
  return run;
106
202
  }
107
- activateNow(agent) {
108
- return __awaiter(this, void 0, void 0, function* () {
203
+ /**
204
+ * `lock` takes the flow lock whatever kind of agent it is, and `suspendPrevious` leaves the
205
+ * outgoing agent waiting instead of deactivating it, as a hand-off does (GENC-1737).
206
+ */
207
+ activateNow(agent_1) {
208
+ return __awaiter(this, arguments, void 0, function* (agent, { lock = false, suspendPrevious = false } = {}) {
109
209
  var _a;
110
210
  const previousAgent = this.active;
111
211
  const switched = !previousAgent || previousAgent.name !== agent.name;
@@ -119,8 +219,15 @@ export class AgentSession {
119
219
  restored: this.hasRestoredState(agent.name),
120
220
  });
121
221
  }
122
- if (switched && previousAgent)
123
- yield this.fireDeactivate(previousAgent, 'switch');
222
+ if (switched && previousAgent) {
223
+ if (suspendPrevious) {
224
+ this.suspended.push(previousAgent);
225
+ }
226
+ else {
227
+ this.handOffData.delete(previousAgent.name);
228
+ yield this.fireDeactivate(previousAgent, 'switch');
229
+ }
230
+ }
124
231
  if (switched && agent.onActivate) {
125
232
  // Hand this agent its persisted state exactly once (consumed here) so a stateful machine
126
233
  // resumes at the right step; a later re-activation of the same agent starts fresh.
@@ -146,10 +253,16 @@ export class AgentSession {
146
253
  // tool handler. The FLOW lock is written rather than the user pin, so completing a flow does
147
254
  // not wipe the user's sticky picker choice.
148
255
  const hasLifecycleHooks = !!(agent.onActivate || agent.onDeactivate);
149
- if (switched && hasLifecycleHooks && this.flowOwner !== agent.name) {
256
+ if (switched && (hasLifecycleHooks || lock) && this.flowOwner !== agent.name) {
150
257
  this.flowOwner = agent.name;
151
258
  transition.flowOwnerChangedTo = agent.name;
152
259
  }
260
+ else if (switched && !suspendPrevious && this.flowOwner === (previousAgent === null || previousAgent === void 0 ? void 0 : previousAgent.name)) {
261
+ // A deactivated owner's flow is over, so its lock goes with it rather than calling it back,
262
+ // with a fresh machine, on the next message: a one-way hand-off to a plain agent (GENC-1737).
263
+ this.flowOwner = null;
264
+ transition.flowOwnerChangedTo = null;
265
+ }
153
266
  this.active = agent;
154
267
  if (switched)
155
268
  this.reportTransition(transition);
@@ -170,6 +283,7 @@ export class AgentSession {
170
283
  const agent = this.active;
171
284
  if (!agent)
172
285
  return undefined;
286
+ this.handOffData.delete(agent.name);
173
287
  yield this.fireDeactivate(agent, 'release');
174
288
  this.active = undefined;
175
289
  const transition = { previousAgent: agent, switched: true };
@@ -212,6 +326,13 @@ export class AgentSession {
212
326
  const agent = this.active;
213
327
  if (agent)
214
328
  yield this.fireDeactivate(agent, 'dispose');
329
+ // Callers waiting in a hand-off are live too, newest first.
330
+ for (const caller of [...this.suspended].reverse()) {
331
+ // oxlint-disable-next-line no-await-in-loop -- one machine at a time, as a swap does
332
+ yield this.fireDeactivate(caller, 'dispose');
333
+ }
334
+ this.suspended = [];
335
+ this.handOffData.clear();
215
336
  this.lifecycleAbortController.abort();
216
337
  this.active = undefined;
217
338
  });
@@ -18,6 +18,9 @@ export const AI_DRIVER_EVENT_TYPES = Object.keys({
18
18
  'agent-changed': true,
19
19
  'agent-released': true,
20
20
  'flow-owner-changed': true,
21
+ 'handoff-started': true,
22
+ 'handoff-returned': true,
23
+ 'handoff-unwound': true,
21
24
  'orchestrating-start': true,
22
25
  'orchestrating-stop': true,
23
26
  });
@@ -106,6 +106,30 @@ export class BaseDriverDecorator extends EventTarget {
106
106
  var _a, _b, _c;
107
107
  return ((_c = (_b = (_a = this.inner).restoreCondensePolicies) === null || _b === void 0 ? void 0 : _b.call(_a, entries)) !== null && _c !== void 0 ? _c : { restored: 0, awaitingReactivation: 0 });
108
108
  }
109
+ getHandOffStack() {
110
+ var _a, _b, _c;
111
+ return (_c = (_b = (_a = this.inner).getHandOffStack) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : [];
112
+ }
113
+ restoreHandOffStack(saved, savedStates, interrupted) {
114
+ var _a, _b, _c;
115
+ return (_c = (_b = (_a = this.inner).restoreHandOffStack) === null || _b === void 0 ? void 0 : _b.call(_a, saved, savedStates, interrupted)) !== null && _c !== void 0 ? _c : {};
116
+ }
117
+ unwindHandOffs(kind) {
118
+ var _a, _b, _c;
119
+ return (_c = (_b = (_a = this.inner).unwindHandOffs) === null || _b === void 0 ? void 0 : _b.call(_a, kind)) !== null && _c !== void 0 ? _c : Promise.resolve();
120
+ }
121
+ serializeWaitingCallers() {
122
+ var _a, _b, _c;
123
+ return (_c = (_b = (_a = this.inner).serializeWaitingCallers) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : {};
124
+ }
125
+ getHandOffData() {
126
+ var _a, _b, _c;
127
+ return (_c = (_b = (_a = this.inner).getHandOffData) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : {};
128
+ }
129
+ restoreHandOffData(saved, interrupted) {
130
+ var _a, _b;
131
+ (_b = (_a = this.inner).restoreHandOffData) === null || _b === void 0 ? void 0 : _b.call(_a, saved, interrupted);
132
+ }
109
133
  getActiveAgent() {
110
134
  return this.inner.getActiveAgent();
111
135
  }
@@ -62,11 +62,3 @@ export const HARVESTED_SUBAGENT_EVENTS = new Set([
62
62
  'tool.failed',
63
63
  'tool.unresolved',
64
64
  ]);
65
- /**
66
- * Name reserved for the cross-agent handoff tool — injected by OrchestratingDriver.
67
- *
68
- * @beta
69
- */
70
- export const REQUEST_CONTINUATION_TOOL = 'request_continuation';
71
- /** Paired in history for each `request_continuation` so tool_calls stay balanced for the provider. */
72
- export const HANDOFF_TOOL_RESULT_PLACEHOLDER = 'Handoff to another specialist — routing continues on the next turn.';