@genesislcap/ai-assistant 15.20.1-alpha-08bf7a668.0 → 15.20.2-FUI-0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/ai-assistant.api.json +105 -0
  2. package/dist/ai-assistant.d.ts +39 -0
  3. package/dist/chat-driver.cjs +99 -6
  4. package/dist/chat-driver.cjs.map +2 -2
  5. package/dist/chat-driver.mjs +99 -6
  6. package/dist/chat-driver.mjs.map +2 -2
  7. package/dist/custom-elements.json +165 -113
  8. package/dist/dts/components/ai-driver/ai-driver.d.ts +7 -0
  9. package/dist/dts/components/ai-driver/ai-driver.d.ts.map +1 -1
  10. package/dist/dts/components/chat-driver/chat-driver.d.ts +18 -0
  11. package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
  12. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts +14 -0
  13. package/dist/dts/components/orchestrating-driver/orchestrating-driver.d.ts.map +1 -1
  14. package/dist/dts/main/main.d.ts.map +1 -1
  15. package/dist/dts/react.d.ts +9 -9
  16. package/dist/dts/state/persistence/diagnostics-cursors.d.ts +7 -2
  17. package/dist/dts/state/persistence/diagnostics-cursors.d.ts.map +1 -1
  18. package/dist/dts/state/persistence/diagnostics.d.ts +33 -19
  19. package/dist/dts/state/persistence/diagnostics.d.ts.map +1 -1
  20. package/dist/dts/state/persistence/session-persister.d.ts +18 -0
  21. package/dist/dts/state/persistence/session-persister.d.ts.map +1 -1
  22. package/dist/dts/utils/condense-history.d.ts +35 -0
  23. package/dist/dts/utils/condense-history.d.ts.map +1 -1
  24. package/dist/esm/components/chat-driver/chat-driver.js +21 -1
  25. package/dist/esm/components/orchestrating-driver/orchestrating-driver.js +16 -0
  26. package/dist/esm/main/main.js +9 -3
  27. package/dist/esm/state/persistence/diagnostics-cursors.js +1 -1
  28. package/dist/esm/state/persistence/diagnostics.js +56 -39
  29. package/dist/esm/state/persistence/session-persister.js +38 -18
  30. package/dist/esm/utils/condense-history.js +124 -21
  31. package/dist/react.cjs +6 -6
  32. package/dist/react.mjs +5 -5
  33. package/package.json +16 -16
@@ -2822,6 +2822,39 @@
2822
2822
  "parameters": [],
2823
2823
  "name": "getExternalDiagnostics"
2824
2824
  },
2825
+ {
2826
+ "kind": "MethodSignature",
2827
+ "canonicalReference": "@genesislcap/ai-assistant!AiDriver#getHistoryForPersistence:member(1)",
2828
+ "docComment": "/**\n * The history a host should PERSIST — {@link AiDriver.getRawHistory} with tool payloads the driver has already condensed out of the model's context replaced by the stubs it sent (GENC-1566). Optional: a driver that does not implement tool-context condensation has nothing to project, and a caller falls back to {@link AiDriver.getRawHistory}.\n */\n",
2829
+ "excerptTokens": [
2830
+ {
2831
+ "kind": "Content",
2832
+ "text": "getHistoryForPersistence?(): "
2833
+ },
2834
+ {
2835
+ "kind": "Reference",
2836
+ "text": "ChatMessage",
2837
+ "canonicalReference": "@genesislcap/foundation-ai!ChatMessage:interface"
2838
+ },
2839
+ {
2840
+ "kind": "Content",
2841
+ "text": "[]"
2842
+ },
2843
+ {
2844
+ "kind": "Content",
2845
+ "text": ";"
2846
+ }
2847
+ ],
2848
+ "isOptional": true,
2849
+ "returnTypeTokenRange": {
2850
+ "startIndex": 1,
2851
+ "endIndex": 3
2852
+ },
2853
+ "releaseTag": "Beta",
2854
+ "overloadIndex": 1,
2855
+ "parameters": [],
2856
+ "name": "getHistoryForPersistence"
2857
+ },
2825
2858
  {
2826
2859
  "kind": "MethodSignature",
2827
2860
  "canonicalReference": "@genesislcap/ai-assistant!AiDriver#getInteractionContext:member(1)",
@@ -4991,6 +5024,42 @@
4991
5024
  "isAbstract": false,
4992
5025
  "name": "getHistory"
4993
5026
  },
5027
+ {
5028
+ "kind": "Method",
5029
+ "canonicalReference": "@genesislcap/ai-assistant!ChatDriver#getHistoryForPersistence:member(1)",
5030
+ "docComment": "/**\n * The transcript as it should be **stored**: every tool payload the model has already stopped seeing replaced by the same stub it was sent (GENC-1566). Live history is untouched — this returns a copy.\n *\n * Condensation deliberately spares stored history, because the live transcript and the debug export both read it. A host writing that transcript to durable storage inherits the other half of that decision: it stores payloads the driver has already retired, on every autosave, for the life of the session. Measured on one small Create session — 58,187 chars, 7.4% of a 790 KB session object, across five payloads worth 14,434 tokens of context, written 86 times.\n *\n * Only already-collapsed payloads are touched, so this can never store a stub for something the model can still see, and it has no side effects (see `condenseForPersistence`, which is internal). A host that wants the unredacted transcript still calls {@link ChatDriver.getRawHistory}, and a diagnostics stream that keeps full payloads is unaffected — which is what makes the elision recoverable.\n */\n",
5031
+ "excerptTokens": [
5032
+ {
5033
+ "kind": "Content",
5034
+ "text": "getHistoryForPersistence(): "
5035
+ },
5036
+ {
5037
+ "kind": "Reference",
5038
+ "text": "ChatMessage",
5039
+ "canonicalReference": "@genesislcap/foundation-ai!ChatMessage:interface"
5040
+ },
5041
+ {
5042
+ "kind": "Content",
5043
+ "text": "[]"
5044
+ },
5045
+ {
5046
+ "kind": "Content",
5047
+ "text": ";"
5048
+ }
5049
+ ],
5050
+ "isStatic": false,
5051
+ "returnTypeTokenRange": {
5052
+ "startIndex": 1,
5053
+ "endIndex": 3
5054
+ },
5055
+ "releaseTag": "Public",
5056
+ "isProtected": false,
5057
+ "overloadIndex": 1,
5058
+ "parameters": [],
5059
+ "isOptional": false,
5060
+ "isAbstract": false,
5061
+ "name": "getHistoryForPersistence"
5062
+ },
4994
5063
  {
4995
5064
  "kind": "Method",
4996
5065
  "canonicalReference": "@genesislcap/ai-assistant!ChatDriver#getInteractionContext:member(1)",
@@ -15544,6 +15613,42 @@
15544
15613
  "isAbstract": false,
15545
15614
  "name": "getExternalDiagnostics"
15546
15615
  },
15616
+ {
15617
+ "kind": "Method",
15618
+ "canonicalReference": "@genesislcap/ai-assistant!OrchestratingDriver#getHistoryForPersistence:member(1)",
15619
+ "docComment": "/**\n * Delegates to the inner {@link ChatDriver} — condensation policies are registered there, so it is the only object that knows which payloads the model has stopped seeing (GENC-1566).\n *\n * **This forward is the whole feature, for any multi-agent host.** `AiDriver` declares `getHistoryForPersistence` optional, and `SessionPersister` calls it through `?.`, falling back to {@link OrchestratingDriver.getRawHistory}. This class does NOT extend `ChatDriver` — it wraps one — so without an explicit forward the optional call resolves to `undefined` and every host on an orchestrating driver silently keeps persisting the full payloads. Measured exactly that way on a Create run: 10 `context.condensed` events fired, and the session still stored the two largest `read_context` results at 26,907 and 23,060 chars. The method existed, the tests passed, and the feature did nothing.\n */\n",
15620
+ "excerptTokens": [
15621
+ {
15622
+ "kind": "Content",
15623
+ "text": "getHistoryForPersistence(): "
15624
+ },
15625
+ {
15626
+ "kind": "Reference",
15627
+ "text": "ChatMessage",
15628
+ "canonicalReference": "@genesislcap/foundation-ai!ChatMessage:interface"
15629
+ },
15630
+ {
15631
+ "kind": "Content",
15632
+ "text": "[]"
15633
+ },
15634
+ {
15635
+ "kind": "Content",
15636
+ "text": ";"
15637
+ }
15638
+ ],
15639
+ "isStatic": false,
15640
+ "returnTypeTokenRange": {
15641
+ "startIndex": 1,
15642
+ "endIndex": 3
15643
+ },
15644
+ "releaseTag": "Beta",
15645
+ "isProtected": false,
15646
+ "overloadIndex": 1,
15647
+ "parameters": [],
15648
+ "isOptional": false,
15649
+ "isAbstract": false,
15650
+ "name": "getHistoryForPersistence"
15651
+ },
15547
15652
  {
15548
15653
  "kind": "Method",
15549
15654
  "canonicalReference": "@genesislcap/ai-assistant!OrchestratingDriver#getInteractionContext:member(1)",
@@ -630,6 +630,13 @@ export declare interface AiDriver extends EventTarget {
630
630
  * Return the full, unredacted conversation history.
631
631
  */
632
632
  getRawHistory?(): readonly ChatMessage[];
633
+ /**
634
+ * The history a host should PERSIST — {@link AiDriver.getRawHistory} with tool payloads the
635
+ * driver has already condensed out of the model's context replaced by the stubs it sent
636
+ * (GENC-1566). Optional: a driver that does not implement tool-context condensation has nothing
637
+ * to project, and a caller falls back to {@link AiDriver.getRawHistory}.
638
+ */
639
+ getHistoryForPersistence?(): ChatMessage[];
633
640
  /**
634
641
  * The live `AgentConfig` currently active in the driver — the instance whose
635
642
  * `onActivate` ran, so its `serialize`/`getDebugSnapshot` closures hold live
@@ -1899,6 +1906,24 @@ export declare class ChatDriver extends EventTarget implements AiDriver {
1899
1906
  getRawHistory(): readonly ChatMessage[];
1900
1907
  /** Returns the current fold stack names for debugging. */
1901
1908
  getActiveFoldNames(): string[];
1909
+ /**
1910
+ * The transcript as it should be **stored**: every tool payload the model has already stopped
1911
+ * seeing replaced by the same stub it was sent (GENC-1566). Live history is untouched — this
1912
+ * returns a copy.
1913
+ *
1914
+ * Condensation deliberately spares stored history, because the live transcript and the debug
1915
+ * export both read it. A host writing that transcript to durable storage inherits the other
1916
+ * half of that decision: it stores payloads the driver has already retired, on every autosave,
1917
+ * for the life of the session. Measured on one small Create session — 58,187 chars, 7.4% of a
1918
+ * 790 KB session object, across five payloads worth 14,434 tokens of context, written 86 times.
1919
+ *
1920
+ * Only already-collapsed payloads are touched, so this can never store a stub for something the
1921
+ * model can still see, and it has no side effects (see `condenseForPersistence`, which is
1922
+ * internal). A host that wants the unredacted transcript still calls
1923
+ * {@link ChatDriver.getRawHistory}, and a diagnostics stream that keeps full payloads is
1924
+ * unaffected — which is what makes the elision recoverable.
1925
+ */
1926
+ getHistoryForPersistence(): ChatMessage[];
1902
1927
  getSuggestions(history: ChatMessage[], prompt: string, count: number, allAgentInfo?: AllAgentSummary[]): Promise<string[]>;
1903
1928
  /**
1904
1929
  * Whether `compact()` would do anything right now — a summarizable run of older
@@ -4922,6 +4947,20 @@ export declare class OrchestratingDriver extends EventTarget implements AiDriver
4922
4947
  setFlowOwner(name: string | null): void;
4923
4948
  loadHistory(messages: ChatMessage[]): void;
4924
4949
  getRawHistory(): readonly ChatMessage[];
4950
+ /**
4951
+ * Delegates to the inner {@link ChatDriver} — condensation policies are registered there, so it
4952
+ * is the only object that knows which payloads the model has stopped seeing (GENC-1566).
4953
+ *
4954
+ * **This forward is the whole feature, for any multi-agent host.** `AiDriver` declares
4955
+ * `getHistoryForPersistence` optional, and `SessionPersister` calls it through `?.`, falling back
4956
+ * to {@link OrchestratingDriver.getRawHistory}. This class does NOT extend `ChatDriver` — it
4957
+ * wraps one — so without an explicit forward the optional call resolves to `undefined` and every
4958
+ * host on an orchestrating driver silently keeps persisting the full payloads. Measured exactly
4959
+ * that way on a Create run: 10 `context.condensed` events fired, and the session still stored
4960
+ * the two largest `read_context` results at 26,907 and 23,060 chars. The method existed, the
4961
+ * tests passed, and the feature did nothing.
4962
+ */
4963
+ getHistoryForPersistence(): ChatMessage[];
4925
4964
  /** {@inheritDoc AiDriver.setContextGuard} */
4926
4965
  setContextGuard(policy?: ContextGuardPolicy): void;
4927
4966
  /** {@inheritDoc AiDriver.compact} */
@@ -3936,6 +3936,14 @@ function condenseStub(target, tool, trigger, origLen, restorable, imageCount2 =
3936
3936
  const images = imageCount2 > 0 ? ` + ${imageCount2} image${imageCount2 === 1 ? "" : "s"}` : "";
3937
3937
  return `[${tool}${key} \u2014 ${what} elided, ~${origLen} chars${images} (${triggerReason(trigger)})${restore}]`;
3938
3938
  }
3939
+ function renderCondensedArgs(policy, tool, fired, origLen) {
3940
+ return {
3941
+ [CONDENSED_ARGS_KEY]: policy === "drop" || policy === "pointer" ? condenseStub("args", tool, fired, origLen, policy === "pointer") : policy.replaceWith
3942
+ };
3943
+ }
3944
+ function renderCondensedResult(policy, tool, fired, textLen, imageCount2) {
3945
+ return policy === "drop" || policy === "pointer" ? condenseStub("response", tool, fired, textLen, policy === "pointer", imageCount2) : policy.replaceWith;
3946
+ }
3939
3947
  function triggerLabel(trigger) {
3940
3948
  switch (trigger.kind) {
3941
3949
  case "age":
@@ -4010,10 +4018,7 @@ function applyCondensation(history, policies, ctx, onCondensed) {
4010
4018
  const origLen = JSON.stringify(tc.args ?? {}).length;
4011
4019
  if (origLen < CONDENSE_MIN_CHARS) return tc;
4012
4020
  changed = true;
4013
- const result = entry.policy.args;
4014
- const args = {
4015
- [CONDENSED_ARGS_KEY]: result === "drop" || result === "pointer" ? condenseStub("args", tc.name, fired, origLen, result === "pointer") : result.replaceWith
4016
- };
4021
+ const args = renderCondensedArgs(entry.policy.args, tc.name, fired, origLen);
4017
4022
  if (!entry.reportedArgs) {
4018
4023
  entry.reportedArgs = true;
4019
4024
  const stubLen = JSON.stringify(args).length;
@@ -4039,8 +4044,13 @@ function applyCondensation(history, policies, ctx, onCondensed) {
4039
4044
  const fired = entry?.policy.response ? firstFired(msg.toolResult.toolCallId, entry) : void 0;
4040
4045
  if (entry && fired && origLen >= CONDENSE_MIN_CHARS) {
4041
4046
  const tool = nameById.get(msg.toolResult.toolCallId) ?? msg.toolResult.toolCallId;
4042
- const result = entry.policy.response;
4043
- const content = result === "drop" || result === "pointer" ? condenseStub("response", tool, fired, textLen, result === "pointer", images.length) : result.replaceWith;
4047
+ const content = renderCondensedResult(
4048
+ entry.policy.response,
4049
+ tool,
4050
+ fired,
4051
+ textLen,
4052
+ images.length
4053
+ );
4044
4054
  if (!entry.reportedResponse) {
4045
4055
  entry.reportedResponse = true;
4046
4056
  onCondensed({
@@ -4060,6 +4070,53 @@ function applyCondensation(history, policies, ctx, onCondensed) {
4060
4070
  return msg;
4061
4071
  });
4062
4072
  }
4073
+ function condenseForPersistence(history, policies) {
4074
+ if (policies.size === 0) return history;
4075
+ const nameById = /* @__PURE__ */ new Map();
4076
+ for (const msg of history) {
4077
+ for (const tc of msg.toolCalls ?? []) nameById.set(tc.id, tc.name);
4078
+ }
4079
+ let changed = false;
4080
+ const projected = history.map((msg) => {
4081
+ if (msg.toolCalls?.length) {
4082
+ let callsChanged = false;
4083
+ const toolCalls = msg.toolCalls.map((tc) => {
4084
+ const entry = policies.get(tc.id);
4085
+ if (!entry?.reportedArgs || !entry.firedTrigger || !entry.policy.args) return tc;
4086
+ callsChanged = true;
4087
+ const origLen = JSON.stringify(tc.args ?? {}).length;
4088
+ return {
4089
+ ...tc,
4090
+ args: renderCondensedArgs(entry.policy.args, tc.name, entry.firedTrigger, origLen)
4091
+ };
4092
+ });
4093
+ if (callsChanged) {
4094
+ changed = true;
4095
+ return { ...msg, toolCalls };
4096
+ }
4097
+ return msg;
4098
+ }
4099
+ if (msg.toolResult) {
4100
+ const entry = policies.get(msg.toolResult.toolCallId);
4101
+ if (entry?.reportedResponse && entry.firedTrigger && entry.policy.response) {
4102
+ changed = true;
4103
+ const tool = nameById.get(msg.toolResult.toolCallId) ?? msg.toolResult.toolCallId;
4104
+ const images = msg.toolResult.attachments ?? [];
4105
+ const content = renderCondensedResult(
4106
+ entry.policy.response,
4107
+ tool,
4108
+ entry.firedTrigger,
4109
+ msg.toolResult.content?.length ?? 0,
4110
+ images.length
4111
+ );
4112
+ const { attachments: _elided, ...restOfResult } = msg.toolResult;
4113
+ return { ...msg, toolResult: { ...restOfResult, content } };
4114
+ }
4115
+ }
4116
+ return msg;
4117
+ });
4118
+ return changed ? projected : history;
4119
+ }
4063
4120
 
4064
4121
  // src/utils/history-transform.ts
4065
4122
  function maskToolPayload(msg) {
@@ -5101,6 +5158,26 @@ var ChatDriver = class _ChatDriver extends EventTarget {
5101
5158
  getActiveFoldNames() {
5102
5159
  return this.foldStack.map((f) => f.foldName);
5103
5160
  }
5161
+ /**
5162
+ * The transcript as it should be **stored**: every tool payload the model has already stopped
5163
+ * seeing replaced by the same stub it was sent (GENC-1566). Live history is untouched — this
5164
+ * returns a copy.
5165
+ *
5166
+ * Condensation deliberately spares stored history, because the live transcript and the debug
5167
+ * export both read it. A host writing that transcript to durable storage inherits the other
5168
+ * half of that decision: it stores payloads the driver has already retired, on every autosave,
5169
+ * for the life of the session. Measured on one small Create session — 58,187 chars, 7.4% of a
5170
+ * 790 KB session object, across five payloads worth 14,434 tokens of context, written 86 times.
5171
+ *
5172
+ * Only already-collapsed payloads are touched, so this can never store a stub for something the
5173
+ * model can still see, and it has no side effects (see `condenseForPersistence`, which is
5174
+ * internal). A host that wants the unredacted transcript still calls
5175
+ * {@link ChatDriver.getRawHistory}, and a diagnostics stream that keeps full payloads is
5176
+ * unaffected — which is what makes the elision recoverable.
5177
+ */
5178
+ getHistoryForPersistence() {
5179
+ return condenseForPersistence([...this.history], this.condensePolicies);
5180
+ }
5104
5181
  async getSuggestions(history, prompt2, count, allAgentInfo) {
5105
5182
  const defaultProvider = this.providerRegistry.default();
5106
5183
  if (!defaultProvider.prompt) {
@@ -6924,6 +7001,22 @@ var OrchestratingDriver = class extends EventTarget {
6924
7001
  getRawHistory() {
6925
7002
  return this.chatDriver.getHistory();
6926
7003
  }
7004
+ /**
7005
+ * Delegates to the inner {@link ChatDriver} — condensation policies are registered there, so it
7006
+ * is the only object that knows which payloads the model has stopped seeing (GENC-1566).
7007
+ *
7008
+ * **This forward is the whole feature, for any multi-agent host.** `AiDriver` declares
7009
+ * `getHistoryForPersistence` optional, and `SessionPersister` calls it through `?.`, falling back
7010
+ * to {@link OrchestratingDriver.getRawHistory}. This class does NOT extend `ChatDriver` — it
7011
+ * wraps one — so without an explicit forward the optional call resolves to `undefined` and every
7012
+ * host on an orchestrating driver silently keeps persisting the full payloads. Measured exactly
7013
+ * that way on a Create run: 10 `context.condensed` events fired, and the session still stored
7014
+ * the two largest `read_context` results at 26,907 and 23,060 chars. The method existed, the
7015
+ * tests passed, and the feature did nothing.
7016
+ */
7017
+ getHistoryForPersistence() {
7018
+ return this.chatDriver.getHistoryForPersistence();
7019
+ }
6927
7020
  /** {@inheritDoc AiDriver.setContextGuard} */
6928
7021
  setContextGuard(policy) {
6929
7022
  this.chatDriver.setContextGuard(policy);