@genesislcap/ai-assistant 14.467.2 → 14.468.0-FUI-2555.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.
- package/dist/ai-assistant.d.ts +39 -1
- package/dist/dts/components/chat-driver/chat-driver.d.ts +38 -0
- package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
- package/dist/dts/state/debug-event-log.d.ts +1 -1
- package/dist/dts/state/debug-event-log.d.ts.map +1 -1
- package/dist/dts/utils/condense-history.d.ts +115 -0
- package/dist/dts/utils/condense-history.d.ts.map +1 -0
- package/dist/dts/utils/condense-history.test.d.ts +2 -0
- package/dist/dts/utils/condense-history.test.d.ts.map +1 -0
- package/dist/esm/components/chat-driver/chat-driver.js +108 -7
- package/dist/esm/components/chat-driver/chat-driver.test.js +196 -1
- package/dist/esm/state/debug-event-log.js +3 -2
- package/dist/esm/utils/condense-history.js +218 -0
- package/dist/esm/utils/condense-history.test.js +297 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +16 -16
- package/src/components/chat-driver/chat-driver.test.ts +233 -1
- package/src/components/chat-driver/chat-driver.ts +120 -6
- package/src/state/debug-event-log.ts +4 -2
- package/src/utils/condense-history.test.ts +373 -0
- package/src/utils/condense-history.ts +306 -0
package/dist/ai-assistant.d.ts
CHANGED
|
@@ -712,6 +712,40 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
|
|
|
712
712
|
* sent to the model — stored `history` stays unchanged for UI and logging.
|
|
713
713
|
*/
|
|
714
714
|
private providerHistoryTransform?;
|
|
715
|
+
/**
|
|
716
|
+
* Tool-declared condensation policies, keyed by tool-call id. Populated by
|
|
717
|
+
* `condenseWhen` (first-wins per call); read by `applyCondensation` before each
|
|
718
|
+
* provider call to collapse stale payloads from the model-bound history only.
|
|
719
|
+
* Accumulates across agents on a shared driver (a superseded read collapses no
|
|
720
|
+
* matter which agent made it) and is never cleared — it dies with the driver.
|
|
721
|
+
*/
|
|
722
|
+
private readonly condensePolicies;
|
|
723
|
+
/**
|
|
724
|
+
* Monotonic model-call counter for the driver's whole lifetime — the age clock
|
|
725
|
+
* for `condenseWhen({ on: { kind: 'age' } })`. The per-`sendMessage` `iterations`
|
|
726
|
+
* loop counter resets to 0 every turn, so it can only measure age WITHIN a
|
|
727
|
+
* single turn; this never resets, so `age` counts model-calls since the result
|
|
728
|
+
* appeared across turn boundaries (each short turn still advances it ≥ 1).
|
|
729
|
+
* Bumped once per tool-loop iteration (provider call).
|
|
730
|
+
*/
|
|
731
|
+
private modelCallSeq;
|
|
732
|
+
/**
|
|
733
|
+
* Monotonic turn counter — the `turnEnd` clock. Bumped once per `sendMessage`
|
|
734
|
+
* (a user turn; NOT per handoff continuation, which is the same request), never
|
|
735
|
+
* reset. `turnEnd` collapses a payload once `turnSeq` exceeds the turn it was
|
|
736
|
+
* created in.
|
|
737
|
+
*/
|
|
738
|
+
private turnSeq;
|
|
739
|
+
/**
|
|
740
|
+
* Monotonic agent-activation counter — the `agentEnd` clock. Advances when the
|
|
741
|
+
* active flow ends: a swap to a different-named agent (`applyAgent`) OR an
|
|
742
|
+
* explicit `releaseAgent` / `completeSubAgent`. A stateful agent re-resolving
|
|
743
|
+
* the same name across turns keeps one activation. `agentEnd` fires for a
|
|
744
|
+
* payload once a LATER activation is current (`callActivation < currentActivation`)
|
|
745
|
+
* — so a re-run of a released agent gets a fresh activation and is NOT
|
|
746
|
+
* collapsed until IT ends.
|
|
747
|
+
*/
|
|
748
|
+
private currentActivation;
|
|
715
749
|
/** Stack of fold frames — grows when a fold opens, shrinks when it closes. */
|
|
716
750
|
private foldStack;
|
|
717
751
|
/** Consecutive fold open/close ops without a real tool call. Reset on real tool execution. */
|
|
@@ -1068,6 +1102,10 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
|
|
|
1068
1102
|
* Centralised here so fold shortcut dispatch and the main tool loop use the
|
|
1069
1103
|
* same context without duplication.
|
|
1070
1104
|
*
|
|
1105
|
+
* @param activeToolCallId - The id of the tool call this context belongs to, so
|
|
1106
|
+
* `condenseWhen` can register against the right call (it stamps the clocks
|
|
1107
|
+
* straight off the driver). Absent for dispatch paths with no addressable tool
|
|
1108
|
+
* call (e.g. the fold-close handler), where `condenseWhen` is a no-op.
|
|
1071
1109
|
* @param traceCapture - Optional per-invocation slot. When provided, the trace
|
|
1072
1110
|
* from any sub-agent call is written here rather than to shared instance state,
|
|
1073
1111
|
* so parallel tool calls each capture their own trace independently.
|
|
@@ -1943,7 +1981,7 @@ declare type MetaEventImportance = 'high' | 'normal' | 'low';
|
|
|
1943
1981
|
* Catalogue of meta event names. This is the documented surface — extend it as
|
|
1944
1982
|
* new events are wired in (Tier 2/3 lifecycle, interaction, provider events).
|
|
1945
1983
|
*/
|
|
1946
|
-
declare type MetaEventType = 'assistant.connected' | 'assistant.disconnected' | 'assistant.popout' | 'assistant.popin' | 'driver.created' | 'driver.wired' | 'driver.unwired' | 'state.changed' | 'turn.start' | 'turn.end' | 'turn.retry' | 'turn.error' | 'tool.failed' | 'tool.unresolved' | 'subagent.started' | 'subagent.completed' | 'subagent.failed' | 'agent.handoff' | 'agent.pinned' | 'agent.unpinned' | 'provider.selected' | 'interaction.requested' | 'interaction.resolved' | 'context.updated' | 'context.threshold-crossed' | 'panel.toggled' | 'attachment.added' | 'file.read-failed' | 'suggestions.failed';
|
|
1984
|
+
declare type MetaEventType = 'assistant.connected' | 'assistant.disconnected' | 'assistant.popout' | 'assistant.popin' | 'driver.created' | 'driver.wired' | 'driver.unwired' | 'state.changed' | 'turn.start' | 'turn.end' | 'turn.retry' | 'turn.error' | 'tool.failed' | 'tool.unresolved' | 'subagent.started' | 'subagent.completed' | 'subagent.failed' | 'agent.handoff' | 'agent.pinned' | 'agent.unpinned' | 'provider.selected' | 'interaction.requested' | 'interaction.resolved' | 'context.updated' | 'context.threshold-crossed' | 'context.condensed' | 'panel.toggled' | 'attachment.added' | 'file.read-failed' | 'suggestions.failed';
|
|
1947
1985
|
|
|
1948
1986
|
/**
|
|
1949
1987
|
* Orchestrates multiple specialist agents. Sits between `FoundationAiAssistant`
|
|
@@ -129,6 +129,40 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
|
|
|
129
129
|
* sent to the model — stored `history` stays unchanged for UI and logging.
|
|
130
130
|
*/
|
|
131
131
|
private providerHistoryTransform?;
|
|
132
|
+
/**
|
|
133
|
+
* Tool-declared condensation policies, keyed by tool-call id. Populated by
|
|
134
|
+
* `condenseWhen` (first-wins per call); read by `applyCondensation` before each
|
|
135
|
+
* provider call to collapse stale payloads from the model-bound history only.
|
|
136
|
+
* Accumulates across agents on a shared driver (a superseded read collapses no
|
|
137
|
+
* matter which agent made it) and is never cleared — it dies with the driver.
|
|
138
|
+
*/
|
|
139
|
+
private readonly condensePolicies;
|
|
140
|
+
/**
|
|
141
|
+
* Monotonic model-call counter for the driver's whole lifetime — the age clock
|
|
142
|
+
* for `condenseWhen({ on: { kind: 'age' } })`. The per-`sendMessage` `iterations`
|
|
143
|
+
* loop counter resets to 0 every turn, so it can only measure age WITHIN a
|
|
144
|
+
* single turn; this never resets, so `age` counts model-calls since the result
|
|
145
|
+
* appeared across turn boundaries (each short turn still advances it ≥ 1).
|
|
146
|
+
* Bumped once per tool-loop iteration (provider call).
|
|
147
|
+
*/
|
|
148
|
+
private modelCallSeq;
|
|
149
|
+
/**
|
|
150
|
+
* Monotonic turn counter — the `turnEnd` clock. Bumped once per `sendMessage`
|
|
151
|
+
* (a user turn; NOT per handoff continuation, which is the same request), never
|
|
152
|
+
* reset. `turnEnd` collapses a payload once `turnSeq` exceeds the turn it was
|
|
153
|
+
* created in.
|
|
154
|
+
*/
|
|
155
|
+
private turnSeq;
|
|
156
|
+
/**
|
|
157
|
+
* Monotonic agent-activation counter — the `agentEnd` clock. Advances when the
|
|
158
|
+
* active flow ends: a swap to a different-named agent (`applyAgent`) OR an
|
|
159
|
+
* explicit `releaseAgent` / `completeSubAgent`. A stateful agent re-resolving
|
|
160
|
+
* the same name across turns keeps one activation. `agentEnd` fires for a
|
|
161
|
+
* payload once a LATER activation is current (`callActivation < currentActivation`)
|
|
162
|
+
* — so a re-run of a released agent gets a fresh activation and is NOT
|
|
163
|
+
* collapsed until IT ends.
|
|
164
|
+
*/
|
|
165
|
+
private currentActivation;
|
|
132
166
|
/** Stack of fold frames — grows when a fold opens, shrinks when it closes. */
|
|
133
167
|
private foldStack;
|
|
134
168
|
/** Consecutive fold open/close ops without a real tool call. Reset on real tool execution. */
|
|
@@ -485,6 +519,10 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
|
|
|
485
519
|
* Centralised here so fold shortcut dispatch and the main tool loop use the
|
|
486
520
|
* same context without duplication.
|
|
487
521
|
*
|
|
522
|
+
* @param activeToolCallId - The id of the tool call this context belongs to, so
|
|
523
|
+
* `condenseWhen` can register against the right call (it stamps the clocks
|
|
524
|
+
* straight off the driver). Absent for dispatch paths with no addressable tool
|
|
525
|
+
* call (e.g. the fold-close handler), where `condenseWhen` is a no-op.
|
|
488
526
|
* @param traceCapture - Optional per-invocation slot. When provided, the trace
|
|
489
527
|
* from any sub-agent call is written here rather than to shared instance state,
|
|
490
528
|
* so parallel tool calls each capture their own trace independently.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-driver.d.ts","sourceRoot":"","sources":["../../../../src/components/chat-driver/chat-driver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,WAAW,EAGX,cAAc,
|
|
1
|
+
{"version":3,"file":"chat-driver.d.ts","sourceRoot":"","sources":["../../../../src/components/chat-driver/chat-driver.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* Catalogue of meta event names. This is the documented surface — extend it as
|
|
28
28
|
* new events are wired in (Tier 2/3 lifecycle, interaction, provider events).
|
|
29
29
|
*/
|
|
30
|
-
export type MetaEventType = 'assistant.connected' | 'assistant.disconnected' | 'assistant.popout' | 'assistant.popin' | 'driver.created' | 'driver.wired' | 'driver.unwired' | 'state.changed' | 'turn.start' | 'turn.end' | 'turn.retry' | 'turn.error' | 'tool.failed' | 'tool.unresolved' | 'subagent.started' | 'subagent.completed' | 'subagent.failed' | 'agent.handoff' | 'agent.pinned' | 'agent.unpinned' | 'provider.selected' | 'interaction.requested' | 'interaction.resolved' | 'context.updated' | 'context.threshold-crossed' | 'panel.toggled' | 'attachment.added' | 'file.read-failed' | 'suggestions.failed';
|
|
30
|
+
export type MetaEventType = 'assistant.connected' | 'assistant.disconnected' | 'assistant.popout' | 'assistant.popin' | 'driver.created' | 'driver.wired' | 'driver.unwired' | 'state.changed' | 'turn.start' | 'turn.end' | 'turn.retry' | 'turn.error' | 'tool.failed' | 'tool.unresolved' | 'subagent.started' | 'subagent.completed' | 'subagent.failed' | 'agent.handoff' | 'agent.pinned' | 'agent.unpinned' | 'provider.selected' | 'interaction.requested' | 'interaction.resolved' | 'context.updated' | 'context.threshold-crossed' | 'context.condensed' | 'panel.toggled' | 'attachment.added' | 'file.read-failed' | 'suggestions.failed';
|
|
31
31
|
/**
|
|
32
32
|
* How much a reader should care about an event — lets a consumer (or an AI
|
|
33
33
|
* agent) filter the timeline: skip `low` UI/bookkeeping noise, skim `normal`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug-event-log.d.ts","sourceRoot":"","sources":["../../../src/state/debug-event-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;GAGG;AACH,MAAM,MAAM,aAAa,GAErB,qBAAqB,GACrB,wBAAwB,GACxB,kBAAkB,GAClB,iBAAiB,GAEjB,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAEhB,eAAe,GACf,YAAY,GACZ,UAAU,GACV,YAAY,GACZ,YAAY,GACZ,aAAa,GACb,iBAAiB,GACjB,kBAAkB,GAClB,oBAAoB,GACpB,iBAAiB,GAEjB,eAAe,GACf,cAAc,GACd,gBAAgB,GAChB,mBAAmB,GAEnB,uBAAuB,GACvB,sBAAsB,GAEtB,iBAAiB,GACjB,2BAA2B,
|
|
1
|
+
{"version":3,"file":"debug-event-log.d.ts","sourceRoot":"","sources":["../../../src/state/debug-event-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;GAGG;AACH,MAAM,MAAM,aAAa,GAErB,qBAAqB,GACrB,wBAAwB,GACxB,kBAAkB,GAClB,iBAAiB,GAEjB,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAEhB,eAAe,GACf,YAAY,GACZ,UAAU,GACV,YAAY,GACZ,YAAY,GACZ,aAAa,GACb,iBAAiB,GACjB,kBAAkB,GAClB,oBAAoB,GACpB,iBAAiB,GAEjB,eAAe,GACf,cAAc,GACd,gBAAgB,GAChB,mBAAmB,GAEnB,uBAAuB,GACvB,sBAAsB,GAEtB,iBAAiB,GACjB,2BAA2B,GAC3B,mBAAmB,GAEnB,eAAe,GACf,kBAAkB,GAClB,kBAAkB,GAClB,oBAAoB,CAAC;AAEzB;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE5D;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,aAAa,EAAE,mBAAmB,CAiC5E,CAAC;AAEF,4CAA4C;AAC5C,MAAM,WAAW,SAAS;IACxB,0FAA0F;IAC1F,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,IAAI,EAAE,aAAa,CAAC;IACpB,6EAA6E;IAC7E,UAAU,EAAE,mBAAmB,CAAC;IAChC,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAmBD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,aAAa,EACnB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,IAAI,CAyBN;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,iBAAiB,GACzB,WAAW,GACX,yBAAyB,GACzB,gBAAgB,GAChB,oBAAoB,GACpB,gBAAgB,CAAC;AAErB;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,iBAAiB,EACzB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,IAAI,CAEN;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,iBAAiB,EACzB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,IAAI,CAEN;AAED,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,CAEnE;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI,CA0BrF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAc7C,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { ChatMessage, CondensePolicy } from '@genesislcap/foundation-ai';
|
|
2
|
+
/**
|
|
3
|
+
* Tool-context condensation: collapse stale tool payloads out of the history
|
|
4
|
+
* sent to the model, while leaving stored history untouched.
|
|
5
|
+
*
|
|
6
|
+
* The driver owns the registry (tool handlers populate it via `condenseWhen`)
|
|
7
|
+
* and the cadence (this runs before every provider call). This module owns the
|
|
8
|
+
* pure application: given the registry + the current loop iteration, produce a
|
|
9
|
+
* rewritten copy of the history with stale args/results replaced by stubs. Kept
|
|
10
|
+
* pure (no driver/session state, no logging) so it unit-tests in isolation —
|
|
11
|
+
* the one-time `context.condensed` signal is delivered via an `onCondensed`
|
|
12
|
+
* callback rather than reaching into the debug-event log directly.
|
|
13
|
+
*
|
|
14
|
+
* @packageDocumentation
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Below this serialized size a tool payload isn't worth condensing — the stub
|
|
18
|
+
* would save little and cost a breadcrumb. A driver-level floor so the public
|
|
19
|
+
* `condenseWhen` API needs no per-policy threshold field.
|
|
20
|
+
*/
|
|
21
|
+
export declare const CONDENSE_MIN_CHARS = 1000;
|
|
22
|
+
/** Key the collapsed args are stored under — a tool-call's args must stay a Record. */
|
|
23
|
+
export declare const CONDENSED_ARGS_KEY = "condensed";
|
|
24
|
+
/**
|
|
25
|
+
* A `condenseWhen` policy registered against a tool-call id, with its age clock
|
|
26
|
+
* and report-once flags. The driver holds these in a `Map<toolCallId, …>`;
|
|
27
|
+
* {@link applyCondensation} reads them and flips the `reported*` flags so the
|
|
28
|
+
* `context.condensed` signal fires once per payload, not once per provider call.
|
|
29
|
+
*/
|
|
30
|
+
export interface RegisteredCondensePolicy {
|
|
31
|
+
policy: CondensePolicy;
|
|
32
|
+
/**
|
|
33
|
+
* Monotonic model-call sequence (`modelCallSeq`) when `condenseWhen` was called
|
|
34
|
+
* — the origin of the age clock. Driver-lifetime and NOT reset per turn, so age
|
|
35
|
+
* is measured consistently across turn boundaries (the field name is historical;
|
|
36
|
+
* it is not the per-turn loop iteration).
|
|
37
|
+
*/
|
|
38
|
+
iteration: number;
|
|
39
|
+
/** Turn (`sendMessage`) sequence when the call was made — the `turnEnd` clock. */
|
|
40
|
+
turn: number;
|
|
41
|
+
/** Agent-activation sequence when the call was made — the `agentEnd` clock. */
|
|
42
|
+
activation: number;
|
|
43
|
+
/** `context.condensed` already emitted for the args payload (fire-once). */
|
|
44
|
+
reportedArgs?: boolean;
|
|
45
|
+
/** `context.condensed` already emitted for the response payload (fire-once). */
|
|
46
|
+
reportedResponse?: boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The driver's live state at the moment of a provider call — the clocks every
|
|
50
|
+
* trigger is evaluated against. Passed by the driver; kept as an interface so the
|
|
51
|
+
* transform stays a pure function of (history, policies, clocks).
|
|
52
|
+
*/
|
|
53
|
+
export interface CondenseContext {
|
|
54
|
+
/** Monotonic model-call sequence now — the `age` clock. */
|
|
55
|
+
modelCall: number;
|
|
56
|
+
/** Monotonic turn (`sendMessage`) sequence now — the `turnEnd` clock. */
|
|
57
|
+
turn: number;
|
|
58
|
+
/** Whether the agent activation that made a call has since ended — the `agentEnd` clock. */
|
|
59
|
+
activationEnded: (activation: number) => boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Structured detail for a `context.condensed` meta-event. The index signature
|
|
63
|
+
* lets it satisfy `recordMetaEvent`'s `Record<string, unknown>` detail param
|
|
64
|
+
* while the named fields stay strictly typed.
|
|
65
|
+
*/
|
|
66
|
+
export interface CondensedEventDetail {
|
|
67
|
+
[key: string]: unknown;
|
|
68
|
+
/** Tool-loop iteration the collapsed call was made on. */
|
|
69
|
+
turn: number;
|
|
70
|
+
toolCallId: string;
|
|
71
|
+
tool: string;
|
|
72
|
+
target: 'args' | 'response';
|
|
73
|
+
/** Human-readable trigger, e.g. `superseded:Foo.tsx` or `age:3`. */
|
|
74
|
+
trigger: string;
|
|
75
|
+
/** Length of the replacement stub. */
|
|
76
|
+
stubLen: number;
|
|
77
|
+
/** Estimated input tokens saved this collapse (char/4 — no tokenizer in-stack). */
|
|
78
|
+
tokensSaved: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Collapse stale tool payloads (declared via `condenseWhen`) out of the
|
|
82
|
+
* model-bound history. Pure over the `history` array — it emits new message
|
|
83
|
+
* objects and never mutates the input messages (mirroring the agent-masking
|
|
84
|
+
* transform). It DOES, however, flip the `reported*` flag on the matching
|
|
85
|
+
* `policies` entry the first time a payload collapses — the report-once gate that
|
|
86
|
+
* keeps `onCondensed` firing once per (tool call, payload) even though the
|
|
87
|
+
* collapse itself re-runs before every provider call.
|
|
88
|
+
*
|
|
89
|
+
* Triggers (a policy may list several via `on: Trigger[]` — the FIRST to fire
|
|
90
|
+
* collapses the payload; all are monotonic, so the collapse never reverts):
|
|
91
|
+
* - `superseded` — among all registered calls sharing a `by` key, the LAST in
|
|
92
|
+
* history order survives; every earlier one's targeted payload collapses. A
|
|
93
|
+
* re-call with the same key becomes the new survivor and re-arms the rest.
|
|
94
|
+
* - `age` — the result is first visible one model-call after the call, so `turns`
|
|
95
|
+
* is how many model-calls may see the full result before it collapses
|
|
96
|
+
* (fires when `modelCall − callModelCall > turns`): `turns: 1` is seen once,
|
|
97
|
+
* then collapses. The clock is monotonic across turns.
|
|
98
|
+
* - `turnEnd` — collapses once the turn (`sendMessage`) that made the call has
|
|
99
|
+
* ended (fires when `turn > callTurn`): full for the rest of that request,
|
|
100
|
+
* gone on every later one.
|
|
101
|
+
* - `agentEnd` — collapses once the agent activation that made the call has ended
|
|
102
|
+
* (a swap to another agent, or `releaseAgent`/`completeSubAgent`): kept across
|
|
103
|
+
* all of the agent's turns, dropped when its flow finishes.
|
|
104
|
+
*
|
|
105
|
+
* The tool-call/result envelope is never removed (providers reject orphaned
|
|
106
|
+
* calls/results) — only the args object or the result content is replaced.
|
|
107
|
+
*
|
|
108
|
+
* @param history - The to-model history copy to rewrite (not mutated).
|
|
109
|
+
* @param policies - The driver's registry, keyed by tool-call id. Its entries'
|
|
110
|
+
* `reported*` flags are flipped as payloads first collapse.
|
|
111
|
+
* @param ctx - The driver's live clocks (model-call / turn / agent-activation).
|
|
112
|
+
* @param onCondensed - Invoked once per payload at its full→stub transition.
|
|
113
|
+
*/
|
|
114
|
+
export declare function applyCondensation(history: ChatMessage[], policies: Map<string, RegisteredCondensePolicy>, ctx: CondenseContext, onCondensed: (detail: CondensedEventDetail) => void): ChatMessage[];
|
|
115
|
+
//# sourceMappingURL=condense-history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"condense-history.d.ts","sourceRoot":"","sources":["../../../src/utils/condense-history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAmB,MAAM,4BAA4B,CAAC;AAE/F;;;;;;;;;;;;;GAaG;AAEH;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,uFAAuF;AACvF,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAQ9C;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,cAAc,CAAC;IACvB;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,4FAA4F;IAC5F,eAAe,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;CAClD;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC;IAC5B,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,WAAW,EAAE,MAAM,CAAC;CACrB;AA4CD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,WAAW,EAAE,EACtB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,wBAAwB,CAAC,EAC/C,GAAG,EAAE,eAAe,EACpB,WAAW,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,IAAI,GAClD,WAAW,EAAE,CAoIf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"condense-history.test.d.ts","sourceRoot":"","sources":["../../../src/utils/condense-history.test.ts"],"names":[],"mappings":""}
|
|
@@ -3,6 +3,7 @@ import { isObservableAIProviderRegistry, MalformedFunctionCallError, } from '@ge
|
|
|
3
3
|
import { agenticActivityBus } from '../../channel/ai-activity-bus';
|
|
4
4
|
import { resolveChatProvider } from '../../config/validate-providers';
|
|
5
5
|
import { clearSession, getMetaEvents, mergeMetaEvents, recordMetaEvent, recordTurnError, recordTurnRetry, } from '../../state/debug-event-log';
|
|
6
|
+
import { applyCondensation } from '../../utils/condense-history';
|
|
6
7
|
import { applyHistoryCap } from '../../utils/history-transform';
|
|
7
8
|
import { logger } from '../../utils/logger';
|
|
8
9
|
import { TOOL_FOLD_SYMBOL } from '../../utils/tool-fold';
|
|
@@ -75,6 +76,40 @@ export class ChatDriver extends EventTarget {
|
|
|
75
76
|
/** Epoch ms when the current turn loop began — drives the `turn.end` duration. */
|
|
76
77
|
this.turnStartedAt = 0;
|
|
77
78
|
this.pendingInteractions = new Map();
|
|
79
|
+
/**
|
|
80
|
+
* Tool-declared condensation policies, keyed by tool-call id. Populated by
|
|
81
|
+
* `condenseWhen` (first-wins per call); read by `applyCondensation` before each
|
|
82
|
+
* provider call to collapse stale payloads from the model-bound history only.
|
|
83
|
+
* Accumulates across agents on a shared driver (a superseded read collapses no
|
|
84
|
+
* matter which agent made it) and is never cleared — it dies with the driver.
|
|
85
|
+
*/
|
|
86
|
+
this.condensePolicies = new Map();
|
|
87
|
+
/**
|
|
88
|
+
* Monotonic model-call counter for the driver's whole lifetime — the age clock
|
|
89
|
+
* for `condenseWhen({ on: { kind: 'age' } })`. The per-`sendMessage` `iterations`
|
|
90
|
+
* loop counter resets to 0 every turn, so it can only measure age WITHIN a
|
|
91
|
+
* single turn; this never resets, so `age` counts model-calls since the result
|
|
92
|
+
* appeared across turn boundaries (each short turn still advances it ≥ 1).
|
|
93
|
+
* Bumped once per tool-loop iteration (provider call).
|
|
94
|
+
*/
|
|
95
|
+
this.modelCallSeq = 0;
|
|
96
|
+
/**
|
|
97
|
+
* Monotonic turn counter — the `turnEnd` clock. Bumped once per `sendMessage`
|
|
98
|
+
* (a user turn; NOT per handoff continuation, which is the same request), never
|
|
99
|
+
* reset. `turnEnd` collapses a payload once `turnSeq` exceeds the turn it was
|
|
100
|
+
* created in.
|
|
101
|
+
*/
|
|
102
|
+
this.turnSeq = 0;
|
|
103
|
+
/**
|
|
104
|
+
* Monotonic agent-activation counter — the `agentEnd` clock. Advances when the
|
|
105
|
+
* active flow ends: a swap to a different-named agent (`applyAgent`) OR an
|
|
106
|
+
* explicit `releaseAgent` / `completeSubAgent`. A stateful agent re-resolving
|
|
107
|
+
* the same name across turns keeps one activation. `agentEnd` fires for a
|
|
108
|
+
* payload once a LATER activation is current (`callActivation < currentActivation`)
|
|
109
|
+
* — so a re-run of a released agent gets a fresh activation and is NOT
|
|
110
|
+
* collapsed until IT ends.
|
|
111
|
+
*/
|
|
112
|
+
this.currentActivation = 0;
|
|
78
113
|
/** Stack of fold frames — grows when a fold opens, shrinks when it closes. */
|
|
79
114
|
this.foldStack = [];
|
|
80
115
|
/** Consecutive fold open/close ops without a real tool call. Reset on real tool execution. */
|
|
@@ -280,6 +315,12 @@ export class ChatDriver extends EventTarget {
|
|
|
280
315
|
*/
|
|
281
316
|
applyAgent(config) {
|
|
282
317
|
var _a, _b, _c;
|
|
318
|
+
// A real swap to a different agent begins a NEW activation — the prior agent's
|
|
319
|
+
// flow is over, so its `agentEnd`-tagged payloads become collapsible. Guarded
|
|
320
|
+
// on a name change so re-applying the same agent (e.g. a per-turn re-resolve)
|
|
321
|
+
// does not spuriously advance the clock and prematurely drop its payloads.
|
|
322
|
+
if (config.name !== this.activeAgentName)
|
|
323
|
+
this.currentActivation += 1;
|
|
283
324
|
this.systemPrompt = config.systemPrompt;
|
|
284
325
|
if (typeof config.toolDefinitions === 'function') {
|
|
285
326
|
this.toolDefinitionsFactory = config.toolDefinitions;
|
|
@@ -873,6 +914,9 @@ export class ChatDriver extends EventTarget {
|
|
|
873
914
|
return { reason: 'done' };
|
|
874
915
|
this.busy = true;
|
|
875
916
|
this.beginTurn();
|
|
917
|
+
// A new user turn — advances the `turnEnd` clock (continuations after a
|
|
918
|
+
// handoff stay on the same turn; they go through `continueFromHistory`).
|
|
919
|
+
this.turnSeq += 1;
|
|
876
920
|
this.subAgentCompletion = undefined;
|
|
877
921
|
this.subAgentFailure = undefined;
|
|
878
922
|
this.agentReleaseRequested = false;
|
|
@@ -918,11 +962,15 @@ export class ChatDriver extends EventTarget {
|
|
|
918
962
|
* Centralised here so fold shortcut dispatch and the main tool loop use the
|
|
919
963
|
* same context without duplication.
|
|
920
964
|
*
|
|
965
|
+
* @param activeToolCallId - The id of the tool call this context belongs to, so
|
|
966
|
+
* `condenseWhen` can register against the right call (it stamps the clocks
|
|
967
|
+
* straight off the driver). Absent for dispatch paths with no addressable tool
|
|
968
|
+
* call (e.g. the fold-close handler), where `condenseWhen` is a no-op.
|
|
921
969
|
* @param traceCapture - Optional per-invocation slot. When provided, the trace
|
|
922
970
|
* from any sub-agent call is written here rather than to shared instance state,
|
|
923
971
|
* so parallel tool calls each capture their own trace independently.
|
|
924
972
|
*/
|
|
925
|
-
buildHandlerContext(traceCapture) {
|
|
973
|
+
buildHandlerContext(activeToolCallId, traceCapture) {
|
|
926
974
|
return Object.assign(Object.assign({ requestInteraction: (componentName, data, options) => this.requestInteraction(componentName, data, options) }, (this.subAgentsMap.size > 0 && {
|
|
927
975
|
requestSubAgent: (name, options) => this.invokeSubAgent(name, options).then(({ outcome, trace }) => {
|
|
928
976
|
if (traceCapture)
|
|
@@ -936,6 +984,9 @@ export class ChatDriver extends EventTarget {
|
|
|
936
984
|
return;
|
|
937
985
|
}
|
|
938
986
|
this.subAgentCompletion = { result };
|
|
987
|
+
// This activation's flow has ended — advance the clock so its
|
|
988
|
+
// `agentEnd` payloads collapse and a re-run starts a fresh activation.
|
|
989
|
+
this.currentActivation += 1;
|
|
939
990
|
}, releaseAgent: () => {
|
|
940
991
|
var _a;
|
|
941
992
|
if (this.agentReleaseRequested) {
|
|
@@ -943,6 +994,42 @@ export class ChatDriver extends EventTarget {
|
|
|
943
994
|
return;
|
|
944
995
|
}
|
|
945
996
|
this.agentReleaseRequested = true;
|
|
997
|
+
// The stateful flow has wrapped up — advance the clock so its `agentEnd`
|
|
998
|
+
// payloads collapse and a re-run starts a fresh activation.
|
|
999
|
+
this.currentActivation += 1;
|
|
1000
|
+
}, condenseWhen: (policy) => {
|
|
1001
|
+
var _a, _b, _c;
|
|
1002
|
+
// No addressable tool call (e.g. fold-close handler) — nothing to attach to.
|
|
1003
|
+
if (!activeToolCallId)
|
|
1004
|
+
return;
|
|
1005
|
+
if (!(policy === null || policy === void 0 ? void 0 : policy.args) && !(policy === null || policy === void 0 ? void 0 : policy.response)) {
|
|
1006
|
+
logger.warn(`ChatDriver(${(_a = this.activeAgentName) !== null && _a !== void 0 ? _a : 'unknown'}): condenseWhen called with neither args nor response — ignoring`);
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
const triggers = Array.isArray(policy.on) ? policy.on : [policy.on];
|
|
1010
|
+
const validTrigger = (t) => (t === null || t === void 0 ? void 0 : t.kind) === 'superseded'
|
|
1011
|
+
? typeof t.by === 'string' && t.by.length > 0
|
|
1012
|
+
: (t === null || t === void 0 ? void 0 : t.kind) === 'age'
|
|
1013
|
+
? typeof t.turns === 'number' && t.turns >= 1
|
|
1014
|
+
: (t === null || t === void 0 ? void 0 : t.kind) === 'turnEnd' || (t === null || t === void 0 ? void 0 : t.kind) === 'agentEnd';
|
|
1015
|
+
if (triggers.length === 0 || !triggers.every(validTrigger)) {
|
|
1016
|
+
logger.warn(`ChatDriver(${(_b = this.activeAgentName) !== null && _b !== void 0 ? _b : 'unknown'}): condenseWhen called with an invalid trigger — ignoring`);
|
|
1017
|
+
return;
|
|
1018
|
+
}
|
|
1019
|
+
// First-wins: a handler declares its policy once per call. A second
|
|
1020
|
+
// declaration for the same tool call is a handler bug, not a refinement.
|
|
1021
|
+
if (this.condensePolicies.has(activeToolCallId)) {
|
|
1022
|
+
logger.error(`ChatDriver(${(_c = this.activeAgentName) !== null && _c !== void 0 ? _c : 'unknown'}): condenseWhen called more than once for the same tool call — keeping the first policy, ignoring this one`);
|
|
1023
|
+
return;
|
|
1024
|
+
}
|
|
1025
|
+
// Stamp the three clocks NOW (read straight off the driver — the handler
|
|
1026
|
+
// runs during the current model-call's tool batch).
|
|
1027
|
+
this.condensePolicies.set(activeToolCallId, {
|
|
1028
|
+
policy,
|
|
1029
|
+
iteration: this.modelCallSeq,
|
|
1030
|
+
turn: this.turnSeq,
|
|
1031
|
+
activation: this.currentActivation,
|
|
1032
|
+
});
|
|
946
1033
|
} });
|
|
947
1034
|
}
|
|
948
1035
|
/**
|
|
@@ -1251,7 +1338,7 @@ export class ChatDriver extends EventTarget {
|
|
|
1251
1338
|
this.toolHandlers = newHandlers;
|
|
1252
1339
|
}
|
|
1253
1340
|
/** Open a fold: push a stack frame, swap the tool set, return the response message. */
|
|
1254
|
-
openFold(foldName, fold, args) {
|
|
1341
|
+
openFold(foldName, fold, args, activeToolCallId) {
|
|
1255
1342
|
// Shortcut dispatch: model passed inner tool args directly, e.g.
|
|
1256
1343
|
// trading_tools({ search_trades: { side: "BUY" } })
|
|
1257
1344
|
for (const key of Object.keys(args)) {
|
|
@@ -1265,7 +1352,7 @@ export class ChatDriver extends EventTarget {
|
|
|
1265
1352
|
const innerArgs = typeof args[key] === 'object' && args[key] !== null
|
|
1266
1353
|
? args[key]
|
|
1267
1354
|
: {};
|
|
1268
|
-
return innerHandler(innerArgs, this.buildHandlerContext()).then((r) => typeof r === 'string' ? r : JSON.stringify(r));
|
|
1355
|
+
return innerHandler(innerArgs, this.buildHandlerContext(activeToolCallId)).then((r) => typeof r === 'string' ? r : JSON.stringify(r));
|
|
1269
1356
|
}
|
|
1270
1357
|
}
|
|
1271
1358
|
// Normal two-step open
|
|
@@ -1344,6 +1431,10 @@ export class ChatDriver extends EventTarget {
|
|
|
1344
1431
|
let firstLlmCall = !!currentInput;
|
|
1345
1432
|
while (iterations < this.maxToolIterations) {
|
|
1346
1433
|
iterations += 1;
|
|
1434
|
+
// Monotonic across the driver's life — the age clock. Unlike `iterations`,
|
|
1435
|
+
// it is NOT reset per turn and NOT decremented for folds, so `age` keeps
|
|
1436
|
+
// counting model-calls once a turn ends. (See the `modelCallSeq` field.)
|
|
1437
|
+
this.modelCallSeq += 1;
|
|
1347
1438
|
// A cancel (or dispose) that landed while the previous iteration's tool
|
|
1348
1439
|
// batch was running takes effect here — before issuing another LLM call.
|
|
1349
1440
|
// An abort during the call itself is handled by the catch below.
|
|
@@ -1412,9 +1503,19 @@ export class ChatDriver extends EventTarget {
|
|
|
1412
1503
|
const primer = [...((_b = this.primerHistory) !== null && _b !== void 0 ? _b : []), ...(transientPrimer !== null && transientPrimer !== void 0 ? transientPrimer : [])];
|
|
1413
1504
|
const baseHistory = firstLlmCall ? this.history.slice(0, -1) : this.history;
|
|
1414
1505
|
firstLlmCall = false;
|
|
1506
|
+
// Collapse stale tool payloads this agent declared via `condenseWhen`, then
|
|
1507
|
+
// pipe through any externally-set transform (e.g. multi-agent masking).
|
|
1508
|
+
// Both run on a copy — stored history is untouched.
|
|
1509
|
+
const condensedHistory = applyCondensation([...baseHistory], this.condensePolicies, {
|
|
1510
|
+
modelCall: this.modelCallSeq,
|
|
1511
|
+
turn: this.turnSeq,
|
|
1512
|
+
// A call's activation has ended once a later activation is current — a
|
|
1513
|
+
// swap or release/complete both advance the counter.
|
|
1514
|
+
activationEnded: (activation) => activation < this.currentActivation,
|
|
1515
|
+
}, (detail) => recordMetaEvent(this.sessionKey, 'context.condensed', detail));
|
|
1415
1516
|
const historyForProvider = this.providerHistoryTransform
|
|
1416
|
-
? this.providerHistoryTransform(
|
|
1417
|
-
:
|
|
1517
|
+
? this.providerHistoryTransform(condensedHistory)
|
|
1518
|
+
: condensedHistory;
|
|
1418
1519
|
const historyForCall = [...primer, ...historyForProvider];
|
|
1419
1520
|
const systemPrompt = malformedAttempts > 0
|
|
1420
1521
|
? `${baseSystemPrompt !== null && baseSystemPrompt !== void 0 ? baseSystemPrompt : ''}\n\nIMPORTANT: Use only the structured function-call API to invoke tools. Do not write Python code or use Python-style syntax to call tools.`
|
|
@@ -1625,7 +1726,7 @@ export class ChatDriver extends EventTarget {
|
|
|
1625
1726
|
});
|
|
1626
1727
|
return;
|
|
1627
1728
|
}
|
|
1628
|
-
const content = yield this.openFold(tc.name, fold, tc.args);
|
|
1729
|
+
const content = yield this.openFold(tc.name, fold, tc.args, tc.id);
|
|
1629
1730
|
executedById.set(tc.id, { toolCallId: tc.id, content });
|
|
1630
1731
|
// Fold open/close does NOT count as a real iteration — decrement to compensate
|
|
1631
1732
|
iterations -= 1;
|
|
@@ -1736,7 +1837,7 @@ export class ChatDriver extends EventTarget {
|
|
|
1736
1837
|
// Real tool execution
|
|
1737
1838
|
try {
|
|
1738
1839
|
const traceCapture = {};
|
|
1739
|
-
const result = yield handler(tc.args, this.buildHandlerContext(traceCapture));
|
|
1840
|
+
const result = yield handler(tc.args, this.buildHandlerContext(tc.id, traceCapture));
|
|
1740
1841
|
const content = typeof result === 'string' ? result : JSON.stringify(result);
|
|
1741
1842
|
executedById.set(tc.id, {
|
|
1742
1843
|
toolCallId: tc.id,
|