@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.
- package/dist/ai-assistant.api.json +419 -50
- package/dist/ai-assistant.d.ts +217 -683
- package/dist/chat-driver.cjs.map +1 -1
- package/dist/chat-driver.mjs.map +1 -1
- package/dist/custom-elements.json +310 -609
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +16 -0
- package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
- package/dist/dts/components/settings-modal/index.d.ts +1 -0
- package/dist/dts/components/settings-modal/index.d.ts.map +1 -1
- package/dist/dts/components/settings-modal/settings-modal.d.ts +215 -0
- package/dist/dts/components/settings-modal/settings-modal.d.ts.map +1 -0
- package/dist/dts/components/settings-modal/settings-modal.template.d.ts.map +1 -1
- package/dist/dts/main/attachment-controller.d.ts +66 -0
- package/dist/dts/main/attachment-controller.d.ts.map +1 -0
- package/dist/dts/main/budget-controller.d.ts +368 -0
- package/dist/dts/main/budget-controller.d.ts.map +1 -0
- package/dist/dts/main/composer-menu-controller.d.ts +113 -0
- package/dist/dts/main/composer-menu-controller.d.ts.map +1 -0
- package/dist/dts/main/composer-resize-controller.d.ts +80 -0
- package/dist/dts/main/composer-resize-controller.d.ts.map +1 -0
- package/dist/dts/main/context-gate-controller.d.ts +197 -0
- package/dist/dts/main/context-gate-controller.d.ts.map +1 -0
- package/dist/dts/main/cost-ledger-controller.d.ts +228 -0
- package/dist/dts/main/cost-ledger-controller.d.ts.map +1 -0
- package/dist/dts/main/main.d.ts +201 -722
- package/dist/dts/main/main.d.ts.map +1 -1
- package/dist/dts/main/main.types.d.ts +25 -0
- package/dist/dts/main/main.types.d.ts.map +1 -1
- package/dist/dts/main/meta-snapshot.d.ts +50 -0
- package/dist/dts/main/meta-snapshot.d.ts.map +1 -0
- package/dist/dts/state/persistence/session-persister.d.ts.map +1 -1
- package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +18 -0
- package/dist/esm/components/settings-modal/index.js +1 -0
- package/dist/esm/components/settings-modal/settings-modal.js +436 -0
- package/dist/esm/components/settings-modal/settings-modal.template.js +15 -4
- package/dist/esm/main/attachment-controller.js +254 -0
- package/dist/esm/main/budget-controller.js +745 -0
- package/dist/esm/main/composer-menu-controller.js +234 -0
- package/dist/esm/main/composer-resize-controller.js +119 -0
- package/dist/esm/main/context-gate-controller.js +289 -0
- package/dist/esm/main/cost-ledger-controller.js +498 -0
- package/dist/esm/main/main.js +501 -2268
- package/dist/esm/main/meta-snapshot.js +108 -0
- package/dist/esm/state/persistence/session-persister.js +5 -4
- package/docs/migration-GENC-1580.md +209 -0
- 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 {
|
|
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
|
-
|
|
643
|
-
|
|
644
|
-
|
|
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.
|
|
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.
|
|
78
|
-
"@genesislcap/genx": "15.
|
|
79
|
-
"@genesislcap/rollup-builder": "15.
|
|
80
|
-
"@genesislcap/ts-builder": "15.
|
|
81
|
-
"@genesislcap/uvu-playwright-builder": "15.
|
|
82
|
-
"@genesislcap/vite-builder": "15.
|
|
83
|
-
"@genesislcap/webpack-builder": "15.
|
|
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.
|
|
90
|
-
"@genesislcap/foundation-logger": "15.
|
|
91
|
-
"@genesislcap/foundation-notifications": "15.
|
|
92
|
-
"@genesislcap/foundation-redux": "15.
|
|
93
|
-
"@genesislcap/foundation-ui": "15.
|
|
94
|
-
"@genesislcap/foundation-utils": "15.
|
|
95
|
-
"@genesislcap/rapid-design-system": "15.
|
|
96
|
-
"@genesislcap/web-core": "15.
|
|
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
|
},
|