@animalabs/agent-framework 0.24.1 → 0.26.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 (45) hide show
  1. package/dist/src/agent.d.ts.map +1 -1
  2. package/dist/src/agent.js +21 -8
  3. package/dist/src/agent.js.map +1 -1
  4. package/dist/src/framework.d.ts +18 -1
  5. package/dist/src/framework.d.ts.map +1 -1
  6. package/dist/src/framework.js +87 -37
  7. package/dist/src/framework.js.map +1 -1
  8. package/dist/src/mcpl/references.d.ts +4 -1
  9. package/dist/src/mcpl/references.d.ts.map +1 -1
  10. package/dist/src/mcpl/references.js +5 -2
  11. package/dist/src/mcpl/references.js.map +1 -1
  12. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  13. package/dist/src/modules/workspace/index.js +74 -20
  14. package/dist/src/modules/workspace/index.js.map +1 -1
  15. package/dist/src/modules/workspace/types.d.ts +6 -2
  16. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  17. package/dist/src/modules/workspace/types.js.map +1 -1
  18. package/dist/src/text-as-stored.d.ts +31 -0
  19. package/dist/src/text-as-stored.d.ts.map +1 -0
  20. package/dist/src/text-as-stored.js +70 -0
  21. package/dist/src/text-as-stored.js.map +1 -0
  22. package/dist/src/tool-image-ledger.d.ts +26 -3
  23. package/dist/src/tool-image-ledger.d.ts.map +1 -1
  24. package/dist/src/tool-image-ledger.js +31 -4
  25. package/dist/src/tool-image-ledger.js.map +1 -1
  26. package/dist/src/tool-presentation.d.ts.map +1 -1
  27. package/dist/src/tool-presentation.js +9 -1
  28. package/dist/src/tool-presentation.js.map +1 -1
  29. package/dist/src/tool-result-history.d.ts +15 -5
  30. package/dist/src/tool-result-history.d.ts.map +1 -1
  31. package/dist/src/tool-result-history.js +33 -9
  32. package/dist/src/tool-result-history.js.map +1 -1
  33. package/dist/src/types/events.d.ts +8 -2
  34. package/dist/src/types/events.d.ts.map +1 -1
  35. package/package.json +3 -3
  36. package/src/agent.ts +21 -8
  37. package/src/framework.ts +92 -36
  38. package/src/mcpl/references.ts +5 -2
  39. package/src/modules/workspace/index.ts +74 -20
  40. package/src/modules/workspace/types.ts +6 -2
  41. package/src/text-as-stored.ts +73 -0
  42. package/src/tool-image-ledger.ts +31 -4
  43. package/src/tool-presentation.ts +8 -1
  44. package/src/tool-result-history.ts +33 -8
  45. package/src/types/events.ts +8 -2
@@ -9,12 +9,14 @@
9
9
  * `maxChars` slice and re-introduces, one turn deferred, exactly the silent
10
10
  * hallucination this feature exists to kill.
11
11
  *
12
- * For MCP-shaped content arrays, this helper keeps text blocks verbatim and
12
+ * For MCP-shaped content arrays, this helper keeps text blocks verbatim,
13
+ * apart from a lone UTF-16 surrogate, which becomes U+FFFD (#695), and
13
14
  * replaces image blocks with a short `[image: mimeType, ~NKB]` placeholder.
14
- * For anything else it falls back to JSON, written by RFC-005's rules at
15
- * every depth (historyJson): a reference is shown as its stub wherever it
16
- * sits in the data, so its uri never reaches history, and inline data that
17
- * claims a uri or a disposition is withheld.
15
+ * A string is already text and is kept as it is. For anything else it falls
16
+ * back to JSON, written by RFC-005's rules at every depth (historyJson): a
17
+ * reference is shown as its stub wherever it sits in the data, so its uri
18
+ * never reaches history, and inline data that claims a uri or a disposition
19
+ * is withheld.
18
20
  */
19
21
  import { INLINE_WITHHELD_TEXT, isInlineContradiction, referenceStubOrNull } from './mcpl/references.js';
20
22
  import { NON_STRING_TEXT_PLACEHOLDER } from './mcpl/visible-content.js';
@@ -39,9 +41,19 @@ import { formatToolImagePlaceholder, toolResultCutAt } from './tool-image-ledger
39
41
  export const DEFAULT_TOOL_RESULT_INLINE_MAX_CHARS = 24000;
40
42
  export function toolResultDataToHistoryString(data, maxChars, options) {
41
43
  const fromArray = tryHistoryStringFromContentArray(data, options);
44
+ // A string is the text the tool means to say, kept as it is: JSON would
45
+ // quote it and escape every newline, so a multi-line result would reach
46
+ // the model, a script and its spill file as one escaped line. Kept well
47
+ // formed: a lone UTF-16 surrogate, which JSON escaped, isn't text, a
48
+ // provider can refuse a request that carries one, and UTF-8 can't store
49
+ // it in a spill file, so it reads as U+FFFD.
42
50
  // JSON leaves out undefined, a function and a symbol: a result with no data
43
51
  // is stored as no text, as an empty content array is.
44
- const str = fromArray ?? historyJson(data) ?? '';
52
+ // RFC-005 shows only objects otherwise (shownInHistory), so a string has
53
+ // nothing for historyJson to stub or withhold.
54
+ const str = fromArray
55
+ ?? (typeof data === 'string' ? data.toWellFormed() : historyJson(data))
56
+ ?? '';
45
57
  return maxChars ? truncateForHistory(str, maxChars) : str;
46
58
  }
47
59
  /**
@@ -52,13 +64,23 @@ export function toolResultDataToHistoryString(data, maxChars, options) {
52
64
  *
53
65
  * Each field is read once: the direct Agent API passes its caller's own
54
66
  * result here, unchecked, and a getter needn't answer the same way twice.
67
+ *
68
+ * Each text a tool result's copies carry is made well formed where it's
69
+ * taken from the result: a lone UTF-16 surrogate becomes U+FFFD, as the
70
+ * context store makes it when it writes, so the copy sent to membrane and the
71
+ * copy stored carry the same text (#695). Other data goes through JSON,
72
+ * which escapes a lone half. toWellFormed() keeps the length,
73
+ * so the cut, the spans and the slots are computed from the well-formed text
74
+ * as before; a cut at a lone high half no longer steps back over it.
55
75
  */
56
76
  export function nonErrorResultText(result, maxChars, options) {
57
77
  const data = result.data;
58
78
  if (data === undefined || data === null) {
59
79
  const error = result.error;
60
- if (typeof error === 'string' && error)
61
- return maxChars ? truncateForHistory(error, maxChars) : error;
80
+ if (typeof error === 'string' && error) {
81
+ const text = error.toWellFormed();
82
+ return maxChars ? truncateForHistory(text, maxChars) : text;
83
+ }
62
84
  }
63
85
  return toolResultDataToHistoryString(data, maxChars, options);
64
86
  }
@@ -92,7 +114,9 @@ function tryHistoryStringFromContentArray(data, options) {
92
114
  if (b.type === 'text') {
93
115
  // A text that isn't a string shows as the converters' placeholder,
94
116
  // rather than sending the whole array to the JSON fallback.
95
- parts.push({ kind: 'text', text: typeof b.text === 'string' ? b.text : NON_STRING_TEXT_PLACEHOLDER });
117
+ // Read once: a direct Agent API result is unchecked.
118
+ const text = b.text;
119
+ parts.push({ kind: 'text', text: typeof text === 'string' ? text.toWellFormed() : NON_STRING_TEXT_PLACEHOLDER });
96
120
  }
97
121
  else if (isInlineContradiction(b)) {
98
122
  // RFC-005 vector 2: checked before the data branch so inline data
@@ -1 +1 @@
1
- {"version":3,"file":"tool-result-history.js","sourceRoot":"","sources":["../../src/tool-result-history.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-result-history.js","sourceRoot":"","sources":["../../src/tool-result-history.ts"],"names":[],"mappings":"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"}
@@ -158,7 +158,13 @@ export interface ModuleEvent {
158
158
  export interface ToolResult {
159
159
  /** Whether the tool succeeded */
160
160
  success: boolean;
161
- /** Result data (if success) */
161
+ /**
162
+ * Result data (if success). The model reads a string as that text, an MCP
163
+ * content array whose every block the framework knows as those blocks, and
164
+ * anything else as JSON, where RFC-005 shows a reference as its stub and
165
+ * withholds inline data that claims a uri or a disposition. With no data,
166
+ * it reads the result's error text, if any.
167
+ */
162
168
  data?: unknown;
163
169
  /** Error message (if failure) */
164
170
  error?: string;
@@ -241,7 +247,7 @@ export interface ToolCall {
241
247
  /**
242
248
  * How long this call's result may be and still reach its caller whole,
243
249
  * measured as the framework stores it: an error's text, or a success's data
244
- * as JSON (a content array as its text). For a model's call it is the
250
+ * as JSON (a string or a content array as its text). For a model's call it is the
245
251
  * agent's inline cap, past which the framework spills the result to a
246
252
  * workspace file and sends a preview. A result that long is stored whole
247
253
  * unless its round's results together pass the readers' per-message bound,
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/types/events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/types/events.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@animalabs/agent-framework",
3
- "version": "0.24.1",
3
+ "version": "0.26.0",
4
4
  "description": "Multi-agent framework with pluggable modules, persistent state, and concurrent tool execution",
5
5
  "repository": {
6
6
  "type": "git",
@@ -49,8 +49,8 @@
49
49
  "license": "MIT",
50
50
  "dependencies": {
51
51
  "@animalabs/chronicle": "^0.4.0",
52
- "@animalabs/context-manager": "^0.18.0",
53
- "@animalabs/membrane": "^0.6.0",
52
+ "@animalabs/context-manager": "^0.20.0",
53
+ "@animalabs/membrane": "^0.7.1",
54
54
  "@modelcontextprotocol/client": "^2.3.1",
55
55
  "chokidar": "^4.0.3",
56
56
  "discord.js": "^14.25.1",
package/src/agent.ts CHANGED
@@ -4,6 +4,7 @@ import { createHash } from 'node:crypto';
4
4
  import type { CacheWireReceipt, KvUnifiedRequestHooks } from './kv-unified-wire.js';
5
5
  import { ToolResultGuard } from './tool-result-guard.js';
6
6
  import { withoutTokenEstimates } from './thinking-token-stamp.js';
7
+ import { injectionsAsStored } from './text-as-stored.js';
7
8
  import { assertBooleanSetting, holdsSettings } from './config-checks.js';
8
9
  import {
9
10
  CONTINUE_ROW,
@@ -1157,6 +1158,8 @@ export class Agent {
1157
1158
  if (this._state.status === 'inferring') {
1158
1159
  throw new Error(`Agent ${this.name} is already inferring`);
1159
1160
  }
1161
+ // Unstored, so they leave for the request here (text-as-stored.ts).
1162
+ injections = injectionsAsStored(injections);
1160
1163
 
1161
1164
  if (this._state.status === 'waiting_for_tools') {
1162
1165
  throw new Error(`Agent ${this.name} is waiting for tool results`);
@@ -1332,6 +1335,9 @@ export class Agent {
1332
1335
  compressionTools: ToolDefinition[] = availableTools,
1333
1336
  options: ActivationRequestOptions = {},
1334
1337
  ): Promise<{ request: NormalizedRequest; continuePrompt?: RequestOnlyPrompt }> {
1338
+ // Unstored, so they leave for the request here (text-as-stored.ts), the
1339
+ // layout hash below included.
1340
+ injections = injectionsAsStored(injections);
1335
1341
  // Compression may revisit hidden tools in recorded history. Keep its full
1336
1342
  // definition set separate from the resident's advertised tools: the
1337
1343
  // autobiographical strategy must declare the same tools on its
@@ -1921,14 +1927,21 @@ export class Agent {
1921
1927
  // via buildStoredToolResultContent, with workspace spill). No workspace
1922
1928
  // is reachable from here, so the house default cap applies as plain
1923
1929
  // truncation — bounded beats unbounded, for errors too.
1924
- const content = results.map((r) => ({
1925
- type: 'tool_result' as const,
1926
- toolUseId: r.id,
1927
- content: r.result.isError
1928
- ? truncateForHistory(r.result.error ?? 'Unknown error', DEFAULT_TOOL_RESULT_INLINE_MAX_CHARS)
1929
- : nonErrorResultText(r.result, DEFAULT_TOOL_RESULT_INLINE_MAX_CHARS),
1930
- isError: r.result.isError,
1931
- }));
1930
+ const content = results.map((r) => {
1931
+ // This API's results are unchecked (nonErrorResultText), so each field
1932
+ // is read once, and only an error that is a string is made well formed;
1933
+ // any other error value is passed on as it was before.
1934
+ const isError = r.result.isError;
1935
+ const error: unknown = isError ? r.result.error ?? 'Unknown error' : undefined;
1936
+ return {
1937
+ type: 'tool_result' as const,
1938
+ toolUseId: r.id,
1939
+ content: isError
1940
+ ? truncateForHistory(typeof error === 'string' ? error.toWellFormed() : error as string, DEFAULT_TOOL_RESULT_INLINE_MAX_CHARS)
1941
+ : nonErrorResultText(r.result, DEFAULT_TOOL_RESULT_INLINE_MAX_CHARS),
1942
+ isError,
1943
+ };
1944
+ });
1932
1945
 
1933
1946
  return [{
1934
1947
  participant: 'user',
package/src/framework.ts CHANGED
@@ -157,6 +157,7 @@ import { bounded, renderList, renderReturn, VALUE_CHARS } from './code-execution
157
157
  import { splitProseRuns, withoutRoundsProse } from './prose-segments.js';
158
158
  import { cumulativeDelta } from './usage-accounting.js';
159
159
  import { stampThinkingTokenEstimates } from './thinking-token-stamp.js';
160
+ import { contentAsStored, nameAsStored } from './text-as-stored.js';
160
161
 
161
162
  /** An MCPL tool call refused because its server isn't in the registry: one
162
163
  * closed for good, one removed, or one whose connect failed without
@@ -929,7 +930,8 @@ function describeDeferredWrite(msg: { id: string; participant: string; content:
929
930
  function isInjectableMidTurn(msg: { participant: string; content: ContentBlock[] }, agentName: string): boolean {
930
931
  // Exact, as membrane's role test is: only a participant equal to the
931
932
  // request's assistantParticipant (Agent's name) renders as the assistant.
932
- return msg.participant !== agentName
933
+ // It's the name as sent, which the boundary takes as the store keeps it.
934
+ return nameAsStored(msg.participant) !== agentName
933
935
  && !msg.content.some((b) => b.type === 'tool_use' || b.type === 'tool_result');
934
936
  }
935
937
 
@@ -1252,6 +1254,12 @@ function isTurnContinuation(reason: string): boolean {
1252
1254
  return reason === 'context_budget_restart' || reason === 'tool_results_ready'
1253
1255
  || reason === 'tool_result_guard_retry';
1254
1256
  }
1257
+
1258
+ /** Wake sources the framework generates for itself (bounce wakes,
1259
+ * continuations, retries, unsticks, admission requeues). A wake from any
1260
+ * other source — a channel message, a heartbeat or other server event, a
1261
+ * gate flush, a timer, an operator nudge — is a cause of its own. */
1262
+ const FRAMEWORK_WAKE_SOURCES = new Set(['framework', 'scheduler']);
1255
1263
  const CONVERSATION_ROUTER_STATE_ID = 'framework/conversation-router';
1256
1264
  const INFERENCE_LOG_ID = 'framework/inference-log';
1257
1265
  const PROCESS_LOG_ID = 'framework/process-log';
@@ -12145,11 +12153,14 @@ export class AgentFramework {
12145
12153
  // 0.5.x, and from 0.6.0 declares it can't carry them, so none are
12146
12154
  // collected for it. Each goes as its participant and content
12147
12155
  // alone: a stored row's metadata is the host's record, not input
12148
- // for membrane.
12156
+ // for membrane. Each goes with its name and text as the store
12157
+ // keeps them, whether it's a heard message, rendered or not, or a
12158
+ // notice the boundary made: this is where they leave for the
12159
+ // request.
12149
12160
  currentState.stream.provideToolResults(
12150
12161
  agent.toolResultGuard.submissionResults(membraneResults),
12151
12162
  midTurnInjections.length > 0
12152
- ? { injectedMessages: midTurnInjections.map(({ participant, content }) => ({ participant, content })) }
12163
+ ? { injectedMessages: midTurnInjections.map(({ participant, content }) => ({ participant: nameAsStored(participant), content: contentAsStored(content) })) }
12153
12164
  : undefined,
12154
12165
  );
12155
12166
  // RFC-006 §3.3: consumption is determined at assembly, and this
@@ -14458,6 +14469,16 @@ export class AgentFramework {
14458
14469
  // requests[0] in that mixed batch bypassed the turn lock because a
14459
14470
  // restart existed, then treated the continuation as a fresh turn.
14460
14471
  const trigger = budgetRestart ?? requests[0];
14472
+ // The bounce-wake cap (bounceProse) stops a bounce → wake → bounce loop
14473
+ // that nothing else feeds. A turn with a cause of its own is not that
14474
+ // loop, so the count starts again. Otherwise only a delivered prose
14475
+ // envelope reset it, and a resident that recovers from bounces with a
14476
+ // send tool kept the count for good: every later bounce, a reply to a
14477
+ // fresh message included, appended its notice without a wake.
14478
+ // (Optional chaining: prototype-built harnesses leave the map unset.)
14479
+ if (requests.some((r) => !FRAMEWORK_WAKE_SOURCES.has(r.source))) {
14480
+ this.proseBounceStreaks?.delete(agentName);
14481
+ }
14461
14482
  // Route this turn's auto-published speech to the channel that triggered
14462
14483
  // it (item-3 redux). A batched wake may carry several triggering channels
14463
14484
  // (messages arrived in >1 channel while the agent was busy/idle):
@@ -16634,7 +16655,9 @@ export class AgentFramework {
16634
16655
  }
16635
16656
  }
16636
16657
 
16637
- /** Cap on consecutive bounce-triggered wakes (notices still append after). */
16658
+ /** Cap on consecutive bounce-triggered wakes (notices still append after).
16659
+ * The count resets on a delivered prose envelope, and when a turn starts
16660
+ * with a cause of its own (processInferenceRequests). */
16638
16661
  private static readonly PROSE_BOUNCE_WAKE_CAP = 2;
16639
16662
 
16640
16663
  /**
@@ -20593,7 +20616,7 @@ export class AgentFramework {
20593
20616
  for (const tc of toolResults) {
20594
20617
  const { text, shown, stored } = alone.get(tc.id)!;
20595
20618
  spilled.set(tc.id, byShare
20596
- ? await this.spillOrTruncate(text, share!.cap, `${dateLabel}-${tc.id}`, shown, share!.bound, stored.written)
20619
+ ? await this.spillOrTruncate(text, share!.cap, `${dateLabel}-${tc.id}`, shown, share!.bound, stored.written, { readCap: maxChars! })
20597
20620
  : stored);
20598
20621
  }
20599
20622
  const blocks: ContentBlock[] = toolResults.map(tc => ({
@@ -20631,7 +20654,7 @@ export class AgentFramework {
20631
20654
  tc: CompletedToolCall,
20632
20655
  maxChars: number | undefined,
20633
20656
  ): { text: string; shown: ShownRanges | null } {
20634
- if (tc.result.isError) return { text: tc.result.error ?? 'Unknown error', shown: null };
20657
+ if (tc.result.isError) return { text: (tc.result.error ?? 'Unknown error').toWellFormed(), shown: null };
20635
20658
  const ledger = this.toolImageLedgerFor(agentName);
20636
20659
  let blocks = null as HistoryBlockSpan[] | null;
20637
20660
  const text = nonErrorResultText(tc.result, undefined, {
@@ -20809,6 +20832,11 @@ export class AgentFramework {
20809
20832
  /** The spill file an earlier cut of this text wrote: reused, not written
20810
20833
  * again. Undefined when none was cut. */
20811
20834
  written?: SpillWrite,
20835
+ /** Set where `cap` and `bound` are this text's share of one turn's
20836
+ * bound (buildStoredToolResultContent): `readCap` is the inline cap,
20837
+ * which a later read of the file comes back under alone in its own turn
20838
+ * and its paging advice is sized to. */
20839
+ share?: { readCap: number },
20812
20840
  ): Promise<{ text: string; filePath: string | null; written?: SpillWrite }> {
20813
20841
  if (!cap || content.length <= cap) return { text: content, filePath: null };
20814
20842
  // The stored text is the only place save_recent_image discovers tool
@@ -20818,45 +20846,67 @@ export class AgentFramework {
20818
20846
  // newest slots past the cut that the live copy showed are re-appended
20819
20847
  // after the notice. Otherwise the live copy is this text, and nothing
20820
20848
  // past the cut is kept (#403). The stored copy, notice and kept slots
20821
- // included, fits `bound`, the most a reader's strategy keeps of it, so
20822
- // no reader's cut takes the notice (cutStoredToolResultToFit), and the
20823
- // spill notices name the head they kept.
20824
- const cut = cutStoredToolResultToFit(content, cap, shown, bound);
20849
+ // included, fits `bound`, the most a reader's strategy keeps of it,
20850
+ // where `bound` leaves the notice its room, so no reader's cut takes the
20851
+ // notice (cutStoredToolResultToFit), and the spill notices name the head
20852
+ // they kept. Under a share too small for that, a cut keeps no head and
20853
+ // stores its notice alone, and a text no longer than that notice is
20854
+ // stored whole, with no file written: each result at its least.
20855
+ const readCap = share?.readCap ?? cap;
20856
+ const cut = cutStoredToolResultToFit(content, cap, shown, bound,
20857
+ share ? this.spillNoticeLength(label, content, shown, bound, readCap) : undefined);
20858
+ if (cut.head === content) return { text: content, filePath: null };
20825
20859
  const { head } = cut;
20826
20860
  const kept = formatKeptImageSlots(cut);
20827
20861
 
20828
20862
  if (written === undefined) written = await this.writeToolResultFile(label, content);
20863
+ const notice = this.spillNotice(head.length, content, shown, bound, readCap, written);
20864
+ // The notice was measured as a written file's reads. A write that failed
20865
+ // keeps nothing, and its notice, naming the failure, can be longer: under
20866
+ // a share, a cut that keeps no head and would store no less than the
20867
+ // text is stored as the text itself, where the text holds no image slot.
20868
+ // One that does is stored as it was measured, cut, since save_recent_image
20869
+ // counted it so before the write.
20870
+ if (share && head.length === 0 && notice.length >= content.length && parseImagePlaceholders(content).length === 0) {
20871
+ return { text: content, filePath: null, written };
20872
+ }
20873
+ return { text: head + notice + kept, filePath: written && written.error === undefined ? written.path : null, written };
20874
+ }
20875
+
20876
+ /**
20877
+ * The notice a cut copy carries after its head (spillOrTruncate): the file
20878
+ * holding the whole result and how to read it back, or why there is none.
20879
+ */
20880
+ private spillNotice(headLength: number, content: string, shown: ShownRanges | null, bound: number | undefined,
20881
+ readCap: number, written: SpillWrite): string {
20829
20882
  if (written && written.error === undefined) {
20830
- const path = written.path;
20831
- return {
20832
- text: head
20833
- + `\n\n[truncated — showing ${head.length} of ${content.length} chars; full content: workspace file ${path}`
20834
- + `. ${this.spillPageAdvice(path, cap, bound === undefined || cutStoredToolResultToFit(content, bound, shown, bound).head.length > head.length)}]`
20835
- + kept,
20836
- filePath: path,
20837
- written,
20838
- };
20883
+ const canRaise = bound === undefined || cutStoredToolResultToFit(content, bound, shown, bound).head.length > headLength;
20884
+ return `\n\n[truncated — showing ${headLength} of ${content.length} chars; full content: workspace file ${written.path}`
20885
+ + `. ${this.spillPageAdvice(written.path, readCap, canRaise)}]`;
20839
20886
  }
20840
20887
  if (written) {
20841
20888
  // A workspace was there and the write FAILED — say that, loudly and
20842
20889
  // distinctly. Telling the agent "no writable workspace" would teach
20843
20890
  // them their residence lacks a capability it actually has.
20844
- return {
20845
- text: head
20846
- + `\n\n[truncated — showing ${head.length} of ${content.length} chars; spill to workspace file ${written.path} FAILED`
20847
- + ` (${written.error}); content over the cap was not retained]`
20848
- + kept,
20849
- filePath: null,
20850
- written,
20851
- };
20891
+ return `\n\n[truncated — showing ${headLength} of ${content.length} chars; spill to workspace file ${written.path} FAILED`
20892
+ + ` (${written.error}); content over the cap was not retained]`;
20852
20893
  }
20853
- return {
20854
- text: head
20855
- + '\n\n[truncated — original was ' + content.length + ' chars; no writable workspace mount without an include, full content not retained]'
20856
- + kept,
20857
- filePath: null,
20858
- written,
20859
- };
20894
+ return '\n\n[truncated — original was ' + content.length + ' chars; no writable workspace mount without an include, full content not retained]';
20895
+ }
20896
+
20897
+ /**
20898
+ * The length of the notice a cut of `content` that keeps no head would
20899
+ * carry, before any file is written, as it reads once its file is
20900
+ * (toolResultFilePlace, where any earlier cut of the text wrote it too), so
20901
+ * the cut and save_recent_image's count of the result before it measure
20902
+ * alike. For keeping whole, under a share, a text no longer than its notice
20903
+ * (cutStoredToolResultToFit). A write that fails carries a notice naming
20904
+ * the failure instead (spillOrTruncate).
20905
+ */
20906
+ private spillNoticeLength(label: string, content: string, shown: ShownRanges | null, bound: number | undefined,
20907
+ readCap: number): number {
20908
+ const place = this.toolResultFilePlace(label);
20909
+ return this.spillNotice(0, content, shown, bound, readCap, place ? { path: place.path } : null).length;
20860
20910
  }
20861
20911
 
20862
20912
  /**
@@ -21185,7 +21235,8 @@ export class AgentFramework {
21185
21235
  if (b.type === 'text') {
21186
21236
  // A text that isn't a string shows as the converters' placeholder,
21187
21237
  // rather than sending the whole array to the JSON fallback.
21188
- let text = typeof b.text === 'string' ? b.text : NON_STRING_TEXT_PLACEHOLDER;
21238
+ // Well formed, as the stored copy's text is (nonErrorResultText).
21239
+ let text = typeof b.text === 'string' ? b.text.toWellFormed() : NON_STRING_TEXT_PLACEHOLDER;
21189
21240
  if (maxChars && text.length > maxChars) {
21190
21241
  text = text.slice(0, toolResultCutAt(text, maxChars))
21191
21242
  + '\n\n[truncated — original was ' + text.length + ' chars'
@@ -28349,11 +28400,16 @@ export class AgentFramework {
28349
28400
  // the round's calls, finished or not.
28350
28401
  const { cap, bound } = this.resolveToolResultInlineCap(agent);
28351
28402
  const share = toolResultShare(cap, bound, state.pending.size + state.completed.length);
28403
+ const dateLabel = new Date().toISOString().slice(0, 10);
28352
28404
  for (let i = state.completed.length - 1; i >= 0 && collecting(); i--) {
28353
28405
  const tc = state.completed[i]!;
28354
28406
  const { text, shown } = this.storedToolResultText(agentName, tc, cap);
28355
28407
  const alone = storedImageSlots(text, cap, shown, bound);
28356
- const byShare = storedImageSlots(text, share.cap, shown, share.bound);
28408
+ // By its share, with the notice the commit's cut would carry, so a
28409
+ // result no longer than its notice counts as kept whole, as the
28410
+ // commit stores it.
28411
+ const byShare = storedImageSlots(text, share.cap, shown, share.bound,
28412
+ this.spillNoticeLength(`${dateLabel}-${tc.id}`, text, shown, share.bound, cap));
28357
28413
  if (alone.length !== byShare.length || alone.some((slot, j) => slot.text !== byShare[j]!.text)) {
28358
28414
  this.toolRoundsByShare.add(state.completed);
28359
28415
  }
@@ -434,7 +434,10 @@ export function unfetchableReason(record: ReferenceRecord, nowMs = Date.now()):
434
434
  /**
435
435
  * RFC-005 treatment for one MCPL wire block, for the model-visible text
436
436
  * lanes. Returns a replacement string, or null when the block should keep
437
- * its existing (inline/text) handling.
437
+ * its existing (inline/text) handling. A reference's stub carries text taken
438
+ * from the block's own fields, so it's made well formed (a lone UTF-16
439
+ * surrogate becomes U+FFFD), as the context store would make it: a tool
440
+ * result's copies then carry the same text (#695).
438
441
  */
439
442
  export function referenceStubOrNull(block: unknown, provenance?: string, serverId?: string): string | null {
440
443
  const c = classifyBlock(block);
@@ -442,7 +445,7 @@ export function referenceStubOrNull(block: unknown, provenance?: string, serverI
442
445
  case 'text': return null;
443
446
  case 'inline':
444
447
  return c.contradiction ? INLINE_WITHHELD_TEXT : null;
445
- case 'reference': return buildReferenceStub(c.testimony, provenance, serverId);
448
+ case 'reference': return buildReferenceStub(c.testimony, provenance, serverId).toWellFormed();
446
449
  case 'invalid': return c.shown;
447
450
  }
448
451
  }