@genesislcap/ai-assistant 15.23.3 → 15.24.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 (46) hide show
  1. package/dist/ai-assistant.api.json +419 -50
  2. package/dist/ai-assistant.d.ts +217 -683
  3. package/dist/chat-driver.cjs.map +1 -1
  4. package/dist/chat-driver.mjs.map +1 -1
  5. package/dist/custom-elements.json +310 -609
  6. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +16 -0
  7. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
  8. package/dist/dts/components/settings-modal/index.d.ts +1 -0
  9. package/dist/dts/components/settings-modal/index.d.ts.map +1 -1
  10. package/dist/dts/components/settings-modal/settings-modal.d.ts +215 -0
  11. package/dist/dts/components/settings-modal/settings-modal.d.ts.map +1 -0
  12. package/dist/dts/components/settings-modal/settings-modal.template.d.ts.map +1 -1
  13. package/dist/dts/main/attachment-controller.d.ts +66 -0
  14. package/dist/dts/main/attachment-controller.d.ts.map +1 -0
  15. package/dist/dts/main/budget-controller.d.ts +368 -0
  16. package/dist/dts/main/budget-controller.d.ts.map +1 -0
  17. package/dist/dts/main/composer-menu-controller.d.ts +113 -0
  18. package/dist/dts/main/composer-menu-controller.d.ts.map +1 -0
  19. package/dist/dts/main/composer-resize-controller.d.ts +80 -0
  20. package/dist/dts/main/composer-resize-controller.d.ts.map +1 -0
  21. package/dist/dts/main/context-gate-controller.d.ts +197 -0
  22. package/dist/dts/main/context-gate-controller.d.ts.map +1 -0
  23. package/dist/dts/main/cost-ledger-controller.d.ts +228 -0
  24. package/dist/dts/main/cost-ledger-controller.d.ts.map +1 -0
  25. package/dist/dts/main/main.d.ts +201 -722
  26. package/dist/dts/main/main.d.ts.map +1 -1
  27. package/dist/dts/main/main.types.d.ts +25 -0
  28. package/dist/dts/main/main.types.d.ts.map +1 -1
  29. package/dist/dts/main/meta-snapshot.d.ts +50 -0
  30. package/dist/dts/main/meta-snapshot.d.ts.map +1 -0
  31. package/dist/dts/state/persistence/session-persister.d.ts.map +1 -1
  32. package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +18 -0
  33. package/dist/esm/components/settings-modal/index.js +1 -0
  34. package/dist/esm/components/settings-modal/settings-modal.js +436 -0
  35. package/dist/esm/components/settings-modal/settings-modal.template.js +15 -4
  36. package/dist/esm/main/attachment-controller.js +254 -0
  37. package/dist/esm/main/budget-controller.js +745 -0
  38. package/dist/esm/main/composer-menu-controller.js +234 -0
  39. package/dist/esm/main/composer-resize-controller.js +119 -0
  40. package/dist/esm/main/context-gate-controller.js +289 -0
  41. package/dist/esm/main/cost-ledger-controller.js +498 -0
  42. package/dist/esm/main/main.js +501 -2268
  43. package/dist/esm/main/meta-snapshot.js +108 -0
  44. package/dist/esm/state/persistence/session-persister.js +5 -4
  45. package/docs/migration-GENC-1580.md +209 -0
  46. package/package.json +16 -16
@@ -0,0 +1,108 @@
1
+ import { configDigest } from '../state/persistence/diagnostics';
2
+ import { stripAgentHandlers } from '../utils/strip-agent-handlers';
3
+ import { expandToolTree } from '../utils/tool-fold';
4
+ /**
5
+ * The single `meta-snapshot` entry for right now — the export-time `meta` block
6
+ * (agent summary, active prompt/state, context + cost) plus the `dedupSignature`
7
+ * the forward-capture delta keys on.
8
+ *
9
+ * Built separately from the timeline entries because the download path needs a
10
+ * FRESH one on its own: the persisted stream only re-appends this block when the
11
+ * near-static config changes, so the newest stored snapshot's volatile half — the
12
+ * `context` figures especially — is typically frozen at the session's first flush.
13
+ *
14
+ * @internal
15
+ */
16
+ export function buildMetaSnapshot(input) {
17
+ var _a, _b, _c, _d, _e, _f;
18
+ const timestamp = new Date().toISOString().replace(/:/g, '-');
19
+ let activeDebugSnapshot;
20
+ try {
21
+ activeDebugSnapshot = (_b = (_a = input.liveActiveAgent) === null || _a === void 0 ? void 0 : _a.getDebugSnapshot) === null || _b === void 0 ? void 0 : _b.call(_a);
22
+ }
23
+ catch (e) {
24
+ activeDebugSnapshot = `<getDebugSnapshot threw: ${e instanceof Error ? e.message : String(e)}>`;
25
+ }
26
+ const contextUsagePercent = input.contextTokens != null && input.contextLimit != null && input.contextLimit > 0
27
+ ? Math.round((input.contextTokens / input.contextLimit) * 100)
28
+ : undefined;
29
+ // The export-time `meta` block, carried on a `meta-snapshot` entry so it lives
30
+ // in the same forward stream (the latest one wins on reassembly, and the
31
+ // accumulated history exposes config/state evolution across the lifetime).
32
+ const metaSnapshot = {
33
+ kind: 'meta-snapshot',
34
+ timestamp: new Date().toISOString(),
35
+ meta: {
36
+ timestamp,
37
+ host: input.host,
38
+ // stripAgentHandlers drops every function-valued field (handlers, lifecycle
39
+ // hooks, onUnresolvedTool, function-form resolvers) AND object handler bags
40
+ // like an object-form `toolHandlers`, and recurses subAgents — no manual
41
+ // exclusion list to keep in sync. We only override toolDefinitions
42
+ // afterwards to expand the fold tree for the log.
43
+ agentSummary: (_c = input.agents) === null || _c === void 0 ? void 0 : _c.map((a) => {
44
+ var _a;
45
+ return (Object.assign(Object.assign({}, stripAgentHandlers(a)), { toolDefinitions: Array.isArray(a.toolDefinitions)
46
+ ? typeof a.toolHandlers === 'function'
47
+ ? // Static defs + dynamic handlers — can't walk fold tree
48
+ // because the handler map isn't materialized at log time.
49
+ a.toolDefinitions
50
+ : expandToolTree(a.toolDefinitions, (_a = a.toolHandlers) !== null && _a !== void 0 ? _a : {})
51
+ : typeof a.toolDefinitions === 'function'
52
+ ? '<dynamic — resolved per turn>'
53
+ : [] }));
54
+ }),
55
+ activeSystemPrompt: typeof ((_d = input.activeAgent) === null || _d === void 0 ? void 0 : _d.systemPrompt) === 'function'
56
+ ? '<dynamic — resolved per turn>'
57
+ : (_e = input.activeAgent) === null || _e === void 0 ? void 0 : _e.systemPrompt,
58
+ activePrimerHistory: (_f = input.activeAgent) === null || _f === void 0 ? void 0 : _f.primerHistory,
59
+ activeFoldStack: input.activeFoldStack,
60
+ // Context window + cost snapshot. `sessionCostUsd` is the chat-scoped
61
+ // total (per-message `cost` summed); the transport's lifetime cost is
62
+ // not included here because it pools other call sites (suggestions,
63
+ // criteria interpretation, etc.) and would be misleading next to the
64
+ // chat-only token counts.
65
+ context: {
66
+ model: input.activeModel,
67
+ contextTokens: input.contextTokens,
68
+ contextLimit: input.contextLimit,
69
+ contextUsagePercent,
70
+ sessionCostUsd: input.sessionCostUsd,
71
+ sessionTokensConsumed: input.sessionTokensConsumed,
72
+ // The per-bucket split alongside the total. Without it a log shows a large
73
+ // token count next to a small cost with no way to tell why — the answer is
74
+ // almost always that most of the prompt was a cache hit.
75
+ sessionUsage: input.sessionUsage,
76
+ },
77
+ // Snapshot captured fresh at log-export time — reflects state NOW, which
78
+ // may have transitioned since the last LLM call.
79
+ activeDebugSnapshot,
80
+ debug: input.debugState,
81
+ },
82
+ };
83
+ // Stable dedup signature for the forward-capture stream (GENC-1351 §5.8 / #12):
84
+ // the near-static config only. Excludes the volatile fields — the export
85
+ // `timestamp`, the per-turn `context` (tokens/cost), and the live
86
+ // `activeDebugSnapshot` — whose churn otherwise made the whole-`meta` dedup key
87
+ // differ on every throttled flush, so a bulky snapshot was re-appended each time
88
+ // instead of "only when the block actually changed". The volatile evolution is
89
+ // already in the timeline (turn snapshots + `context.updated` events), so the
90
+ // persister only needs a fresh meta-snapshot when the config/prompt changes.
91
+ // Consequence for the download path: the newest STORED snapshot's context/cost
92
+ // figures are stale, which is why `buildDownloadLog` appends a fresh one.
93
+ //
94
+ // DIGESTED rather than stored verbatim (GENC-1566). The projection is right; keeping a
95
+ // full copy of it was not. It is only ever compared for equality, and `agentSummary`
96
+ // alone was 159 KB in the session that prompted this — so each snapshot carried the
97
+ // block plus a stringified copy of most of it, and both went up the wire on every
98
+ // flush. See {@link configDigest} for the hash and why a collision is harmless here.
99
+ const m = metaSnapshot.meta;
100
+ metaSnapshot.dedupSignature = configDigest(JSON.stringify({
101
+ host: m.host,
102
+ agentSummary: m.agentSummary,
103
+ activeSystemPrompt: m.activeSystemPrompt,
104
+ activePrimerHistory: m.activePrimerHistory,
105
+ activeFoldStack: m.activeFoldStack,
106
+ }));
107
+ return metaSnapshot;
108
+ }
@@ -1,5 +1,5 @@
1
1
  import { __awaiter } from "tslib";
2
- import { OrchestratingDriver } from '../../components/orchestrating-driver/orchestrating-driver';
2
+ import { asOrchestrator } from '../../components/orchestrating-driver/orchestrating-driver';
3
3
  import { flattenSubAgentMessages } from '../../utils/flatten-sub-agent-messages';
4
4
  import { logger } from '../../utils/logger';
5
5
  import { isSessionNoticeMarker, SESSION_RESTORE_FAILED_LABEL, SESSION_RESTORED_LABEL, } from '../../utils/message-partition';
@@ -639,9 +639,10 @@ export class SessionPersister {
639
639
  // (flow-owned but unpinned) — `resolvePinnedAgent` reads `flowOwnerAgentName ??
640
640
  // pinnedAgentName`, so restoring both resumes the flow without re-classifying, and the
641
641
  // driver's routing agrees with the restored (picker-locked) store state.
642
- if (driver instanceof OrchestratingDriver) {
643
- driver.setPinnedAgent((_d = snapshot.pinnedAgentName) !== null && _d !== void 0 ? _d : null);
644
- driver.setFlowOwner((_e = snapshot.flowOwnerAgentName) !== null && _e !== void 0 ? _e : null);
642
+ const orchestrator = asOrchestrator(driver);
643
+ if (orchestrator) {
644
+ orchestrator.setPinnedAgent((_d = snapshot.pinnedAgentName) !== null && _d !== void 0 ? _d : null);
645
+ orchestrator.setFlowOwner((_e = snapshot.flowOwnerAgentName) !== null && _e !== void 0 ? _e : null);
645
646
  }
646
647
  logger.debug('Session restored', { key, messages: messages.length });
647
648
  }
@@ -0,0 +1,209 @@
1
+ # Migration Guide — GENC-1580 (agent lifecycle leaves the orchestrator)
2
+
3
+ > ## ⚠️ Not shipped yet — do not action this guide
4
+ >
5
+ > **Nothing described below has landed.** This guide was written ahead of the change so the public
6
+ > delta could be agreed before any code moved, and it is published early only so that agreement is
7
+ > reviewable. It describes an *intended* contract.
8
+ >
9
+ > **In the package you are reading this in, the old API is still the live one:**
10
+ >
11
+ > | This guide says | Actually available today |
12
+ > | --- | --- |
13
+ > | `ChatDriver.installAgent` | ✗ — still `ChatDriver.applyAgent`, unchanged |
14
+ > | `ChatDriver.activateAgent` | ✗ — does not exist |
15
+ > | `ChatDriver.agentSession` | ✗ — does not exist |
16
+ > | `pinned-changed` is dispatched | ✗ — still dead wiring |
17
+ >
18
+ > **Self-check, whatever version you are on:** if `installAgent` is not present on `ChatDriver`,
19
+ > none of this has landed and you should change nothing.
20
+ >
21
+ > GENC-1580 ships in more than one PR. The first delivered an internal decomposition of `main.ts`
22
+ > only — five feature controllers, no public API change of any kind. **The agent-lifecycle work
23
+ > described here comes in a later PR under the same ticket**, and this notice is removed in the
24
+ > same change that makes the guide true.
25
+ >
26
+ > ---
27
+ >
28
+ > When it does land: **config-compatible — no changes required to `chatConfig`, `agents`, or
29
+ > `persistence`.** No element property, attribute, event or `::part()` changes. Nothing about which
30
+ > driver runs your agents changes, so **no runtime behaviour changes**.
31
+ >
32
+ > You will need to read this if you call `ChatDriver` directly, or if you implement `AiDriver`
33
+ > yourself. If you only configure the element, there is nothing here for you.
34
+ >
35
+ > All surfaces below are `@beta` unless marked otherwise.
36
+
37
+ ---
38
+
39
+ ## Why
40
+
41
+ Stateful agents — anything built with `defineStatefulAgent`, or any `AgentConfig` declaring
42
+ `onActivate`/`onDeactivate` — only worked under `OrchestratingDriver`. That was not a design
43
+ decision; it was where the code happened to live.
44
+
45
+ The contract was split across both drivers. `ChatDriver` **raised** the signals: it offers
46
+ `releaseAgent` to tool handlers and records the call via `getAgentReleaseRequested()`.
47
+ `OrchestratingDriver` was the only thing that **acted** on them — the only caller of
48
+ `onActivate`/`onDeactivate`, the only holder of the restored-state images that reach an agent's
49
+ `init` as `ctx.restored`, and the only implementer of `getActiveAgent()`, through which
50
+ `serialize()` and `getDebugSnapshot()` are reached.
51
+
52
+ The visible consequence was that the element routed *every* agents-configured session through the
53
+ orchestrator — even a single agent with no routing to do — purely so the hooks would fire. A
54
+ session with no agents at all got a bare `ChatDriver` and could not host a stateful agent.
55
+
56
+ This change moves that lifecycle into an `AgentSession` that both drivers own, so the capability no
57
+ longer depends on which driver you got.
58
+
59
+ ## What changed
60
+
61
+ ### 1. `ChatDriver.applyAgent` is renamed to `installAgent`
62
+
63
+ **This is the only breaking change in this release.** `applyAgent` was public `@beta` and appeared
64
+ in the published type rollup.
65
+
66
+ ```ts
67
+ // before
68
+ driver.applyAgent(config);
69
+
70
+ // after
71
+ driver.installAgent(config);
72
+ ```
73
+
74
+ The behaviour is byte-identical: it installs an agent's system prompt, tool definitions, tool
75
+ handlers and per-agent provider settings. It does **not** fire lifecycle hooks, and it never did.
76
+
77
+ It was renamed because a new sibling now does:
78
+
79
+ ```ts
80
+ /** Fire `onDeactivate`/`onActivate`, consume any restored state, then install. */
81
+ await driver.activateAgent(config);
82
+ ```
83
+
84
+ Two methods called `applyAgent` and `activateAgent`, one firing hooks and one not, is a footgun —
85
+ and a demonstrated one. The hookless method is what `invokeSubAgent` calls, which is why sub-agent
86
+ lifecycle hooks have never fired (see [Known remaining](#known-remaining-sub-agent-lifecycle)). The
87
+ name `installAgent` says what it does, so the next reader has to choose deliberately.
88
+
89
+ **Which one do you want?** If you are driving a single agent yourself and it has lifecycle hooks or
90
+ state to restore, `activateAgent`. If you are re-applying a per-turn tool surface on an agent
91
+ already activated, `installAgent`.
92
+
93
+ ### 2. `ChatDriver.agentSession` is exposed
94
+
95
+ ```ts
96
+ /** @internal */
97
+ readonly agentSession: AgentSession;
98
+ ```
99
+
100
+ `AgentSession` owns one conversation's agent lifecycle: the live active `AgentConfig`, the
101
+ `onActivate`/`onDeactivate` hooks, the pin and flow-owner locks, and the restored state images
102
+ waiting to be handed back. It knows nothing about drivers, routing or history.
103
+
104
+ It is **public but tagged `@internal`** — `OrchestratingDriver` reaches through the inner driver to
105
+ it, so it cannot be private, but it is not a supported surface and may change without a migration
106
+ guide. Prefer the delegating methods on the driver (§3) over touching it.
107
+
108
+ It is reached through `ChatDriver` rather than owned separately by each driver because there is one
109
+ session per conversation, and the inner driver outlives any routing decision made above it. That
110
+ also puts `getAgentReleaseRequested()` and the session that responds to it in the same object,
111
+ which is the coupling that used to span two classes.
112
+
113
+ ### 3. Four `AiDriver` members are no longer optional
114
+
115
+ These moved from optional to required, because `ChatDriver` now implements all four:
116
+
117
+ | Member | Was | Now |
118
+ | --- | --- | --- |
119
+ | `getActiveAgent()` | `OrchestratingDriver` only | both |
120
+ | `setPinnedAgent(name)` | `OrchestratingDriver` only | both |
121
+ | `setFlowOwner(name)` | `OrchestratingDriver` only | both |
122
+ | `primeRestoredAgentState(snapshots)` | `OrchestratingDriver` only | both |
123
+
124
+ **If you implement `AiDriver` yourself, this is a breaking change** — you must add all four.
125
+ Delegate to an `AgentSession` if you want the standard semantics, or return `undefined` / no-op if
126
+ your driver genuinely owns no agents.
127
+
128
+ Callers can drop the optional-call guards:
129
+
130
+ ```ts
131
+ // before
132
+ const reserve = driver.getActiveAgent?.()?.contextReserve;
133
+
134
+ // after
135
+ const reserve = driver.getActiveAgent()?.contextReserve;
136
+ ```
137
+
138
+ The remaining ten optional members on `AiDriver` are unchanged. They are a separate problem, and
139
+ `ai-driver.ts` still carries a doc comment claiming the element depends only on this interface,
140
+ which is not yet true.
141
+
142
+ ### 4. `pinned-changed` is now actually dispatched
143
+
144
+ `setPinnedAgent()` was a bare assignment that emitted nothing, while the element registered a
145
+ listener for `pinned-changed` and a comment asserting the driver did emit it. Neither half was
146
+ right.
147
+
148
+ `AgentSession.setPinnedAgent()` now emits `pinned-changed` with `string | null`, on the owning
149
+ driver. If you were listening for it and quietly receiving nothing, you will now receive events.
150
+ If you were not, nothing changes — the element's own pin path writes through its
151
+ `pinnedAgentName` setter and guards against the redundant round-trip.
152
+
153
+ ### 5. Stateful agents no longer depend on the orchestrator
154
+
155
+ `onActivate`, `onDeactivate`, `ctx.restored`, `serialize()`, `getDebugSnapshot()` and
156
+ `releaseAgent` now work identically under either driver.
157
+
158
+ **This is a capability, not yet a behaviour change.** Driver selection is deliberately untouched in
159
+ this release: a configured `agents` array still gets `OrchestratingDriver`, exactly as before, and
160
+ a single-agent session still pays for a classifier that short-circuits. Making the element choose a
161
+ bare `ChatDriver` for a single agent is a follow-up, precisely because it *would* change runtime
162
+ behaviour on the session-restore path and deserves its own release to be judged against.
163
+
164
+ ## What did not change
165
+
166
+ - Every `chatConfig`, `agents` and `persistence` option, and every element property, attribute,
167
+ method, event and `::part()`.
168
+ - Which driver runs your agents. `agents.length > 0` still means `OrchestratingDriver`.
169
+ - The order and timing of lifecycle hooks: outgoing `onDeactivate` is awaited before incoming
170
+ `onActivate`; a hook that throws is logged and swallowed rather than stranding the turn; a
171
+ restored image is consumed exactly once per activation.
172
+ - Which agent owns a flow. Stateful agents still auto-lock on activation, still hold the lock
173
+ across turns, and still release only via `releaseAgent` or teardown. The user pin still survives
174
+ a release.
175
+ - `OrchestratingDriver`'s routing: classification, handoffs, the handoff cap, terminality rules,
176
+ the continuation tool, and per-agent history masking.
177
+ - `OrchestratingDriver.applyAgent` — it was already private, and stays private. It shrinks, but its
178
+ name and signature are not part of any contract.
179
+ - Session persistence and restore, including the shape written to the persistence provider.
180
+
181
+ ## Known remaining: sub-agent lifecycle
182
+
183
+ **A stateful agent used as a sub-agent still gets no lifecycle hooks.** `invokeSubAgent` installs
184
+ the child with the hookless path and tears it down with `dispose()`, so `onActivate` and
185
+ `onDeactivate` never fire for it and its `serialize()` is never persisted.
186
+
187
+ This has the same root cause and is deliberately out of scope, because fixing it needs decisions
188
+ this refactor should not be making on its own:
189
+
190
+ - Should a child's `onActivate` fire at all, given the parent already activated an agent?
191
+ - What `sessionKey` does a child's lifecycle context carry?
192
+ - Does a child's serialized state belong in the session snapshot, and under what key?
193
+
194
+ Until that is settled, treat lifecycle hooks as a top-level-agent feature. A stateful agent
195
+ invoked as a sub-agent will run its tools correctly but will not initialise or tear down state.
196
+
197
+ ## Internal reorganisation
198
+
199
+ This release also splits the two largest modules. None of it is consumer-visible through the
200
+ package's entry points (`.`, `./config`, `./chat-driver`, `./react`), but if you deep-import from
201
+ `dist/esm/...` — which is unsupported — paths have moved:
202
+
203
+ - `chat-driver.ts` sheds its turn-failure taxonomy, interaction handling, turn recording, turn
204
+ setup, fold machinery and provider resolution into sibling modules.
205
+ - `main.ts` sheds the settings modal, composer controls, cost ledger, budget latching, context gate
206
+ and diagnostics assembly into controllers.
207
+
208
+ See [`code-health.md`](./code-health.md) for the analysis behind the split. That file is excluded
209
+ from the published package.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genesislcap/ai-assistant",
3
3
  "description": "Genesis AI Assistant micro-frontend",
4
- "version": "15.23.3",
4
+ "version": "15.24.0",
5
5
  "license": "SEE LICENSE IN license.txt",
6
6
  "main": "dist/esm/index.js",
7
7
  "types": "dist/ai-assistant.d.ts",
@@ -74,26 +74,26 @@
74
74
  }
75
75
  },
76
76
  "devDependencies": {
77
- "@genesislcap/foundation-testing": "15.23.3",
78
- "@genesislcap/genx": "15.23.3",
79
- "@genesislcap/rollup-builder": "15.23.3",
80
- "@genesislcap/ts-builder": "15.23.3",
81
- "@genesislcap/uvu-playwright-builder": "15.23.3",
82
- "@genesislcap/vite-builder": "15.23.3",
83
- "@genesislcap/webpack-builder": "15.23.3",
77
+ "@genesislcap/foundation-testing": "15.24.0",
78
+ "@genesislcap/genx": "15.24.0",
79
+ "@genesislcap/rollup-builder": "15.24.0",
80
+ "@genesislcap/ts-builder": "15.24.0",
81
+ "@genesislcap/uvu-playwright-builder": "15.24.0",
82
+ "@genesislcap/vite-builder": "15.24.0",
83
+ "@genesislcap/webpack-builder": "15.24.0",
84
84
  "@types/dompurify": "^3.0.5",
85
85
  "@types/marked": "^5.0.2",
86
86
  "esbuild": "0.25.12"
87
87
  },
88
88
  "dependencies": {
89
- "@genesislcap/foundation-ai": "15.23.3",
90
- "@genesislcap/foundation-logger": "15.23.3",
91
- "@genesislcap/foundation-notifications": "15.23.3",
92
- "@genesislcap/foundation-redux": "15.23.3",
93
- "@genesislcap/foundation-ui": "15.23.3",
94
- "@genesislcap/foundation-utils": "15.23.3",
95
- "@genesislcap/rapid-design-system": "15.23.3",
96
- "@genesislcap/web-core": "15.23.3",
89
+ "@genesislcap/foundation-ai": "15.24.0",
90
+ "@genesislcap/foundation-logger": "15.24.0",
91
+ "@genesislcap/foundation-notifications": "15.24.0",
92
+ "@genesislcap/foundation-redux": "15.24.0",
93
+ "@genesislcap/foundation-ui": "15.24.0",
94
+ "@genesislcap/foundation-utils": "15.24.0",
95
+ "@genesislcap/rapid-design-system": "15.24.0",
96
+ "@genesislcap/web-core": "15.24.0",
97
97
  "dompurify": "^3.3.1",
98
98
  "marked": "^17.0.3"
99
99
  },