@genesislcap/ai-assistant 15.56.0 → 15.58.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 (42) hide show
  1. package/dist/ai-assistant.api.json +438 -8
  2. package/dist/ai-assistant.d.ts +120 -4
  3. package/dist/chat-driver.cjs +60 -9
  4. package/dist/chat-driver.cjs.map +2 -2
  5. package/dist/chat-driver.mjs +60 -9
  6. package/dist/chat-driver.mjs.map +2 -2
  7. package/dist/custom-elements.json +238 -3
  8. package/dist/dts/components/agent-session/agent-session.d.ts +9 -0
  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 +31 -2
  11. package/dist/dts/components/ai-driver/ai-driver.d.ts.map +1 -1
  12. package/dist/dts/components/chat-driver/chat-driver.d.ts +18 -2
  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 +15 -2
  15. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
  16. package/dist/dts/config/config.d.ts +21 -0
  17. package/dist/dts/config/config.d.ts.map +1 -1
  18. package/dist/dts/config/define-stateful-agent.d.ts +6 -0
  19. package/dist/dts/config/define-stateful-agent.d.ts.map +1 -1
  20. package/dist/dts/main/main.d.ts +21 -0
  21. package/dist/dts/main/main.d.ts.map +1 -1
  22. package/dist/dts/state/debug-event-log.d.ts +1 -1
  23. package/dist/dts/state/debug-event-log.d.ts.map +1 -1
  24. package/dist/dts/state/persistence/resume-verdict.d.ts +32 -0
  25. package/dist/dts/state/persistence/resume-verdict.d.ts.map +1 -0
  26. package/dist/dts/state/persistence/session-persister.d.ts +34 -1
  27. package/dist/dts/state/persistence/session-persister.d.ts.map +1 -1
  28. package/dist/dts/state/persistence/session-snapshot.d.ts +19 -0
  29. package/dist/dts/state/persistence/session-snapshot.d.ts.map +1 -1
  30. package/dist/dts/utils/message-partition.d.ts +9 -1
  31. package/dist/dts/utils/message-partition.d.ts.map +1 -1
  32. package/dist/esm/components/agent-session/agent-session.js +14 -0
  33. package/dist/esm/components/chat-driver/chat-driver.js +12 -5
  34. package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +34 -2
  35. package/dist/esm/config/define-stateful-agent.js +1 -0
  36. package/dist/esm/main/main.js +101 -22
  37. package/dist/esm/state/debug-event-log.js +4 -0
  38. package/dist/esm/state/persistence/resume-verdict.js +20 -0
  39. package/dist/esm/state/persistence/session-persister.js +55 -15
  40. package/dist/esm/state/persistence/session-snapshot.js +67 -0
  41. package/dist/esm/utils/message-partition.js +11 -2
  42. package/package.json +17 -17
@@ -4032,6 +4032,10 @@ var META_EVENT_IMPORTANCE = {
4032
4032
  "session.switched": "low",
4033
4033
  "session.switch-deferred": "low",
4034
4034
  "persistence.restored": "normal",
4035
+ // Whether a restored flow will be re-activated and resumed (GENC-1662), and how much the trim cut.
4036
+ "persistence.resume-planned": "normal",
4037
+ // A planned resume that did not run, and why (GENC-1662) — the divider was put back to plain.
4038
+ "persistence.resume-withdrawn": "normal",
4035
4039
  "persistence.suppressed": "normal",
4036
4040
  "persistence.not-resumable": "normal",
4037
4041
  "driver.wired": "low",
@@ -4825,6 +4829,8 @@ var AgentSession = class {
4825
4829
  * activation, then deleted so a later re-activation starts fresh.
4826
4830
  */
4827
4831
  this.restoredStates = {};
4832
+ /** The tail of the activation queue — see {@link AgentSession.activate}. */
4833
+ this.activation = Promise.resolve();
4828
4834
  }
4829
4835
  /** The active agent, or `undefined` before the first activation and after a release. */
4830
4836
  getActive() {
@@ -4873,8 +4879,19 @@ var AgentSession = class {
4873
4879
  *
4874
4880
  * Re-activating the same agent by name is not a switch: no hooks fire, no lock moves, and no
4875
4881
  * handoff is recorded. That guard matters because a per-turn re-resolve calls through here.
4876
- */
4877
- async activate(agent) {
4882
+ *
4883
+ * Single-flight (GENC-1662): calls run one after another, never interleaved. `active` is only
4884
+ * set once the hooks have finished, so two overlapping calls for the same agent would otherwise
4885
+ * both see a switch and run `onActivate` twice — and a restored `init` would be overwritten by a
4886
+ * fresh one that finished later. That overlap became possible when a restore started activating
4887
+ * the flow owner outside a turn, where a send can land mid-activation.
4888
+ */
4889
+ activate(agent) {
4890
+ const run = this.activation.then(() => this.activateNow(agent));
4891
+ this.activation = run.catch(() => void 0);
4892
+ return run;
4893
+ }
4894
+ async activateNow(agent) {
4878
4895
  const previousAgent = this.active;
4879
4896
  const switched = !previousAgent || previousAgent.name !== agent.name;
4880
4897
  const transition = { previousAgent, switched };
@@ -7435,9 +7452,13 @@ var ChatDriver = class _ChatDriver extends EventTarget {
7435
7452
  }
7436
7453
  /**
7437
7454
  * Continue the tool loop from current history without appending a new user message.
7438
- * Used by OrchestratingDriver after an agent handoff.
7455
+ * Used by OrchestratingDriver after an agent handoff, and to resume a restored flow (GENC-1662).
7456
+ *
7457
+ * `options.tailNote` rides the framed tail of the FIRST model call only — after the history, where
7458
+ * a note about the conversation belongs — and is dropped once the model has answered, so it
7459
+ * cannot go stale over the rest of the loop. Contrast `transientPrimer`, which leads the request.
7439
7460
  */
7440
- async continueFromHistory(transientPrimer) {
7461
+ async continueFromHistory(transientPrimer, options) {
7441
7462
  if (this.busy) return { reason: "done" };
7442
7463
  this.busy = true;
7443
7464
  if (this.messageController.signal.aborted) this.beginMessage();
@@ -7459,7 +7480,7 @@ var ChatDriver = class _ChatDriver extends EventTarget {
7459
7480
  this.activityBus.publish("tool-loop-start", void 0);
7460
7481
  let result = { reason: "done" };
7461
7482
  try {
7462
- result = await this.runToolLoop("", void 0, transientPrimer);
7483
+ result = await this.runToolLoop("", void 0, transientPrimer, options?.tailNote);
7463
7484
  return result;
7464
7485
  } catch (e) {
7465
7486
  logger2.error("ChatDriver error:", e);
@@ -7496,7 +7517,7 @@ var ChatDriver = class _ChatDriver extends EventTarget {
7496
7517
  // splitting threads that state through signatures rather than removing it. `turn-setup.ts`
7497
7518
  // (docs/code-health.md §11.3) is the intended carve-up.
7498
7519
  // oxlint-disable-next-line complexity, max-lines-per-function
7499
- async runToolLoop(userInput, attachments, transientPrimer) {
7520
+ async runToolLoop(userInput, attachments, transientPrimer, tailNote) {
7500
7521
  if (!this.systemPrompt) {
7501
7522
  logger2.warn(
7502
7523
  "ChatDriver: no systemPrompt set. The assistant will have no instructions \u2014 provide a systemPrompt via agents config or the foundation-ai-assistant property."
@@ -7557,7 +7578,10 @@ var ChatDriver = class _ChatDriver extends EventTarget {
7557
7578
  ${MALFORMED_CALL_NUDGE}` : emptyResponseAttempts > 0 ? `
7558
7579
 
7559
7580
  ${EMPTY_RESPONSE_NUDGE}` : "";
7560
- const frameworkSystemSuffix = `${foldSuffix}${retryNudge}`;
7581
+ const firstCallNote = tailNote && iterations === 1 ? `
7582
+
7583
+ ${tailNote}` : "";
7584
+ const frameworkSystemSuffix = `${foldSuffix}${firstCallNote}${retryNudge}`;
7561
7585
  const primer = normalizeForProvider([
7562
7586
  ...this.primerHistory ?? [],
7563
7587
  ...transientPrimer ?? []
@@ -8616,13 +8640,39 @@ var OrchestratingDriver = class extends EventTarget {
8616
8640
  }
8617
8641
  return lastResult?.reason === "done" ? lastResult : { reason: "done" };
8618
8642
  }
8619
- async continueFromHistory(transientPrimer) {
8620
- return this.chatDriver.continueFromHistory(transientPrimer);
8643
+ async continueFromHistory(transientPrimer, options) {
8644
+ return this.chatDriver.continueFromHistory(transientPrimer, options);
8621
8645
  }
8622
8646
  /** {@inheritDoc AiDriver.primeRestoredAgentState} */
8623
8647
  primeRestoredAgentState(snapshots) {
8624
8648
  this.agentSession.primeRestoredStates(snapshots);
8625
8649
  }
8650
+ /** {@inheritDoc AiDriver.canRestoreFlowOwner} */
8651
+ canRestoreFlowOwner(agentName) {
8652
+ return this.agents.some((a) => a.name === agentName);
8653
+ }
8654
+ /** {@inheritDoc AiDriver.canResumeRestoredFlow} */
8655
+ canResumeRestoredFlow(agentName) {
8656
+ const agent = this.agents.find((a) => a.name === agentName);
8657
+ return !!agent && agent.resumeOnRestore !== false;
8658
+ }
8659
+ /**
8660
+ * {@inheritDoc AiDriver.resumeRestoredFlow}
8661
+ *
8662
+ * Installs the flow owner directly rather than through `handleTurn`: there is no user message
8663
+ * to classify, and a restored lock already says which agent owns the flow. `continueFromHistory`
8664
+ * on its own would not do — it neither routes nor installs, so it would run on whatever agent
8665
+ * happened to be installed (none, straight after a reload).
8666
+ */
8667
+ async resumeRestoredFlow(resumeNote) {
8668
+ const owner = this.agentSession.getFlowOwner();
8669
+ const agent = owner ? this.agents.find((a) => a.name === owner) : void 0;
8670
+ if (!agent) return void 0;
8671
+ this.cancelled = false;
8672
+ await this.installAgent(agent);
8673
+ if (!resumeNote || agent.resumeOnRestore === false || this.cancelled) return void 0;
8674
+ return this.chatDriver.continueFromHistory(void 0, { tailNote: resumeNote });
8675
+ }
8626
8676
  /**
8627
8677
  * {@inheritDoc AiDriver.getContextReserve}
8628
8678
  *
@@ -9097,6 +9147,7 @@ function defineStatefulAgent(opts) {
9097
9147
  onUnresolvedTool: wrappedOnUnresolvedTool,
9098
9148
  resumable: wrappedResumable,
9099
9149
  notResumableMessage: opts.notResumableMessage,
9150
+ resumeOnRestore: opts.resumeOnRestore,
9100
9151
  contextReserve: opts.contextReserve,
9101
9152
  onActivate: async (ctx) => {
9102
9153
  state = await opts.init(ctx);