@theokit/sdk 5.9.2 → 5.11.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 (133) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/dist/{agent-WQ4LLTSY.cjs → agent-5DOR5T3E.cjs} +12 -10
  3. package/dist/{agent-WQ4LLTSY.cjs.map → agent-5DOR5T3E.cjs.map} +1 -1
  4. package/dist/{agent-enXXu447.d.ts → agent-CmKwSyyD.d.ts} +27 -0
  5. package/dist/{agent-GZVZXKME.js → agent-GWKRARAL.js} +11 -9
  6. package/dist/{agent-GZVZXKME.js.map → agent-GWKRARAL.js.map} +1 -1
  7. package/dist/{agent-Dh2YHSLj.d.cts → agent-XMkGzff_.d.cts} +27 -0
  8. package/dist/{chunk-PEIV7LOU.js → chunk-4PHSVR2R.js} +68 -37
  9. package/dist/chunk-4PHSVR2R.js.map +1 -0
  10. package/dist/{chunk-KXKT3HSD.cjs → chunk-5H2GJXGC.cjs} +4 -4
  11. package/dist/{chunk-KXKT3HSD.cjs.map → chunk-5H2GJXGC.cjs.map} +1 -1
  12. package/dist/{chunk-JU76WCW7.cjs → chunk-5OHB5HJF.cjs} +123 -92
  13. package/dist/chunk-5OHB5HJF.cjs.map +1 -0
  14. package/dist/{chunk-EVH3OUMY.js → chunk-74OA5DIM.js} +189 -43
  15. package/dist/chunk-74OA5DIM.js.map +1 -0
  16. package/dist/chunk-7KIN3L2S.js +103 -0
  17. package/dist/chunk-7KIN3L2S.js.map +1 -0
  18. package/dist/{chunk-EXI7EHDN.js → chunk-7Y23B7XX.js} +3 -3
  19. package/dist/{chunk-EXI7EHDN.js.map → chunk-7Y23B7XX.js.map} +1 -1
  20. package/dist/chunk-ASK2OQM5.cjs +84 -0
  21. package/dist/chunk-ASK2OQM5.cjs.map +1 -0
  22. package/dist/{chunk-QY3CIMUV.cjs → chunk-BZKF7TXX.cjs} +192 -44
  23. package/dist/chunk-BZKF7TXX.cjs.map +1 -0
  24. package/dist/{chunk-ZDF2IJKC.js → chunk-DPY2M74T.js} +3 -3
  25. package/dist/{chunk-ZDF2IJKC.js.map → chunk-DPY2M74T.js.map} +1 -1
  26. package/dist/{chunk-X7Z2FEI7.cjs → chunk-FYEHYQ7T.cjs} +8 -8
  27. package/dist/{chunk-X7Z2FEI7.cjs.map → chunk-FYEHYQ7T.cjs.map} +1 -1
  28. package/dist/{chunk-OZLQ6ZFM.js → chunk-IZDDSLL2.js} +4 -3
  29. package/dist/chunk-IZDDSLL2.js.map +1 -0
  30. package/dist/{chunk-DLUCTZ56.cjs → chunk-L3C6CCBG.cjs} +15 -15
  31. package/dist/{chunk-DLUCTZ56.cjs.map → chunk-L3C6CCBG.cjs.map} +1 -1
  32. package/dist/chunk-LZJXEPEQ.js +58 -0
  33. package/dist/chunk-LZJXEPEQ.js.map +1 -0
  34. package/dist/{chunk-FR6COQXZ.cjs → chunk-N7ZIPW2N.cjs} +3 -3
  35. package/dist/{chunk-FR6COQXZ.cjs.map → chunk-N7ZIPW2N.cjs.map} +1 -1
  36. package/dist/{chunk-RX3CFWQ2.cjs → chunk-NQVWSSX2.cjs} +6 -5
  37. package/dist/chunk-NQVWSSX2.cjs.map +1 -0
  38. package/dist/chunk-NWS2CS3Y.cjs +61 -0
  39. package/dist/chunk-NWS2CS3Y.cjs.map +1 -0
  40. package/dist/chunk-R5YPDAKD.cjs +108 -0
  41. package/dist/chunk-R5YPDAKD.cjs.map +1 -0
  42. package/dist/chunk-RGQICWFU.js +82 -0
  43. package/dist/chunk-RGQICWFU.js.map +1 -0
  44. package/dist/{chunk-N7KYUNFO.js → chunk-W2ZVTEOD.js} +3 -3
  45. package/dist/{chunk-N7KYUNFO.js.map → chunk-W2ZVTEOD.js.map} +1 -1
  46. package/dist/{chunk-47Z6LP3I.js → chunk-X3LOJJMO.js} +88 -28
  47. package/dist/chunk-X3LOJJMO.js.map +1 -0
  48. package/dist/{chunk-M2CCHC66.js → chunk-Z5BAFHPU.js} +3 -3
  49. package/dist/{chunk-M2CCHC66.js.map → chunk-Z5BAFHPU.js.map} +1 -1
  50. package/dist/{chunk-VZ2JZ2EH.cjs → chunk-ZD66GFH5.cjs} +89 -27
  51. package/dist/chunk-ZD66GFH5.cjs.map +1 -0
  52. package/dist/{compact-session-4QHBBGEY.cjs → compact-session-2AETONOS.cjs} +12 -12
  53. package/dist/{compact-session-4QHBBGEY.cjs.map → compact-session-2AETONOS.cjs.map} +1 -1
  54. package/dist/{compact-session-PVAWTKKL.js → compact-session-F2UDGZCN.js} +3 -3
  55. package/dist/{compact-session-PVAWTKKL.js.map → compact-session-F2UDGZCN.js.map} +1 -1
  56. package/dist/{cron-DTuaPMVI.d.ts → cron-BPccQCO8.d.ts} +1 -1
  57. package/dist/{cron-QTgcwcZt.d.cts → cron-Blj6wMYg.d.cts} +1 -1
  58. package/dist/cron.cjs +11 -9
  59. package/dist/cron.d.cts +2 -2
  60. package/dist/cron.d.ts +2 -2
  61. package/dist/cron.js +10 -8
  62. package/dist/eval.cjs +14 -12
  63. package/dist/eval.cjs.map +1 -1
  64. package/dist/eval.js +10 -8
  65. package/dist/eval.js.map +1 -1
  66. package/dist/fs-session-store-3VI4CPTX.js +11 -0
  67. package/dist/{fs-session-store-LCZBM3LT.js.map → fs-session-store-3VI4CPTX.js.map} +1 -1
  68. package/dist/fs-session-store-IQ6PEHYF.cjs +20 -0
  69. package/dist/{fs-session-store-SVEMRE4K.cjs.map → fs-session-store-IQ6PEHYF.cjs.map} +1 -1
  70. package/dist/{index-manager-6B2UF5S3.js → index-manager-JVYIVTZG.js} +5 -4
  71. package/dist/{index-manager-6B2UF5S3.js.map → index-manager-JVYIVTZG.js.map} +1 -1
  72. package/dist/{index-manager-M3FHJCHQ.cjs → index-manager-YGXRFJMZ.cjs} +6 -5
  73. package/dist/{index-manager-M3FHJCHQ.cjs.map → index-manager-YGXRFJMZ.cjs.map} +1 -1
  74. package/dist/index.cjs +62 -145
  75. package/dist/index.cjs.map +1 -1
  76. package/dist/index.d.cts +12 -3
  77. package/dist/index.d.ts +12 -3
  78. package/dist/index.js +27 -115
  79. package/dist/index.js.map +1 -1
  80. package/dist/{inject-session-O24XGRR6.js → inject-session-E5UDFVLI.js} +3 -3
  81. package/dist/{inject-session-O24XGRR6.js.map → inject-session-E5UDFVLI.js.map} +1 -1
  82. package/dist/{inject-session-OMLFL2V3.cjs → inject-session-W4UKACYJ.cjs} +4 -4
  83. package/dist/{inject-session-OMLFL2V3.cjs.map → inject-session-W4UKACYJ.cjs.map} +1 -1
  84. package/dist/internal/budget/normalize-usage.d.ts +81 -0
  85. package/dist/internal/llm/anthropic-shared.d.ts +6 -0
  86. package/dist/internal/llm/openai.d.ts +3 -5
  87. package/dist/internal/llm/openrouter-system.d.ts +1 -0
  88. package/dist/internal/llm/types.d.ts +10 -5
  89. package/dist/internal/memory/dreaming/phases.d.ts +2 -0
  90. package/dist/internal/memory/dreaming/run.d.ts +5 -0
  91. package/dist/internal/memory/sdk-memory-peer-loader.d.ts +2 -0
  92. package/dist/internal/memory/storage/fact-ceiling.d.cts +19 -0
  93. package/dist/internal/memory/storage/fact-ceiling.d.ts +19 -0
  94. package/dist/internal/memory/storage/index.cjs +40 -31
  95. package/dist/internal/memory/storage/index.d.cts +1 -0
  96. package/dist/internal/memory/storage/index.d.ts +1 -0
  97. package/dist/internal/memory/storage/index.js +3 -2
  98. package/dist/internal/memory/storage/markdown-store.d.cts +3 -1
  99. package/dist/internal/memory/storage/markdown-store.d.ts +3 -1
  100. package/dist/internal/memory/types.d.ts +6 -0
  101. package/dist/internal/persistence/index.cjs +7 -6
  102. package/dist/internal/persistence/index.cjs.map +1 -1
  103. package/dist/internal/persistence/index.js +2 -1
  104. package/dist/internal/persistence/index.js.map +1 -1
  105. package/dist/internal/runtime/registry/agent-registry-store.d.ts +2 -0
  106. package/dist/models.cjs +5 -50
  107. package/dist/models.cjs.map +1 -1
  108. package/dist/models.js +3 -51
  109. package/dist/models.js.map +1 -1
  110. package/dist/persistence.cjs +7 -6
  111. package/dist/persistence.cjs.map +1 -1
  112. package/dist/persistence.js +2 -1
  113. package/dist/persistence.js.map +1 -1
  114. package/dist/subagents-loader.d.cts +1 -1
  115. package/dist/subagents-loader.d.ts +1 -1
  116. package/dist/types/agent.d.ts +27 -0
  117. package/docs/error-codes.md +29 -26
  118. package/docs/harness-capability-map.md +6 -1
  119. package/package.json +1 -1
  120. package/dist/chunk-47Z6LP3I.js.map +0 -1
  121. package/dist/chunk-BKMDRBJ7.js +0 -180
  122. package/dist/chunk-BKMDRBJ7.js.map +0 -1
  123. package/dist/chunk-EVH3OUMY.js.map +0 -1
  124. package/dist/chunk-JU76WCW7.cjs.map +0 -1
  125. package/dist/chunk-OF2CLCTH.cjs +0 -186
  126. package/dist/chunk-OF2CLCTH.cjs.map +0 -1
  127. package/dist/chunk-OZLQ6ZFM.js.map +0 -1
  128. package/dist/chunk-PEIV7LOU.js.map +0 -1
  129. package/dist/chunk-QY3CIMUV.cjs.map +0 -1
  130. package/dist/chunk-RX3CFWQ2.cjs.map +0 -1
  131. package/dist/chunk-VZ2JZ2EH.cjs.map +0 -1
  132. package/dist/fs-session-store-LCZBM3LT.js +0 -10
  133. package/dist/fs-session-store-SVEMRE4K.cjs +0 -19
package/CHANGELOG.md CHANGED
@@ -1,5 +1,109 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#734](https://github.com/usetheokit/theokit-sdk/pull/734) [`1f04344`](https://github.com/usetheokit/theokit-sdk/commit/1f0434491b706f7ea97f53d998fc33b300af1c33) Thanks [@usetheodev](https://github.com/usetheodev)! - Prompt caching now turns on for Anthropic models, and the cache counters they report reach the
8
+ turn's usage.
9
+
10
+ For a model id that starts with `anthropic/` or `claude` (after an optional `openrouter/`,
11
+ `vertex/` or `bedrock/` prefix),
12
+ the agent loop sends the system prompt as text blocks: the configured prompt first, marked with
13
+ `cache_control: { type: "ephemeral" }`, then the `<active-memory>` block when memory adds one. The
14
+ Anthropic client sends the blocks as they are, and the OpenRouter client sends them as `content`
15
+ parts of the `system` message, with `cache_control` on the cacheable part. Every other provider
16
+ still receives one string. Bedrock ids (`anthropic.claude-…`) are not matched,
17
+ and their bodies do not change. Vertex Anthropic ids (`vertex/anthropic/claude-…`) are matched
18
+ and get the same blocks; no live Vertex response was measured for this change.
19
+
20
+ Things a caller can observe:
21
+
22
+ - **Billing.** Anthropic charges cache writes at 1.25 times the input price and cache reads at 0.1
23
+ times. A run with a single turn whose system prompt is above the model's caching minimum pays
24
+ the write premium and never reads the prefix back.
25
+ - **Order.** For these models the memory block now comes after the configured prompt instead of
26
+ before it. On a client that joins the blocks into one string, the text is the same and the order
27
+ is reversed.
28
+ - **What still misses the cache.** The cached prefix is the whole assembled prompt, so `<memory>`
29
+ facts, resolved skills or context that change between turns change block 1 and miss.
30
+ - **Counters.** The Anthropic streaming client reads `cache_read_input_tokens` and
31
+ `cache_creation_input_tokens` from `message_start`, where Anthropic reports them; a value in
32
+ `message_delta` still wins when it is above zero, and a zero there leaves the `message_start`
33
+ value in place. The non-streaming parser shared by the Bedrock and Vertex Anthropic clients now
34
+ returns both counters too.
35
+ - **Cost on the chat-completions client.** `prompt_tokens` there already includes the cached
36
+ slice, and the client used to report it whole as `inputTokens` beside `cacheReadTokens`, so the
37
+ estimated cost charged every cached token twice (about 8 times too high on a cached
38
+ OpenRouter Anthropic turn). `inputTokens` is now the uncached portion, as on the Anthropic
39
+ client, and `prompt_tokens_details.cache_write_tokens` is read into `cacheWriteTokens`. A
40
+ native OpenAI chat-completions run with a cache hit reports a lower `inputTokens` and a lower
41
+ cost than before. When a usage object carries both the nested `prompt_tokens_details` counts and the
42
+ Anthropic-style top-level ones, the nested count wins and a top-level count fills a nested
43
+ zero, the rule `normalizeUsage` already applied; the stream client used to let the top-level
44
+ field win.
45
+ - **Budget trackers.** A `BudgetTracker`'s `input` event now carries the whole prompt:
46
+ `inputTokens` plus `cacheReadTokens` and `cacheWriteTokens`. On the chat-completions client this
47
+ keeps the count a tracker saw before `inputTokens` became the uncached portion. On the Anthropic
48
+ clients, which always reported the uncached portion, a cached turn now counts its cached tokens
49
+ against `maxTokens`, and `createUsdBudgetTracker` prices them at the input rate, so a cost cap
50
+ trips earlier than the provider's bill would.
51
+ - **Input tokens on the Anthropic stream.** `input_tokens` is read from `message_start` too, so a
52
+ stream whose `message_delta` carries only `output_tokens` reports its uncached input instead of
53
+ none. A value above zero in `message_delta` still replaces it; a `null` or a zero there leaves
54
+ the `message_start` count.
55
+ - **Malformed Anthropic frames.** A `content_block_start`, `content_block_delta` or
56
+ `message_delta` frame that is not valid JSON now fails the turn with a retryable `NetworkError`
57
+ (`code: "stream_malformed_frame"`) instead of being skipped, which finished the turn with text
58
+ or tool input missing. Any other malformed frame is still skipped and reported on the
59
+ diagnostics channel. The error message and the diagnostic line name the event and the frame's
60
+ length, never its body, which can hold model output or tool input.
61
+
62
+ ## 5.10.0
63
+
64
+ ### Minor Changes
65
+
66
+ - [#724](https://github.com/usetheokit/theokit-sdk/pull/724) [`bc2f665`](https://github.com/usetheokit/theokit-sdk/commit/bc2f665d4c5e03dda26858004ac60bd1f7d3f3bb) Thanks [@usetheodev](https://github.com/usetheodev)! - Memory can now be given a fact ceiling. Once the store is full, a new fact is refused with a
67
+ typed error. Before this, nothing stopped the store growing, and the one cap that did exist, 500
68
+ facts per dreaming sweep, left the rest out of clustering while the result still said
69
+ `status: "ok"`.
70
+
71
+ Set `memory.maxFacts` on an agent to declare a ceiling. A new fact at or over it is refused with a
72
+ `ConfigurationError` whose code is `memory_ceiling_reached`, and nothing is written. The message
73
+ gives the directory, how many facts it holds, the ceiling and what to consolidate. Recording a fact
74
+ that is already stored counts as a second observation, not a new fact, so it is still admitted. A
75
+ value that is not a positive integer is refused with `invalid_memory_ceiling` by `Agent.create`
76
+ and `Agent.resume`, before the agent exists, and again by the writer before anything touches
77
+ disk. A prompt-driven memory write that hits the ceiling reports it on one diagnostic line and
78
+ stores nothing. With no ceiling declared, nothing changes and no extra read happens.
79
+
80
+ The ceiling holds across processes. Every SDK process that writes one memory directory with a
81
+ ceiling takes a lock (`<directory>.lock`, beside the directory) around the count and the write, so
82
+ two processes one fact below the ceiling no longer both get in. The lock needs the optional
83
+ `proper-lockfile` peer. Without it the ceiling holds within one process only, and the SDK says so
84
+ once on its diagnostics channel. A writer that declares no ceiling, such as the Claude Code CLI,
85
+ takes no lock and can still add facts past it.
86
+
87
+ A resumed agent keeps its ceiling and its `memory.directory`. The directory is now saved with the
88
+ agent, and a `memory` object passed to `Agent.resume` replaces only the fields it sets (a field
89
+ set to `undefined` keeps its persisted value). Before
90
+ this, `Agent.resume(id, { memory: { enabled: true } })` came back with no ceiling, and any resumed
91
+ agent wrote to the default store instead of the directory it was created with.
92
+
93
+ `createInMemoryMarkdownProvider({ maxFacts })` in `@theokit/sdk-memory` applies the same ceiling
94
+ to the adapter's `write` and to the `memory_remember` tool. Each handle counts its own facts.
95
+
96
+ `DreamingSweepResult` gains `factsLeftOut`, the number of deduplicated facts past the 500-fact
97
+ cap that a sweep did not cluster. It is reported on both dispatch paths, the `@theokit/sdk-memory`
98
+ peer and the SDK's own fallback. It is 0 on a skipped sweep and absent on a failed one. It is also
99
+ absent when an older `@theokit/sdk-memory` runs the sweep, because that version cannot count it,
100
+ so read absence as unknown, not as 0. `ClusterResult`, which `@theokit/sdk-memory` exports, now
101
+ requires `factsLeftOut` too. Code that builds its own `ClusterResult`, such as a mock of
102
+ `remPhase`, has to add it.
103
+
104
+ `@theokit/sdk-memory` now needs `@theokit/sdk` `^5.10.0`, the first release that exports the
105
+ ceiling helpers it imports.
106
+
3
107
  ## 5.9.2
4
108
 
5
109
  ### Patch Changes
@@ -1,18 +1,18 @@
1
1
  'use strict';
2
2
 
3
- var chunkJU76WCW7_cjs = require('./chunk-JU76WCW7.cjs');
3
+ var chunk5OHB5HJF_cjs = require('./chunk-5OHB5HJF.cjs');
4
4
  require('./chunk-J6GXS5A2.cjs');
5
- require('./chunk-FR6COQXZ.cjs');
5
+ require('./chunk-N7ZIPW2N.cjs');
6
6
  require('./chunk-BUUUWQMB.cjs');
7
- require('./chunk-DLUCTZ56.cjs');
7
+ require('./chunk-L3C6CCBG.cjs');
8
8
  require('./chunk-KIKKTW5O.cjs');
9
9
  require('./chunk-BV2MWEMV.cjs');
10
10
  require('./chunk-YEHQ3SIC.cjs');
11
11
  require('./chunk-GHX4P3V2.cjs');
12
12
  require('./chunk-TMKTSYDS.cjs');
13
- require('./chunk-VZ2JZ2EH.cjs');
14
- require('./chunk-RX3CFWQ2.cjs');
15
- require('./chunk-QY3CIMUV.cjs');
13
+ require('./chunk-ZD66GFH5.cjs');
14
+ require('./chunk-NQVWSSX2.cjs');
15
+ require('./chunk-BZKF7TXX.cjs');
16
16
  require('./chunk-CQYBJOB2.cjs');
17
17
  require('./chunk-YJNYDJ2T.cjs');
18
18
  require('./chunk-WPO3VCY4.cjs');
@@ -40,7 +40,8 @@ require('./chunk-NKIQTLFA.cjs');
40
40
  require('./chunk-ZWACQM5U.cjs');
41
41
  require('./chunk-A4RAL2ER.cjs');
42
42
  require('./chunk-P22BZE7G.cjs');
43
- require('./chunk-OF2CLCTH.cjs');
43
+ require('./chunk-R5YPDAKD.cjs');
44
+ require('./chunk-ASK2OQM5.cjs');
44
45
  require('./chunk-ZF2LDKQQ.cjs');
45
46
  require('./chunk-GHHIJEFX.cjs');
46
47
  require('./chunk-JLRLCBJ4.cjs');
@@ -48,6 +49,7 @@ require('./chunk-C7GKRGKN.cjs');
48
49
  require('./chunk-TY56BKSK.cjs');
49
50
  require('./chunk-MPR2ISL2.cjs');
50
51
  require('./chunk-J5623RIV.cjs');
52
+ require('./chunk-NWS2CS3Y.cjs');
51
53
  require('./chunk-3EE6LVWT.cjs');
52
54
  require('./chunk-SGC7LSHF.cjs');
53
55
  require('./chunk-HU666T3Q.cjs');
@@ -63,7 +65,7 @@ require('./chunk-6LHQPOMI.cjs');
63
65
 
64
66
  Object.defineProperty(exports, "Agent", {
65
67
  enumerable: true,
66
- get: function () { return chunkJU76WCW7_cjs.Agent; }
68
+ get: function () { return chunk5OHB5HJF_cjs.Agent; }
67
69
  });
68
- //# sourceMappingURL=agent-WQ4LLTSY.cjs.map
69
- //# sourceMappingURL=agent-WQ4LLTSY.cjs.map
70
+ //# sourceMappingURL=agent-5DOR5T3E.cjs.map
71
+ //# sourceMappingURL=agent-5DOR5T3E.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-WQ4LLTSY.cjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-5DOR5T3E.cjs"}
@@ -1437,6 +1437,33 @@ interface MemorySettings {
1437
1437
  * share the writes.
1438
1438
  */
1439
1439
  directory?: string;
1440
+ /**
1441
+ * The most facts this agent's memory may hold. Default: no ceiling.
1442
+ *
1443
+ * The ceiling counts the write directory only: the per-memory fact files and any legacy
1444
+ * `## Facts` bullets in that directory's `MEMORY.md`. A dreaming sweep's `factsBefore` counts
1445
+ * every root it reads, so the two numbers can differ.
1446
+ *
1447
+ * At the ceiling a new fact is refused with a `ConfigurationError` whose code is
1448
+ * `memory_ceiling_reached` and whose message names the directory, the count and what to
1449
+ * consolidate; nothing is written. Recording a fact that is already stored is a second
1450
+ * observation, not a new fact, and is still admitted. A value that is not a positive integer is
1451
+ * refused with `invalid_memory_ceiling` by `Agent.create` and `Agent.resume`, before the agent
1452
+ * exists, whether or not memory is enabled, and again by the writer before anything touches disk.
1453
+ *
1454
+ * The count and the write hold a lock that every SDK process writing this directory with a
1455
+ * ceiling takes, so several processes on one directory cannot together pass it. That lock is
1456
+ * the companion `<directory>.lock` beside the directory and needs the optional `proper-lockfile`
1457
+ * peer; without it the ceiling holds within one process only, and the SDK says so once on its
1458
+ * diagnostics channel. A writer that declares no ceiling, such as the Claude Code CLI, does not
1459
+ * take the lock and can still add facts past it. When the lock stays busy past its retries the
1460
+ * write is refused with `proper-lockfile`'s `ELOCKED` error, and nothing is written.
1461
+ *
1462
+ * A resumed agent keeps its ceiling and its `directory`: a `memory` object passed to
1463
+ * `Agent.resume` replaces only the fields it sets, and a field set to `undefined` keeps its
1464
+ * persisted value.
1465
+ */
1466
+ maxFacts?: number;
1440
1467
  /**
1441
1468
  * Whether the SDK auto-injects recalled facts as a `<memory>` block in the
1442
1469
  * LLM system prompt. Default `true`.
@@ -1,16 +1,16 @@
1
- export { Agent } from './chunk-PEIV7LOU.js';
1
+ export { Agent } from './chunk-4PHSVR2R.js';
2
2
  import './chunk-XKMVJ443.js';
3
- import './chunk-EXI7EHDN.js';
3
+ import './chunk-7Y23B7XX.js';
4
4
  import './chunk-K2BQQ445.js';
5
- import './chunk-ZDF2IJKC.js';
5
+ import './chunk-DPY2M74T.js';
6
6
  import './chunk-ZHWKT2NI.js';
7
7
  import './chunk-2SFBB54R.js';
8
8
  import './chunk-HI3W37FY.js';
9
9
  import './chunk-H73MEMQB.js';
10
10
  import './chunk-OR6XIWLB.js';
11
- import './chunk-47Z6LP3I.js';
12
- import './chunk-OZLQ6ZFM.js';
13
- import './chunk-EVH3OUMY.js';
11
+ import './chunk-X3LOJJMO.js';
12
+ import './chunk-IZDDSLL2.js';
13
+ import './chunk-74OA5DIM.js';
14
14
  import './chunk-SUVCHX4L.js';
15
15
  import './chunk-2XC6KDJM.js';
16
16
  import './chunk-TE6XVTOA.js';
@@ -38,7 +38,8 @@ import './chunk-GTX6FEDP.js';
38
38
  import './chunk-FTZTZBCU.js';
39
39
  import './chunk-WE22OXQA.js';
40
40
  import './chunk-XZHJYSPB.js';
41
- import './chunk-BKMDRBJ7.js';
41
+ import './chunk-7KIN3L2S.js';
42
+ import './chunk-RGQICWFU.js';
42
43
  import './chunk-Q5EWJPRY.js';
43
44
  import './chunk-GGRPAQ3B.js';
44
45
  import './chunk-3JHIFQ4I.js';
@@ -46,6 +47,7 @@ import './chunk-ZDYDBXSD.js';
46
47
  import './chunk-X7EUUHXU.js';
47
48
  import './chunk-MQGSOKR3.js';
48
49
  import './chunk-GMRFAX4I.js';
50
+ import './chunk-LZJXEPEQ.js';
49
51
  import './chunk-R7WIIPUR.js';
50
52
  import './chunk-I2ORT6QD.js';
51
53
  import './chunk-SVCPJRUB.js';
@@ -56,5 +58,5 @@ import './chunk-H3CVJSFC.js';
56
58
  import './chunk-Q7GYMXVC.js';
57
59
  import './chunk-B5MHRQJZ.js';
58
60
  import './chunk-CZJ6Q7CW.js';
59
- //# sourceMappingURL=agent-GZVZXKME.js.map
60
- //# sourceMappingURL=agent-GZVZXKME.js.map
61
+ //# sourceMappingURL=agent-GWKRARAL.js.map
62
+ //# sourceMappingURL=agent-GWKRARAL.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-GZVZXKME.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-GWKRARAL.js"}
@@ -1437,6 +1437,33 @@ interface MemorySettings {
1437
1437
  * share the writes.
1438
1438
  */
1439
1439
  directory?: string;
1440
+ /**
1441
+ * The most facts this agent's memory may hold. Default: no ceiling.
1442
+ *
1443
+ * The ceiling counts the write directory only: the per-memory fact files and any legacy
1444
+ * `## Facts` bullets in that directory's `MEMORY.md`. A dreaming sweep's `factsBefore` counts
1445
+ * every root it reads, so the two numbers can differ.
1446
+ *
1447
+ * At the ceiling a new fact is refused with a `ConfigurationError` whose code is
1448
+ * `memory_ceiling_reached` and whose message names the directory, the count and what to
1449
+ * consolidate; nothing is written. Recording a fact that is already stored is a second
1450
+ * observation, not a new fact, and is still admitted. A value that is not a positive integer is
1451
+ * refused with `invalid_memory_ceiling` by `Agent.create` and `Agent.resume`, before the agent
1452
+ * exists, whether or not memory is enabled, and again by the writer before anything touches disk.
1453
+ *
1454
+ * The count and the write hold a lock that every SDK process writing this directory with a
1455
+ * ceiling takes, so several processes on one directory cannot together pass it. That lock is
1456
+ * the companion `<directory>.lock` beside the directory and needs the optional `proper-lockfile`
1457
+ * peer; without it the ceiling holds within one process only, and the SDK says so once on its
1458
+ * diagnostics channel. A writer that declares no ceiling, such as the Claude Code CLI, does not
1459
+ * take the lock and can still add facts past it. When the lock stays busy past its retries the
1460
+ * write is refused with `proper-lockfile`'s `ELOCKED` error, and nothing is written.
1461
+ *
1462
+ * A resumed agent keeps its ceiling and its `directory`: a `memory` object passed to
1463
+ * `Agent.resume` replaces only the fields it sets, and a field set to `undefined` keeps its
1464
+ * persisted value.
1465
+ */
1466
+ maxFacts?: number;
1440
1467
  /**
1441
1468
  * Whether the SDK auto-injects recalled facts as a `<memory>` block in the
1442
1469
  * LLM system prompt. Default `true`.
@@ -1,13 +1,13 @@
1
1
  import { submit, emitRunEvent } from './chunk-XKMVJ443.js';
2
- import { enqueueSessionWrite, hydrateSession, persistTurnToTranscript, flushSessionWrites, appendSessionMessage, getSessionMessages, discardSession, clearSession } from './chunk-EXI7EHDN.js';
3
- import { IndexManager } from './chunk-ZDF2IJKC.js';
2
+ import { enqueueSessionWrite, hydrateSession, persistTurnToTranscript, flushSessionWrites, appendSessionMessage, getSessionMessages, discardSession, clearSession } from './chunk-7Y23B7XX.js';
3
+ import { IndexManager } from './chunk-DPY2M74T.js';
4
4
  import { currentPersonalityContext, warnPersonalitySwitchInsideFork } from './chunk-ZHWKT2NI.js';
5
5
  import { extractCodePlugins } from './chunk-2SFBB54R.js';
6
6
  import { createOpenAiCompatibleRuntime } from './chunk-HI3W37FY.js';
7
7
  import { persistActiveMemoryTranscript } from './chunk-OR6XIWLB.js';
8
- import { writeSessionSummary, resolveMemoryRoot, MEMORY_KINDS, appendFact, readFacts, legacyMemoryJsonPath, memoryMdPath, appendFactToMarkdown } from './chunk-47Z6LP3I.js';
9
- import { FsSessionStore } from './chunk-OZLQ6ZFM.js';
10
- import { discoverProviderPlugins, validateApiKeyShape, getConfiguredBaseUrl, httpRequest, isFixtureApiKey, presentProviderCredentialEnvVars, buildDefaultSummarizer, shouldUseRealLocalRuntime, parseSseStream, CircuitBreaker, resolveRunProvider, mergeExplicitApiKey, resolveProviderChain, abortError, tryFirstEvent, relayStream, renderToolResultContentText } from './chunk-EVH3OUMY.js';
8
+ import { resolveMaxFacts, writeSessionSummary, resolveMemoryRoot, MEMORY_KINDS, appendFact, readFacts, legacyMemoryJsonPath, memoryMdPath, appendFactToMarkdown } from './chunk-X3LOJJMO.js';
9
+ import { FsSessionStore } from './chunk-IZDDSLL2.js';
10
+ import { discoverProviderPlugins, validateApiKeyShape, getConfiguredBaseUrl, httpRequest, isFixtureApiKey, presentProviderCredentialEnvVars, buildDefaultSummarizer, shouldUseRealLocalRuntime, parseSseStream, CircuitBreaker, resolveRunProvider, mergeExplicitApiKey, resolveProviderChain, abortError, tryFirstEvent, relayStream, renderToolResultContentText } from './chunk-74OA5DIM.js';
11
11
  import { resolveChildEnv } from './chunk-HKCKOAIO.js';
12
12
  import { DEFAULT_MAX_BYTES_PER_FILE, runDiscovery, truncateWithMarker } from './chunk-7QJYKVP6.js';
13
13
  import { warnFailureOnce, loadHookConfig, warnOnce } from './chunk-OPAKPEPG.js';
@@ -22,13 +22,14 @@ import { validateArtifactPath, PathTraversalError, safePathJoin } from './chunk-
22
22
  import { insideRoot, atOrInsideRoot } from './chunk-UKMBRMGT.js';
23
23
  import { mapWithConcurrency } from './chunk-7JAKO3NM.js';
24
24
  import { expandTilde, defaultBaseDir } from './chunk-FTZTZBCU.js';
25
- import { withFileLock } from './chunk-BKMDRBJ7.js';
25
+ import { withFileLock } from './chunk-RGQICWFU.js';
26
26
  import { withCwdMutex } from './chunk-Q5EWJPRY.js';
27
27
  import { sweepStaleAtomicTemps, atomicWriteJson } from './chunk-3JHIFQ4I.js';
28
28
  import { loadSubagents, pluginBundleDirs } from './chunk-ZDYDBXSD.js';
29
29
  import { reportUndeclaredSources, theokitConfigRoot, undefinedVariablesIn, getTheokitHome, adapterForConfigPath, adaptersForSurface, projectConfigRoots, pluginBundleRoots } from './chunk-X7EUUHXU.js';
30
30
  import { readWorkspaceDir, parseSimpleYaml } from './chunk-MQGSOKR3.js';
31
31
  import { resolveEffectiveContextWindow, CONTEXT_WINDOW_FLOOR, CONTEXT_WINDOW_MARGIN } from './chunk-GMRFAX4I.js';
32
+ import { isAnthropicFamilyModel } from './chunk-LZJXEPEQ.js';
32
33
  import { parseModelId } from './chunk-R7WIIPUR.js';
33
34
  import { getProviderProfile } from './chunk-I2ORT6QD.js';
34
35
  import { getCatalogModelInfo, isPatchedModelKey } from './chunk-SVCPJRUB.js';
@@ -335,6 +336,8 @@ function serializeMemory(memory) {
335
336
  if (memory.scope !== void 0) out.scope = memory.scope;
336
337
  if (memory.activeRecall !== void 0) out.activeRecall = { ...memory.activeRecall };
337
338
  if (memory.index !== void 0) out.index = serializeMemoryIndex(memory.index);
339
+ if (memory.maxFacts !== void 0) out.maxFacts = memory.maxFacts;
340
+ if (memory.directory !== void 0) out.directory = memory.directory;
338
341
  return out;
339
342
  }
340
343
  function serializeMemoryIndex(index) {
@@ -884,6 +887,7 @@ async function readMemoryFacts(cwd, config) {
884
887
  }
885
888
  async function appendMemoryFact(cwd, config, fact) {
886
889
  if (!config.enabled) return;
890
+ resolveMaxFacts(config.maxFacts);
887
891
  await migrateLegacyJson(cwd, config);
888
892
  const sanitized = {
889
893
  text: redactSecrets(fact.text),
@@ -3611,6 +3615,7 @@ function validateToolSchema(tool) {
3611
3615
  }
3612
3616
  function validateMemory(options) {
3613
3617
  const memory = options.memory;
3618
+ resolveMaxFacts(memory?.maxFacts);
3614
3619
  if (memory?.storePath === void 0) return;
3615
3620
  const storePath = memory.storePath;
3616
3621
  if (storePath.includes("..") || storePath.startsWith("/") || /^[A-Z]:/i.test(storePath)) {
@@ -5800,14 +5805,27 @@ function stripThinkBlocks(content) {
5800
5805
  // src/internal/agent-loop/loop-llm-stream.ts
5801
5806
  function resolveSystemPromptWithMemoryAdditions(systemPrompt, additions) {
5802
5807
  if (additions === void 0 || additions.length === 0) return systemPrompt;
5803
- const block = `<active-memory>
5804
- ${escapeBlockBody(additions)}
5805
- </active-memory>`;
5808
+ const block = activeMemoryBlock(additions);
5806
5809
  if (systemPrompt === void 0 || systemPrompt.length === 0) return block;
5807
5810
  return `${block}
5808
5811
 
5809
5812
  ${systemPrompt}`;
5810
5813
  }
5814
+ function activeMemoryBlock(additions) {
5815
+ return `<active-memory>
5816
+ ${escapeBlockBody(additions)}
5817
+ </active-memory>`;
5818
+ }
5819
+ function buildLoopSystem(systemPrompt, additions, modelId) {
5820
+ if (!isAnthropicFamilyModel(modelId) || systemPrompt === void 0 || systemPrompt.length === 0) {
5821
+ return resolveSystemPromptWithMemoryAdditions(systemPrompt, additions);
5822
+ }
5823
+ const blocks = [{ text: systemPrompt, cacheable: true }];
5824
+ if (additions !== void 0 && additions.length > 0) {
5825
+ blocks.push({ text: activeMemoryBlock(additions) });
5826
+ }
5827
+ return blocks;
5828
+ }
5811
5829
  function toLlmTool(tool) {
5812
5830
  return { name: tool.name, description: tool.description, inputSchema: tool.inputSchema };
5813
5831
  }
@@ -5846,9 +5864,10 @@ async function streamLlmTurn(inputs, ctx) {
5846
5864
  {
5847
5865
  model: inputs.model.id ?? "auto",
5848
5866
  ...(() => {
5849
- const effective = resolveSystemPromptWithMemoryAdditions(
5867
+ const effective = buildLoopSystem(
5850
5868
  inputs.systemPrompt,
5851
- ctx.memorySystemPromptAdditions
5869
+ ctx.memorySystemPromptAdditions,
5870
+ inputs.model.id
5852
5871
  );
5853
5872
  return effective !== void 0 ? { system: effective } : {};
5854
5873
  })(),
@@ -6835,29 +6854,32 @@ async function runIteration(inputs, ctx) {
6835
6854
  const llmOutput = await streamLlmTurn(inputs, ctx);
6836
6855
  await inputs.pluginManager?.runPostLlmCallHooks(hookCtx);
6837
6856
  accumulateUsage(ctx.usage, llmOutput);
6838
- if (inputs.budgetTracker !== void 0) {
6839
- const modelId = inputs.model.id ?? "auto";
6840
- const inputT = llmOutput.inputTokens ?? 0;
6841
- const outputT = llmOutput.outputTokens ?? 0;
6842
- try {
6843
- if (inputT > 0) {
6844
- inputs.budgetTracker.track({
6845
- tokens: inputT,
6846
- model: modelId,
6847
- type: "input"
6848
- });
6849
- }
6850
- if (outputT > 0) {
6851
- inputs.budgetTracker.track({
6852
- tokens: outputT,
6853
- model: modelId,
6854
- type: "output"
6855
- });
6856
- }
6857
- } catch {
6857
+ trackTurnUsage(inputs, llmOutput);
6858
+ return continueOrTerminate(inputs, ctx, llmOutput);
6859
+ }
6860
+ function trackTurnUsage(inputs, llmOutput) {
6861
+ const tracker = inputs.budgetTracker;
6862
+ if (tracker === void 0) return;
6863
+ const modelId = inputs.model.id ?? "auto";
6864
+ const inputT = (llmOutput.inputTokens ?? 0) + (llmOutput.cacheReadTokens ?? 0) + (llmOutput.cacheWriteTokens ?? 0);
6865
+ const outputT = llmOutput.outputTokens ?? 0;
6866
+ try {
6867
+ if (inputT > 0) {
6868
+ tracker.track({
6869
+ tokens: inputT,
6870
+ model: modelId,
6871
+ type: "input"
6872
+ });
6858
6873
  }
6874
+ if (outputT > 0) {
6875
+ tracker.track({
6876
+ tokens: outputT,
6877
+ model: modelId,
6878
+ type: "output"
6879
+ });
6880
+ }
6881
+ } catch {
6859
6882
  }
6860
- return continueOrTerminate(inputs, ctx, llmOutput);
6861
6883
  }
6862
6884
  async function transformLlmOutputText(inputs, text, ctx) {
6863
6885
  return inputs.pluginManager !== void 0 ? inputs.pluginManager.runTransformLlmOutputHooks(text, ctx) : text;
@@ -10607,10 +10629,12 @@ async function rehydrateExistingAgent(agentId, existing, options) {
10607
10629
  await discoverProviderPlugins();
10608
10630
  await validateRehydratedAgent(agentId, existing);
10609
10631
  const mergedLocal = options.local !== void 0 && existing.options.local !== void 0 ? { ...existing.options.local, ...options.local } : options.local ?? existing.options.local;
10632
+ const mergedMemory = mergeResumedMemory(existing.options.memory, options.memory);
10610
10633
  const mergedOptions = {
10611
10634
  ...existing.options,
10612
10635
  ...options,
10613
10636
  ...mergedLocal !== void 0 ? { local: mergedLocal } : {},
10637
+ ...mergedMemory !== void 0 ? { memory: mergedMemory } : {},
10614
10638
  // SE8 — normalize a caller-supplied bare-string model override at this resume
10615
10639
  // boundary (Agent.resume never flows through runCreateUnderSpan). Cloud resume
10616
10640
  // honors it; local resume forces the persisted model below.
@@ -10618,6 +10642,7 @@ async function rehydrateExistingAgent(agentId, existing, options) {
10618
10642
  mcpServers: void 0,
10619
10643
  agentId
10620
10644
  };
10645
+ resolveMaxFacts(mergedOptions.memory?.maxFacts);
10621
10646
  if (existing.runtime === "cloud") {
10622
10647
  return new CloudAgent(mergedOptions, agentId);
10623
10648
  }
@@ -10625,6 +10650,12 @@ async function rehydrateExistingAgent(agentId, existing, options) {
10625
10650
  await agent.initialize();
10626
10651
  return agent;
10627
10652
  }
10653
+ function mergeResumedMemory(persisted, override) {
10654
+ if (override === void 0) return persisted;
10655
+ if (persisted === void 0) return override;
10656
+ const named = Object.entries(override).filter(([, value]) => value !== void 0);
10657
+ return { ...persisted, ...Object.fromEntries(named) };
10658
+ }
10628
10659
  async function validateRehydratedAgent(agentId, entry) {
10629
10660
  if (entry.runtime !== "local") return;
10630
10661
  const candidate = entry.options.local?.cwd ?? entry.cwd;
@@ -11053,7 +11084,7 @@ var Agent = class _Agent {
11053
11084
  */
11054
11085
  static async compact(agentId, options = {}) {
11055
11086
  const reg = await requireLocalAgent(agentId, "compact");
11056
- const { compactSessionTranscript, buildDefaultSummarizer: buildDefaultSummarizer2 } = await import('./compact-session-PVAWTKKL.js');
11087
+ const { compactSessionTranscript, buildDefaultSummarizer: buildDefaultSummarizer2 } = await import('./compact-session-F2UDGZCN.js');
11057
11088
  const { cwd, model, store } = await openLocalStore(reg);
11058
11089
  return enqueueSessionWrite(
11059
11090
  cwd,
@@ -11083,7 +11114,7 @@ var Agent = class _Agent {
11083
11114
  */
11084
11115
  static async injectSessionTurn(agentId, turn) {
11085
11116
  const reg = await requireLocalAgent(agentId, "injectSessionTurn");
11086
- const { injectSessionTurn } = await import('./inject-session-O24XGRR6.js');
11117
+ const { injectSessionTurn } = await import('./inject-session-E5UDFVLI.js');
11087
11118
  const { cwd, model, store } = await openLocalStore(reg);
11088
11119
  await injectSessionTurn({
11089
11120
  store,
@@ -11233,7 +11264,7 @@ async function openLocalStore(reg) {
11233
11264
  const cwd = reg.cwd ?? process.cwd();
11234
11265
  const optModel = reg.options.model;
11235
11266
  const model = reg.model?.id ?? (typeof optModel === "string" ? optModel : optModel?.id) ?? "unknown";
11236
- const { FsSessionStore: FsSessionStore2 } = await import('./fs-session-store-LCZBM3LT.js');
11267
+ const { FsSessionStore: FsSessionStore2 } = await import('./fs-session-store-3VI4CPTX.js');
11237
11268
  const { defaultBaseDir: defaultBaseDir2, expandTilde: expandTilde2 } = await import('./session-transcript-AR7IBICT.js');
11238
11269
  const configuredSessionDir = reg.options.local?.sessionDir ?? reg.options.local?.baseDir;
11239
11270
  const baseDir = configuredSessionDir !== void 0 ? expandTilde2(configuredSessionDir) : defaultBaseDir2();
@@ -11241,5 +11272,5 @@ async function openLocalStore(reg) {
11241
11272
  }
11242
11273
 
11243
11274
  export { Agent, AgentBuilder, DEFAULT_AGENTIC_MODEL_ID, MEMORY_EMBEDDING_ADAPTERS, Tool, ToolError, UsageAccumulator, computeCost, generateCronId, getPricingEntry, managedSettingsPathFor, openRouterMemoryEmbeddingProviderAdapter, readManagedSettings, resolveSessionDir };
11244
- //# sourceMappingURL=chunk-PEIV7LOU.js.map
11245
- //# sourceMappingURL=chunk-PEIV7LOU.js.map
11275
+ //# sourceMappingURL=chunk-4PHSVR2R.js.map
11276
+ //# sourceMappingURL=chunk-4PHSVR2R.js.map