@illuma-ai/agents 1.5.1 → 2.1.1

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 (319) hide show
  1. package/README.md +0 -62
  2. package/dist/cjs/agents/AgentContext.cjs +160 -259
  3. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  4. package/dist/cjs/common/enum.cjs +12 -12
  5. package/dist/cjs/common/enum.cjs.map +1 -1
  6. package/dist/cjs/graphs/Graph.cjs +30 -13
  7. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  8. package/dist/cjs/graphs/MultiAgentGraph.cjs +1 -1
  9. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  10. package/dist/cjs/graphs/phases/memoryFlushPhase.cjs +1 -1
  11. package/dist/cjs/graphs/phases/memoryFlushPhase.cjs.map +1 -1
  12. package/dist/cjs/hooks/HookRegistry.cjs +1 -1
  13. package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
  14. package/dist/cjs/hooks/matchers.cjs +2 -2
  15. package/dist/cjs/hooks/matchers.cjs.map +1 -1
  16. package/dist/cjs/hooks/types.cjs +1 -1
  17. package/dist/cjs/hooks/types.cjs.map +1 -1
  18. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +1 -5
  19. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  20. package/dist/cjs/llm/bedrock/index.cjs +33 -61
  21. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  22. package/dist/cjs/llm/openai/index.cjs +1 -1
  23. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  24. package/dist/cjs/llm/openai/utils/index.cjs +10 -27
  25. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  26. package/dist/cjs/main.cjs +3 -84
  27. package/dist/cjs/main.cjs.map +1 -1
  28. package/dist/cjs/memory/citations.cjs +4 -4
  29. package/dist/cjs/memory/citations.cjs.map +1 -1
  30. package/dist/cjs/memory/constants.cjs +17 -17
  31. package/dist/cjs/memory/constants.cjs.map +1 -1
  32. package/dist/cjs/memory/mmr.cjs +1 -1
  33. package/dist/cjs/memory/mmr.cjs.map +1 -1
  34. package/dist/cjs/memory/paths.cjs +1 -1
  35. package/dist/cjs/memory/paths.cjs.map +1 -1
  36. package/dist/cjs/memory/recallTracking.cjs +3 -3
  37. package/dist/cjs/memory/recallTracking.cjs.map +1 -1
  38. package/dist/cjs/memory/temporalDecay.cjs +2 -2
  39. package/dist/cjs/memory/temporalDecay.cjs.map +1 -1
  40. package/dist/cjs/messages/cache.cjs +0 -89
  41. package/dist/cjs/messages/cache.cjs.map +1 -1
  42. package/dist/cjs/messages/format.cjs +13 -71
  43. package/dist/cjs/messages/format.cjs.map +1 -1
  44. package/dist/cjs/tools/BashExecutor.cjs +11 -21
  45. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  46. package/dist/cjs/tools/CodeExecutor.cjs +13 -41
  47. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  48. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +11 -16
  49. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  50. package/dist/cjs/tools/ToolNode.cjs +78 -13
  51. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  52. package/dist/cjs/tools/memory/memoryAppendTool.cjs +1 -1
  53. package/dist/cjs/tools/memory/memoryAppendTool.cjs.map +1 -1
  54. package/dist/cjs/tools/memory/memoryGetTool.cjs +2 -2
  55. package/dist/cjs/tools/memory/memoryGetTool.cjs.map +1 -1
  56. package/dist/cjs/tools/memory/memorySearchTool.cjs +3 -3
  57. package/dist/cjs/tools/memory/memorySearchTool.cjs.map +1 -1
  58. package/dist/cjs/tools/memory/shared.cjs +1 -1
  59. package/dist/cjs/tools/memory/shared.cjs.map +1 -1
  60. package/dist/cjs/tools/search/search.cjs +3 -11
  61. package/dist/cjs/tools/search/search.cjs.map +1 -1
  62. package/dist/cjs/tools/search/tool.cjs +4 -28
  63. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  64. package/dist/cjs/tools/search/utils.cjs +3 -10
  65. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  66. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +48 -0
  67. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  68. package/dist/cjs/types/graph.cjs.map +1 -1
  69. package/dist/esm/agents/AgentContext.mjs +160 -259
  70. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  71. package/dist/esm/common/enum.mjs +12 -12
  72. package/dist/esm/common/enum.mjs.map +1 -1
  73. package/dist/esm/graphs/Graph.mjs +30 -13
  74. package/dist/esm/graphs/Graph.mjs.map +1 -1
  75. package/dist/esm/graphs/MultiAgentGraph.mjs +1 -1
  76. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  77. package/dist/esm/graphs/phases/memoryFlushPhase.mjs +1 -1
  78. package/dist/esm/graphs/phases/memoryFlushPhase.mjs.map +1 -1
  79. package/dist/esm/hooks/HookRegistry.mjs +1 -1
  80. package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
  81. package/dist/esm/hooks/matchers.mjs +2 -2
  82. package/dist/esm/hooks/matchers.mjs.map +1 -1
  83. package/dist/esm/hooks/types.mjs +1 -1
  84. package/dist/esm/hooks/types.mjs.map +1 -1
  85. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +1 -5
  86. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  87. package/dist/esm/llm/bedrock/index.mjs +34 -61
  88. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  89. package/dist/esm/llm/openai/index.mjs +1 -1
  90. package/dist/esm/llm/openai/index.mjs.map +1 -1
  91. package/dist/esm/llm/openai/utils/index.mjs +10 -27
  92. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  93. package/dist/esm/main.mjs +1 -5
  94. package/dist/esm/main.mjs.map +1 -1
  95. package/dist/esm/memory/citations.mjs +4 -4
  96. package/dist/esm/memory/citations.mjs.map +1 -1
  97. package/dist/esm/memory/constants.mjs +17 -17
  98. package/dist/esm/memory/constants.mjs.map +1 -1
  99. package/dist/esm/memory/mmr.mjs +1 -1
  100. package/dist/esm/memory/mmr.mjs.map +1 -1
  101. package/dist/esm/memory/paths.mjs +1 -1
  102. package/dist/esm/memory/paths.mjs.map +1 -1
  103. package/dist/esm/memory/recallTracking.mjs +3 -3
  104. package/dist/esm/memory/recallTracking.mjs.map +1 -1
  105. package/dist/esm/memory/temporalDecay.mjs +2 -2
  106. package/dist/esm/memory/temporalDecay.mjs.map +1 -1
  107. package/dist/esm/messages/cache.mjs +0 -89
  108. package/dist/esm/messages/cache.mjs.map +1 -1
  109. package/dist/esm/messages/format.mjs +13 -71
  110. package/dist/esm/messages/format.mjs.map +1 -1
  111. package/dist/esm/tools/BashExecutor.mjs +12 -22
  112. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  113. package/dist/esm/tools/CodeExecutor.mjs +14 -41
  114. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  115. package/dist/esm/tools/ProgrammaticToolCalling.mjs +12 -17
  116. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  117. package/dist/esm/tools/ToolNode.mjs +78 -13
  118. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  119. package/dist/esm/tools/memory/memoryAppendTool.mjs +1 -1
  120. package/dist/esm/tools/memory/memoryAppendTool.mjs.map +1 -1
  121. package/dist/esm/tools/memory/memoryGetTool.mjs +2 -2
  122. package/dist/esm/tools/memory/memoryGetTool.mjs.map +1 -1
  123. package/dist/esm/tools/memory/memorySearchTool.mjs +3 -3
  124. package/dist/esm/tools/memory/memorySearchTool.mjs.map +1 -1
  125. package/dist/esm/tools/memory/shared.mjs +1 -1
  126. package/dist/esm/tools/memory/shared.mjs.map +1 -1
  127. package/dist/esm/tools/search/search.mjs +3 -11
  128. package/dist/esm/tools/search/search.mjs.map +1 -1
  129. package/dist/esm/tools/search/tool.mjs +4 -28
  130. package/dist/esm/tools/search/tool.mjs.map +1 -1
  131. package/dist/esm/tools/search/utils.mjs +3 -10
  132. package/dist/esm/tools/search/utils.mjs.map +1 -1
  133. package/dist/esm/tools/subagent/SubagentExecutor.mjs +48 -0
  134. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  135. package/dist/esm/types/graph.mjs.map +1 -1
  136. package/dist/types/agents/AgentContext.d.ts +25 -95
  137. package/dist/types/common/enum.d.ts +12 -12
  138. package/dist/types/graphs/Graph.d.ts +2 -2
  139. package/dist/types/graphs/phases/memoryFlushPhase.d.ts +2 -2
  140. package/dist/types/hooks/HookRegistry.d.ts +1 -1
  141. package/dist/types/hooks/matchers.d.ts +2 -2
  142. package/dist/types/hooks/types.d.ts +1 -1
  143. package/dist/types/index.d.ts +0 -1
  144. package/dist/types/llm/bedrock/index.d.ts +1 -54
  145. package/dist/types/llm/openai/index.d.ts +1 -1
  146. package/dist/types/memory/citations.d.ts +4 -4
  147. package/dist/types/memory/constants.d.ts +17 -17
  148. package/dist/types/memory/mmr.d.ts +3 -3
  149. package/dist/types/memory/paths.d.ts +1 -1
  150. package/dist/types/memory/temporalDecay.d.ts +2 -2
  151. package/dist/types/memory/types.d.ts +3 -3
  152. package/dist/types/messages/format.d.ts +2 -5
  153. package/dist/types/tools/CodeExecutor.d.ts +0 -6
  154. package/dist/types/tools/ToolNode.d.ts +3 -3
  155. package/dist/types/tools/memory/shared.d.ts +1 -1
  156. package/dist/types/tools/search/test.d.ts +1 -0
  157. package/dist/types/tools/search/types.d.ts +5 -99
  158. package/dist/types/tools/search/utils.d.ts +2 -2
  159. package/dist/types/tools/subagent/SubagentExecutor.d.ts +29 -0
  160. package/dist/types/types/graph.d.ts +30 -34
  161. package/dist/types/types/index.d.ts +0 -1
  162. package/dist/types/types/messages.d.ts +1 -1
  163. package/dist/types/types/run.d.ts +1 -3
  164. package/dist/types/types/tools.d.ts +5 -14
  165. package/package.json +1 -61
  166. package/src/agents/AgentContext.test.ts +176 -0
  167. package/src/agents/AgentContext.ts +179 -305
  168. package/src/agents/__tests__/AgentContext.test.ts +0 -632
  169. package/src/common/__tests__/enum.test.ts +1 -1
  170. package/src/common/enum.ts +12 -12
  171. package/src/graphs/Graph.ts +32 -13
  172. package/src/graphs/MultiAgentGraph.ts +1 -1
  173. package/src/graphs/gapFeatures.test.ts +1 -1
  174. package/src/graphs/phases/__tests__/memoryFlushPhase.test.ts +1 -1
  175. package/src/graphs/phases/memoryFlushPhase.ts +2 -2
  176. package/src/hooks/HookRegistry.ts +1 -1
  177. package/src/hooks/index.ts +1 -1
  178. package/src/hooks/matchers.ts +2 -2
  179. package/src/hooks/types.ts +1 -1
  180. package/src/index.ts +0 -6
  181. package/src/llm/anthropic/utils/message_inputs.ts +1 -10
  182. package/src/llm/bedrock/__tests__/bedrock-caching.test.ts +18 -166
  183. package/src/llm/bedrock/index.ts +41 -116
  184. package/src/llm/openai/index.ts +2 -2
  185. package/src/llm/openai/utils/index.ts +14 -31
  186. package/src/memory/citations.ts +4 -4
  187. package/src/memory/constants.ts +17 -17
  188. package/src/memory/mmr.ts +3 -3
  189. package/src/memory/paths.ts +1 -1
  190. package/src/memory/recallTracking.ts +3 -3
  191. package/src/memory/temporalDecay.ts +2 -2
  192. package/src/memory/types.ts +3 -3
  193. package/src/messages/cache.test.ts +24 -62
  194. package/src/messages/cache.ts +0 -112
  195. package/src/messages/ensureThinkingBlock.test.ts +1 -1
  196. package/src/messages/format.ts +13 -92
  197. package/src/messages/formatAgentMessages.test.ts +1 -1
  198. package/src/scripts/subagent-configurable-inheritance.ts +263 -0
  199. package/src/scripts/subagent-event-driven-debug.ts +2 -2
  200. package/src/specs/anthropic.simple.test.ts +0 -61
  201. package/src/specs/prune.orphans.test.ts +1 -1
  202. package/src/tools/BashExecutor.ts +13 -37
  203. package/src/tools/CodeExecutor.ts +14 -59
  204. package/src/tools/ProgrammaticToolCalling.ts +14 -29
  205. package/src/tools/ToolNode.ts +75 -14
  206. package/src/tools/__tests__/CodeExecutor.test.ts +3 -3
  207. package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +0 -60
  208. package/src/tools/__tests__/SubagentExecutor.test.ts +157 -0
  209. package/src/tools/memory/memoryAppendTool.ts +1 -1
  210. package/src/tools/memory/memoryGetTool.ts +2 -2
  211. package/src/tools/memory/memorySearchTool.ts +3 -3
  212. package/src/tools/memory/shared.ts +1 -1
  213. package/src/tools/search/output.md +2775 -0
  214. package/src/tools/search/search.ts +2 -12
  215. package/src/tools/search/test.html +884 -0
  216. package/src/tools/search/test.md +643 -0
  217. package/src/tools/search/test.ts +159 -0
  218. package/src/tools/search/tool.ts +2 -36
  219. package/src/tools/search/types.ts +8 -133
  220. package/src/tools/search/utils.ts +5 -13
  221. package/src/tools/subagent/SubagentExecutor.ts +78 -0
  222. package/src/types/graph.ts +27 -34
  223. package/src/types/index.ts +0 -1
  224. package/src/types/messages.ts +1 -1
  225. package/src/types/run.ts +1 -3
  226. package/src/types/tools.ts +5 -14
  227. package/dist/cjs/langchain/google-common.cjs +0 -3
  228. package/dist/cjs/langchain/google-common.cjs.map +0 -1
  229. package/dist/cjs/langchain/index.cjs +0 -86
  230. package/dist/cjs/langchain/index.cjs.map +0 -1
  231. package/dist/cjs/langchain/language_models/chat_models.cjs +0 -3
  232. package/dist/cjs/langchain/language_models/chat_models.cjs.map +0 -1
  233. package/dist/cjs/langchain/messages/tool.cjs +0 -3
  234. package/dist/cjs/langchain/messages/tool.cjs.map +0 -1
  235. package/dist/cjs/langchain/messages.cjs +0 -51
  236. package/dist/cjs/langchain/messages.cjs.map +0 -1
  237. package/dist/cjs/langchain/openai.cjs +0 -3
  238. package/dist/cjs/langchain/openai.cjs.map +0 -1
  239. package/dist/cjs/langchain/prompts.cjs +0 -11
  240. package/dist/cjs/langchain/prompts.cjs.map +0 -1
  241. package/dist/cjs/langchain/runnables.cjs +0 -19
  242. package/dist/cjs/langchain/runnables.cjs.map +0 -1
  243. package/dist/cjs/langchain/tools.cjs +0 -23
  244. package/dist/cjs/langchain/tools.cjs.map +0 -1
  245. package/dist/cjs/langchain/utils/env.cjs +0 -11
  246. package/dist/cjs/langchain/utils/env.cjs.map +0 -1
  247. package/dist/cjs/llm/bedrock/cacheSupport.cjs +0 -55
  248. package/dist/cjs/llm/bedrock/cacheSupport.cjs.map +0 -1
  249. package/dist/cjs/tools/search/tavily-scraper.cjs +0 -189
  250. package/dist/cjs/tools/search/tavily-scraper.cjs.map +0 -1
  251. package/dist/cjs/tools/search/tavily-search.cjs +0 -372
  252. package/dist/cjs/tools/search/tavily-search.cjs.map +0 -1
  253. package/dist/cjs/types/agent-cache.cjs +0 -54
  254. package/dist/cjs/types/agent-cache.cjs.map +0 -1
  255. package/dist/esm/langchain/google-common.mjs +0 -2
  256. package/dist/esm/langchain/google-common.mjs.map +0 -1
  257. package/dist/esm/langchain/index.mjs +0 -5
  258. package/dist/esm/langchain/index.mjs.map +0 -1
  259. package/dist/esm/langchain/language_models/chat_models.mjs +0 -2
  260. package/dist/esm/langchain/language_models/chat_models.mjs.map +0 -1
  261. package/dist/esm/langchain/messages/tool.mjs +0 -2
  262. package/dist/esm/langchain/messages/tool.mjs.map +0 -1
  263. package/dist/esm/langchain/messages.mjs +0 -2
  264. package/dist/esm/langchain/messages.mjs.map +0 -1
  265. package/dist/esm/langchain/openai.mjs +0 -2
  266. package/dist/esm/langchain/openai.mjs.map +0 -1
  267. package/dist/esm/langchain/prompts.mjs +0 -2
  268. package/dist/esm/langchain/prompts.mjs.map +0 -1
  269. package/dist/esm/langchain/runnables.mjs +0 -2
  270. package/dist/esm/langchain/runnables.mjs.map +0 -1
  271. package/dist/esm/langchain/tools.mjs +0 -2
  272. package/dist/esm/langchain/tools.mjs.map +0 -1
  273. package/dist/esm/langchain/utils/env.mjs +0 -2
  274. package/dist/esm/langchain/utils/env.mjs.map +0 -1
  275. package/dist/esm/llm/bedrock/cacheSupport.mjs +0 -52
  276. package/dist/esm/llm/bedrock/cacheSupport.mjs.map +0 -1
  277. package/dist/esm/tools/search/tavily-scraper.mjs +0 -186
  278. package/dist/esm/tools/search/tavily-scraper.mjs.map +0 -1
  279. package/dist/esm/tools/search/tavily-search.mjs +0 -370
  280. package/dist/esm/tools/search/tavily-search.mjs.map +0 -1
  281. package/dist/esm/types/agent-cache.mjs +0 -52
  282. package/dist/esm/types/agent-cache.mjs.map +0 -1
  283. package/dist/types/langchain/google-common.d.ts +0 -1
  284. package/dist/types/langchain/index.d.ts +0 -8
  285. package/dist/types/langchain/language_models/chat_models.d.ts +0 -1
  286. package/dist/types/langchain/messages/tool.d.ts +0 -1
  287. package/dist/types/langchain/messages.d.ts +0 -2
  288. package/dist/types/langchain/openai.d.ts +0 -1
  289. package/dist/types/langchain/prompts.d.ts +0 -1
  290. package/dist/types/langchain/runnables.d.ts +0 -2
  291. package/dist/types/langchain/tools.d.ts +0 -2
  292. package/dist/types/langchain/utils/env.d.ts +0 -1
  293. package/dist/types/llm/bedrock/cacheSupport.d.ts +0 -35
  294. package/dist/types/tools/search/tavily-scraper.d.ts +0 -19
  295. package/dist/types/tools/search/tavily-search.d.ts +0 -4
  296. package/dist/types/tools/subagent/types.d.ts +0 -84
  297. package/dist/types/types/agent-cache.d.ts +0 -71
  298. package/src/agents/__tests__/AgentContext.cacheTtl.live.test.ts +0 -259
  299. package/src/agents/__tests__/AgentContext.crossAgentTier1.live.test.ts +0 -266
  300. package/src/agents/__tests__/AgentContext.crossUserCache.live.test.ts +0 -342
  301. package/src/langchain/google-common.ts +0 -1
  302. package/src/langchain/index.ts +0 -8
  303. package/src/langchain/language_models/chat_models.ts +0 -1
  304. package/src/langchain/messages/tool.ts +0 -5
  305. package/src/langchain/messages.ts +0 -21
  306. package/src/langchain/openai.ts +0 -1
  307. package/src/langchain/prompts.ts +0 -1
  308. package/src/langchain/runnables.ts +0 -7
  309. package/src/langchain/tools.ts +0 -8
  310. package/src/langchain/utils/env.ts +0 -1
  311. package/src/llm/anthropic/utils/server-tool-inputs.test.ts +0 -436
  312. package/src/llm/bedrock/cacheSupport.test.ts +0 -99
  313. package/src/llm/bedrock/cacheSupport.ts +0 -53
  314. package/src/tools/search/tavily-scraper.ts +0 -235
  315. package/src/tools/search/tavily-search.ts +0 -424
  316. package/src/tools/search/tavily.test.ts +0 -965
  317. package/src/tools/subagent/types.test.ts +0 -70
  318. package/src/tools/subagent/types.ts +0 -115
  319. package/src/types/agent-cache.ts +0 -74
@@ -12,8 +12,6 @@ import type * as t from '@/types';
12
12
  import type { createPruneMessages } from '@/messages';
13
13
  import { createSchemaOnlyTools } from '@/tools/schema';
14
14
  import { ContentTypes, Providers } from '@/common';
15
- import { MAX_SYSTEM_CACHE_BLOCKS } from '@/types/agent-cache';
16
- import { isBedrockCacheSupported } from '@/llm/bedrock/cacheSupport';
17
15
  import { toJsonSchema } from '@/utils/schema';
18
16
 
19
17
  /**
@@ -39,9 +37,7 @@ export class AgentContext {
39
37
  toolEnd,
40
38
  toolRegistry,
41
39
  toolDefinitions,
42
- system_cache_blocks,
43
40
  instructions,
44
- instructions_cache_ttl,
45
41
  additional_instructions,
46
42
  streamBuffer,
47
43
  maxContextTokens,
@@ -56,6 +52,8 @@ export class AgentContext {
56
52
  persistedSummary,
57
53
  summarizationConfig,
58
54
  fileManifest,
55
+ system_cache_blocks,
56
+ instructions_cache_ttl,
59
57
  } = agentConfig;
60
58
 
61
59
  // Normalize structured output: support both camelCase and snake_case inputs
@@ -89,9 +87,7 @@ export class AgentContext {
89
87
  toolMap,
90
88
  toolRegistry,
91
89
  toolDefinitions,
92
- systemCacheBlocks: system_cache_blocks,
93
90
  instructions,
94
- instructionsCacheTtl: instructions_cache_ttl,
95
91
  additionalInstructions: additional_instructions,
96
92
  reasoningKey,
97
93
  toolEnd,
@@ -105,10 +101,12 @@ export class AgentContext {
105
101
  persistedSummary,
106
102
  summarizationConfig,
107
103
  fileManifest,
104
+ systemCacheBlocks: system_cache_blocks,
105
+ instructionsCacheTtl: instructions_cache_ttl,
108
106
  });
109
107
 
110
108
  /**
111
- * Track subagent inputs on the context. `_sourceInputs`
109
+ * Track upstream-aligned subagent inputs on the context. `_sourceInputs`
112
110
  * preserves the original AgentInputs so SubagentExecutor can self-spawn
113
111
  * (`SubagentConfig.self === true`) without separate config; the other
114
112
  * two flow straight from agentConfig.
@@ -189,18 +187,9 @@ export class AgentContext {
189
187
  toolDefinitions?: t.LCTool[];
190
188
  /** Set of tool names discovered via tool search (to be loaded) */
191
189
  discoveredToolNames: Set<string> = new Set();
192
- /**
193
- * Cacheable system content blocks emitted before `instructions`. Each
194
- * gets its own cache marker (cachePoint on Bedrock, cache_control on
195
- * Anthropic). Earlier entries = wider cache key (best for cross-tenant
196
- * sharing). See `src/types/agent-cache.ts`.
197
- */
198
- systemCacheBlocks?: t.SystemCacheBlock[];
199
- /** Stable/cacheable instructions for this agent (gets trailing marker). */
190
+ /** Instructions for this agent */
200
191
  instructions?: string;
201
- /** TTL for the trailing instructions cache marker. Defaults to '5m'. */
202
- instructionsCacheTtl?: t.AgentCacheTTL;
203
- /** Dynamic system tail (per-user / per-message — never cached). */
192
+ /** Additional instructions for this agent */
204
193
  additionalInstructions?: string;
205
194
  /**
206
195
  * Dynamic context that changes per-request (e.g., current time, user info).
@@ -279,6 +268,15 @@ export class AgentContext {
279
268
  summarizationConfig?: t.SummarizationConfig;
280
269
  /** Lightweight file manifest for file-aware compaction (IDs and names only, no content) */
281
270
  fileManifest?: t.FileManifestEntry[];
271
+ /**
272
+ * Workspace-shared system-message tiers. When set, each entry becomes a
273
+ * separate text block in the SystemMessage with its own cachePoint /
274
+ * cache_control marker, BEFORE the per-agent `instructions` block.
275
+ * See {@link t.AgentInputs.system_cache_blocks} for full semantics.
276
+ */
277
+ systemCacheBlocks?: Array<{ text: string; ttl?: '5m' | '1h' }>;
278
+ /** TTL hint for the per-agent instructions cache marker. Defaults to '5m'. */
279
+ instructionsCacheTtl?: '5m' | '1h';
282
280
  /** Original AgentInputs used to create this context — used for self-spawn subagent resolution. */
283
281
  _sourceInputs?: t.AgentInputs;
284
282
  /** Subagent configurations for hierarchical delegation. */
@@ -299,9 +297,7 @@ export class AgentContext {
299
297
  toolMap,
300
298
  toolRegistry,
301
299
  toolDefinitions,
302
- systemCacheBlocks,
303
300
  instructions,
304
- instructionsCacheTtl,
305
301
  additionalInstructions,
306
302
  dynamicContext,
307
303
  reasoningKey,
@@ -314,6 +310,8 @@ export class AgentContext {
314
310
  persistedSummary,
315
311
  summarizationConfig,
316
312
  fileManifest,
313
+ systemCacheBlocks,
314
+ instructionsCacheTtl,
317
315
  }: {
318
316
  agentId: string;
319
317
  name?: string;
@@ -327,9 +325,7 @@ export class AgentContext {
327
325
  toolMap?: t.ToolMap;
328
326
  toolRegistry?: t.LCToolRegistry;
329
327
  toolDefinitions?: t.LCTool[];
330
- systemCacheBlocks?: t.SystemCacheBlock[];
331
328
  instructions?: string;
332
- instructionsCacheTtl?: t.AgentCacheTTL;
333
329
  additionalInstructions?: string;
334
330
  dynamicContext?: string;
335
331
  reasoningKey?: 'reasoning_content' | 'reasoning';
@@ -344,6 +340,8 @@ export class AgentContext {
344
340
  persistedSummary?: string;
345
341
  summarizationConfig?: t.SummarizationConfig;
346
342
  fileManifest?: t.FileManifestEntry[];
343
+ systemCacheBlocks?: Array<{ text: string; ttl?: '5m' | '1h' }>;
344
+ instructionsCacheTtl?: '5m' | '1h';
347
345
  }) {
348
346
  this.agentId = agentId;
349
347
  this.name = name;
@@ -357,20 +355,7 @@ export class AgentContext {
357
355
  this.toolMap = toolMap;
358
356
  this.toolRegistry = toolRegistry;
359
357
  this.toolDefinitions = toolDefinitions;
360
- if (
361
- systemCacheBlocks &&
362
- systemCacheBlocks.length > MAX_SYSTEM_CACHE_BLOCKS
363
- ) {
364
- throw new Error(
365
- `system_cache_blocks supports at most ${MAX_SYSTEM_CACHE_BLOCKS} entries ` +
366
- `(received ${systemCacheBlocks.length}); excess entries would exceed ` +
367
- `Bedrock's 4-cachePoint per-request budget once the tools array and ` +
368
- `trailing 'instructions' marker are counted. See src/types/agent-cache.ts.`,
369
- );
370
- }
371
- this.systemCacheBlocks = systemCacheBlocks;
372
358
  this.instructions = instructions;
373
- this.instructionsCacheTtl = instructionsCacheTtl;
374
359
  this.additionalInstructions = additionalInstructions;
375
360
  this.dynamicContext = dynamicContext;
376
361
  this.structuredOutput = structuredOutput;
@@ -378,6 +363,12 @@ export class AgentContext {
378
363
  this.persistedSummary = persistedSummary;
379
364
  this.summarizationConfig = summarizationConfig;
380
365
  this.fileManifest = fileManifest;
366
+ if (systemCacheBlocks && systemCacheBlocks.length > 0) {
367
+ this.systemCacheBlocks = systemCacheBlocks;
368
+ }
369
+ if (instructionsCacheTtl) {
370
+ this.instructionsCacheTtl = instructionsCacheTtl;
371
+ }
381
372
  if (reasoningKey) {
382
373
  this.reasoningKey = reasoningKey;
383
374
  }
@@ -605,11 +596,8 @@ export class AgentContext {
605
596
  }
606
597
 
607
598
  // Stale or first access - rebuild
608
- this.cachedSystemRunnable = this.buildSystemRunnable({
609
- systemCacheBlocks: this.systemCacheBlocks ?? [],
610
- stableInstructions: this.buildStableInstructionsString(),
611
- dynamicInstructions: this.buildDynamicInstructionsString(),
612
- });
599
+ const instructionsString = this.buildInstructionsString();
600
+ this.cachedSystemRunnable = this.buildSystemRunnable(instructionsString);
613
601
  this.systemRunnableStale = false;
614
602
  return this.cachedSystemRunnable;
615
603
  }
@@ -620,27 +608,17 @@ export class AgentContext {
620
608
  */
621
609
  initializeSystemRunnable(): void {
622
610
  if (this.systemRunnableStale || this.cachedSystemRunnable === undefined) {
623
- this.cachedSystemRunnable = this.buildSystemRunnable({
624
- systemCacheBlocks: this.systemCacheBlocks ?? [],
625
- stableInstructions: this.buildStableInstructionsString(),
626
- dynamicInstructions: this.buildDynamicInstructionsString(),
627
- });
611
+ const instructionsString = this.buildInstructionsString();
612
+ this.cachedSystemRunnable = this.buildSystemRunnable(instructionsString);
628
613
  this.systemRunnableStale = false;
629
614
  }
630
615
  }
631
616
 
632
617
  /**
633
- * Builds the cacheable instructions string (without creating SystemMessage).
634
- * Includes agent identity preamble, the agent's static instructions, and
635
- * programmatic-only tool documentation. This is the part of the system
636
- * message that stays byte-stable across turns and across users for the
637
- * same agent — the prompt cache prefix.
638
- *
639
- * Per-user/per-message dynamic context belongs in
640
- * `buildDynamicInstructionsString()` so it does not invalidate the cache
641
- * marker. (See `feedback_cache_stability_invariant` for the rule.)
618
+ * Builds the raw instructions string (without creating SystemMessage).
619
+ * Includes agent identity preamble and handoff context when available.
642
620
  */
643
- private buildStableInstructionsString(): string {
621
+ private buildInstructionsString(): string {
644
622
  const parts: string[] = [];
645
623
 
646
624
  /** Build agent identity and handoff context preamble */
@@ -654,27 +632,7 @@ export class AgentContext {
654
632
  parts.push(this.instructions);
655
633
  }
656
634
 
657
- /** Add programmatic tools documentation */
658
- const programmaticToolsDoc = this.buildProgrammaticOnlyToolsInstructions();
659
- if (programmaticToolsDoc) {
660
- parts.push(programmaticToolsDoc);
661
- }
662
-
663
- return parts.join('\n\n');
664
- }
665
-
666
- /**
667
- * Builds the dynamic system-tail string (without creating SystemMessage).
668
- * Keep this out of prompt-cache-marked content so volatile per-call
669
- * context does not invalidate the stable prefix.
670
- *
671
- * `additional_instructions` is treated as dynamic (per-user/per-message
672
- * memory, runtime context, etc.) and intentionally excluded from the
673
- * cacheable prefix.
674
- */
675
- private buildDynamicInstructionsString(): string {
676
- const parts: string[] = [];
677
-
635
+ /** Add additional instructions */
678
636
  if (
679
637
  this.additionalInstructions != null &&
680
638
  this.additionalInstructions !== ''
@@ -682,6 +640,12 @@ export class AgentContext {
682
640
  parts.push(this.additionalInstructions);
683
641
  }
684
642
 
643
+ /** Add programmatic tools documentation */
644
+ const programmaticToolsDoc = this.buildProgrammaticOnlyToolsInstructions();
645
+ if (programmaticToolsDoc) {
646
+ parts.push(programmaticToolsDoc);
647
+ }
648
+
685
649
  return parts.join('\n\n');
686
650
  }
687
651
 
@@ -737,168 +701,121 @@ export class AgentContext {
737
701
  }
738
702
 
739
703
  /**
740
- * True when Anthropic prompt caching is enabled for this agent.
741
- * Used by `buildSystemRunnable` to decide whether to emit a cache_control
742
- * marker on the stable instructions prefix.
743
- */
744
- private hasAnthropicPromptCache(): boolean {
745
- if (this.provider !== Providers.ANTHROPIC) {
746
- return false;
747
- }
748
- const anthropicOptions = this.clientOptions as
749
- | t.AnthropicClientOptions
750
- | undefined;
751
- return anthropicOptions?.promptCache === true;
752
- }
753
-
754
- /**
755
- * True when Bedrock prompt caching is enabled for this agent AND the
756
- * configured model supports `cachePoint` blocks. Only Claude (and Nova)
757
- * models on Bedrock honour cachePoint — Llama / Titan reject it.
758
- *
759
- * Used by `buildSystemRunnable` to inline a `cachePoint` block right
760
- * after the stable system text so the system prefix is cached at the
761
- * AWS account level (cross-user, cross-conversation).
704
+ * Build system runnable from pre-built instructions string.
705
+ * Only called when content has actually changed.
762
706
  */
763
- private hasBedrockPromptCache(): boolean {
764
- if (this.provider !== Providers.BEDROCK) {
765
- return false;
766
- }
767
- const bedrockOptions = this.clientOptions as
768
- | (t.BedrockAnthropicClientOptions & {
769
- model?: string;
770
- bedrockCacheModelPatterns?: readonly RegExp[];
771
- })
772
- | undefined;
773
- if (bedrockOptions?.promptCache !== true) {
774
- return false;
775
- }
776
- /* Allowlist-based check (see src/llm/bedrock/cacheSupport.ts). The
777
- * `bedrockCacheModelPatterns` clientOption lets consumers add new
778
- * model patterns without forking the library — useful when AWS adds
779
- * a new family before the next library release. */
780
- return isBedrockCacheSupported(
781
- bedrockOptions.model,
782
- bedrockOptions.bedrockCacheModelPatterns,
783
- );
784
- }
785
-
786
- /**
787
- * Build system runnable from cacheable blocks + the trailing
788
- * `instructions` block + optional dynamic tail.
789
- *
790
- * ┌──────────────────────────────────────────┐
791
- * │ system_cache_blocks[0].text │ ← consumer-defined block 0
792
- * ├──── cache marker (TTL = blocks[0].ttl) ──┤
793
- * │ system_cache_blocks[1].text │ ← consumer-defined block 1
794
- * ├──── cache marker (TTL = blocks[1].ttl) ──┤
795
- * │ instructions │ ← per-agent stable
796
- * ├──── cache marker (TTL = instructionsCacheTtl) ┤
797
- * │ additional_instructions │ ← dynamic (uncached)
798
- * └──────────────────────────────────────────┘
799
- *
800
- * If `system_cache_blocks` is empty, behavior reduces to the 2-tier
801
- * (instructions + dynamic) path used by simpler consumers.
802
- *
803
- * Provider-specific cache marker:
804
- * - Anthropic: `cache_control: { type: 'ephemeral', ttl?: '1h'|'5m' }` on
805
- * each cacheable text block. Up to 4 cache breakpoints per workspace.
806
- * - Bedrock (Claude/Nova): a `{ cachePoint: { type: 'default', ttl?: '1h'|'5m' } }`
807
- * block inserted after each cacheable section. Up to 4 cachePoints per
808
- * request, of which the tools array can consume up to 2.
809
- *
810
- * Cache key composition: every byte from message start to a given cache
811
- * marker forms that marker's cache key. Earlier blocks = wider cache key
812
- * = more cross-tenant share. Place the most stable content first.
813
- */
814
- private buildSystemRunnable({
815
- systemCacheBlocks,
816
- stableInstructions,
817
- dynamicInstructions,
818
- }: {
819
- systemCacheBlocks: t.SystemCacheBlock[];
820
- stableInstructions: string;
821
- dynamicInstructions: string;
822
- }):
707
+ private buildSystemRunnable(
708
+ instructionsString: string
709
+ ):
823
710
  | Runnable<
824
711
  BaseMessage[],
825
712
  (BaseMessage | SystemMessage)[],
826
713
  RunnableConfig<Record<string, unknown>>
827
714
  >
828
715
  | undefined {
829
- const hasAnyCacheBlocks = systemCacheBlocks.length > 0;
830
- if (!hasAnyCacheBlocks && !stableInstructions && !dynamicInstructions) {
716
+ if (!instructionsString) {
831
717
  // Remove previous tokens if we had a system message before
832
718
  this.instructionTokens -= this.systemMessageTokens;
833
719
  this.systemMessageTokens = 0;
834
720
  return undefined;
835
721
  }
836
722
 
837
- const useAnthropicCache = this.hasAnthropicPromptCache();
838
- const useBedrockCache = this.hasBedrockPromptCache();
839
- const instructionsTtl: t.AgentCacheTTL = this.instructionsCacheTtl ?? '5m';
723
+ let finalInstructions: string | BaseMessageFields = instructionsString;
840
724
 
841
- let finalInstructions: string | BaseMessageFields;
842
- if (useAnthropicCache) {
843
- type AnthropicTextBlock = {
844
- type: 'text';
845
- text: string;
846
- cache_control?: { type: 'ephemeral'; ttl?: t.AgentCacheTTL };
847
- };
848
- const content: AnthropicTextBlock[] = [];
849
- // Emit each system_cache_blocks entry with its own cache_control.
850
- for (const block of systemCacheBlocks) {
851
- if (!block.text) continue;
852
- content.push({
853
- type: 'text',
854
- text: block.text,
855
- cache_control: { type: 'ephemeral', ttl: block.ttl ?? '5m' },
856
- });
857
- }
858
- // Trailing stable instructions block (also cacheable).
859
- if (stableInstructions) {
860
- content.push({
861
- type: 'text',
862
- text: stableInstructions,
863
- cache_control: { type: 'ephemeral', ttl: instructionsTtl },
864
- });
865
- }
866
- if (dynamicInstructions) {
867
- // Dynamic tail: NO cache_control so it doesn't shift the cache prefix.
868
- content.push({ type: 'text', text: dynamicInstructions });
869
- }
870
- finalInstructions = { content } as BaseMessageFields;
871
- } else if (useBedrockCache && (hasAnyCacheBlocks || stableInstructions)) {
872
- type BedrockBlock =
873
- | { type: 'text'; text: string }
874
- | { cachePoint: { type: 'default'; ttl?: t.AgentCacheTTL } };
875
- const content: BedrockBlock[] = [];
876
- // Emit each system_cache_blocks entry as text + cachePoint pair.
877
- for (const block of systemCacheBlocks) {
878
- if (!block.text) continue;
879
- content.push({ type: 'text', text: block.text });
880
- content.push({
881
- cachePoint: { type: 'default', ttl: block.ttl ?? '5m' },
882
- });
883
- }
884
- if (stableInstructions) {
885
- content.push({ type: 'text', text: stableInstructions });
886
- content.push({
887
- cachePoint: { type: 'default', ttl: instructionsTtl },
888
- });
889
- }
890
- if (dynamicInstructions) {
891
- content.push({ type: 'text', text: dynamicInstructions });
725
+ /**
726
+ * Tiered system-message assembly. When `systemCacheBlocks` is set, build
727
+ * a multi-block SystemMessage so each tier has its own cache breakpoint:
728
+ *
729
+ * [tier1_block_1][tier1_cachePoint]...[tier1_block_N][tier1_cachePoint]
730
+ * [instructions][instructions_cachePoint]
731
+ *
732
+ * Forward-prefix-hash means agents in the same workspace whose tier-1
733
+ * bytes are identical share the platform cache entry; only the per-agent
734
+ * `instructions` block invalidates per-agent.
735
+ *
736
+ * - Bedrock: emit `cachePoint: { type: 'default' }` blocks (handled by
737
+ * `convertSystemMessageToConverseMessage`).
738
+ * - Anthropic: emit `cache_control: { type: 'ephemeral' }` on each text
739
+ * block. (TTL hints are dropped for Anthropic the SDK currently
740
+ * only supports `'ephemeral'`. Bedrock cachePoint has no TTL knob.)
741
+ */
742
+ const hasTieredCache =
743
+ Array.isArray(this.systemCacheBlocks) &&
744
+ this.systemCacheBlocks.length > 0;
745
+ const isBedrock = this.provider === Providers.BEDROCK;
746
+ const isAnthropic = this.provider === Providers.ANTHROPIC;
747
+ const anthropicCacheEnabled =
748
+ isAnthropic &&
749
+ (this.clientOptions as t.AnthropicClientOptions | undefined)
750
+ ?.promptCache === true;
751
+ /**
752
+ * Bedrock cachePoint is Claude-only — Nova/Llama/Titan reject it.
753
+ * Mirrors the model check in `IllumaBedrockConverse.invocationParams`
754
+ * (src/llm/bedrock/index.ts:186-189).
755
+ */
756
+ const bedrockCacheEnabled =
757
+ isBedrock &&
758
+ (() => {
759
+ const opts = this.clientOptions as
760
+ | (t.BedrockAnthropicClientOptions & { model?: string })
761
+ | undefined;
762
+ const modelId = (opts?.model ?? '').toLowerCase();
763
+ const isClaudeModel =
764
+ modelId.includes('claude') || modelId.includes('anthropic');
765
+ return opts?.promptCache === true && isClaudeModel;
766
+ })();
767
+
768
+ if (hasTieredCache && (bedrockCacheEnabled || anthropicCacheEnabled)) {
769
+ /**
770
+ * Anthropic / Bedrock cap cache breakpoints at 4 per request. The
771
+ * lib already emits one for tools and up to two for messages, so we
772
+ * have at most 1 left for the system block. We spend it on Tier 1
773
+ * (the workspace-shared bytes) — per-agent Tier 2 caching is still
774
+ * achieved implicitly via the tools breakpoint that follows, since
775
+ * cache lookups are forward-prefix-hash.
776
+ *
777
+ * Tier 1 may itself be emitted as multiple text blocks (one per
778
+ * `systemCacheBlocks` entry); only the LAST gets the cache marker,
779
+ * the rest are plain text inside the same cached prefix.
780
+ */
781
+ const contentBlocks: Array<Record<string, unknown>> = [];
782
+ const tier1Blocks = this.systemCacheBlocks!.filter((b) => b?.text);
783
+ tier1Blocks.forEach((block, idx) => {
784
+ const isLast = idx === tier1Blocks.length - 1;
785
+ if (bedrockCacheEnabled) {
786
+ contentBlocks.push({ type: 'text', text: block.text });
787
+ if (isLast) {
788
+ contentBlocks.push({ cachePoint: { type: 'default' } });
789
+ }
790
+ } else if (isLast) {
791
+ contentBlocks.push({
792
+ type: 'text',
793
+ text: block.text,
794
+ cache_control: { type: 'ephemeral' },
795
+ });
796
+ } else {
797
+ contentBlocks.push({ type: 'text', text: block.text });
798
+ }
799
+ });
800
+ if (instructionsString) {
801
+ // No cache marker on the trailing per-agent block — tools'
802
+ // breakpoint covers it.
803
+ contentBlocks.push({ type: 'text', text: instructionsString });
892
804
  }
893
- finalInstructions = { content } as unknown as BaseMessageFields;
894
- } else {
895
- finalInstructions = [
896
- ...systemCacheBlocks.map((b) => b.text),
897
- stableInstructions,
898
- dynamicInstructions,
899
- ]
900
- .filter((part) => part !== '')
901
- .join('\n\n');
805
+ finalInstructions = {
806
+ content: contentBlocks as unknown as BaseMessageFields['content'],
807
+ };
808
+ } else if (anthropicCacheEnabled) {
809
+ // Legacy single-block Anthropic caching (preserved for back-compat).
810
+ finalInstructions = {
811
+ content: [
812
+ {
813
+ type: 'text',
814
+ text: instructionsString,
815
+ cache_control: { type: 'ephemeral' },
816
+ },
817
+ ],
818
+ };
902
819
  }
903
820
 
904
821
  const systemMessage = new SystemMessage(finalInstructions);
@@ -974,49 +891,6 @@ export class AgentContext {
974
891
  }
975
892
  }
976
893
 
977
- /** Active tool definitions for token accounting (excludes deferred-and-undiscovered entries
978
- * and definitions whose `allowed_callers` exclude `'direct'`). Mirrors the gate
979
- * `getEventDrivenToolsForBinding` applies so accounting and binding stay aligned. */
980
- private getActiveToolDefinitions(): t.LCTool[] {
981
- if (!this.toolDefinitions) {
982
- return [];
983
- }
984
- return this.toolDefinitions.filter((def) => {
985
- const allowedCallers = def.allowed_callers ?? ['direct'];
986
- if (!allowedCallers.includes('direct')) {
987
- return false;
988
- }
989
- return (
990
- def.defer_loading !== true || this.discoveredToolNames.has(def.name)
991
- );
992
- });
993
- }
994
-
995
- /**
996
- * Single source of truth for "which entries of `this.tools` should be
997
- * treated as actually bound". Callers:
998
- * - `getToolsForBinding` (non-event-driven branch)
999
- * - `getEventDrivenToolsForBinding` (appends instance tools alongside
1000
- * schema-only definitions)
1001
- * - `calculateInstructionTokens` (counts schema bytes for accounting)
1002
- *
1003
- * In event-driven mode (`toolDefinitions` present) instance tools are
1004
- * appended unfiltered; outside event-driven mode they pass through
1005
- * `filterToolsForBinding`. Centralizing the decision here prevents the
1006
- * accounting/binding paths from drifting apart, which was the root
1007
- * cause of the original miscount (Fixes #121).
1008
- */
1009
- private getEffectiveInstanceTools(): t.GraphTools | undefined {
1010
- if (!this.tools) {
1011
- return undefined;
1012
- }
1013
- const isEventDriven = (this.toolDefinitions?.length ?? 0) > 0;
1014
- if (isEventDriven || !this.toolRegistry) {
1015
- return this.tools;
1016
- }
1017
- return this.filterToolsForBinding(this.tools);
1018
- }
1019
-
1020
894
  /**
1021
895
  * Calculate tool tokens and add to instruction tokens
1022
896
  * Note: System message tokens are calculated during systemRunnable creation
@@ -1034,17 +908,9 @@ export class AgentContext {
1034
908
  // Reset per-tool breakdown
1035
909
  this.toolsDetail = [];
1036
910
 
1037
- /* Use `getEffectiveInstanceTools()` so accounting reflects exactly the
1038
- * subset that `getToolsForBinding` would emit — preventing the
1039
- * worst-case-ceiling miscount that triggered spurious `empty_messages`
1040
- * preflight rejections at low `maxContextTokens`. Deferred and
1041
- * non-`'direct'` `toolDefinitions` are excluded by
1042
- * `getActiveToolDefinitions()` below. */
1043
- const effectiveInstanceTools = this.getEffectiveInstanceTools();
1044
-
1045
911
  // Count tokens for bound tools (StructuredTool instances with .schema)
1046
- if (effectiveInstanceTools && effectiveInstanceTools.length > 0) {
1047
- for (const tool of effectiveInstanceTools) {
912
+ if (this.tools && this.tools.length > 0) {
913
+ for (const tool of this.tools) {
1048
914
  const genericTool = tool as Record<string, unknown>;
1049
915
  if (
1050
916
  genericTool.schema != null &&
@@ -1073,27 +939,25 @@ export class AgentContext {
1073
939
  // Count tokens for tool definitions (MCP / event-driven tools).
1074
940
  // These are sent to the provider API as tool schemas alongside bound tools.
1075
941
  // Both can be populated simultaneously (graph tools + MCP tools).
1076
- // Use `getActiveToolDefinitions()` so programmatic-only definitions
1077
- // (e.g. `allowed_callers: ['code_execution']`) and deferred-and-
1078
- // -undiscovered ones don't inflate `toolSchemaTokens` while never
1079
- // being bound to the model.
1080
- for (const def of this.getActiveToolDefinitions()) {
1081
- if (countedToolNames.has(def.name)) {
1082
- continue; // Already counted via this.tools
942
+ if (this.toolDefinitions && this.toolDefinitions.length > 0) {
943
+ for (const def of this.toolDefinitions) {
944
+ if (countedToolNames.has(def.name)) {
945
+ continue; // Already counted via this.tools
946
+ }
947
+ const schema = {
948
+ name: def.name,
949
+ description: def.description ?? '',
950
+ parameters: def.parameters ?? {},
951
+ };
952
+ const defTokens = tokenCounter(
953
+ new SystemMessage(JSON.stringify(schema))
954
+ );
955
+ this.toolsDetail.push({
956
+ name: def.name || 'unknown',
957
+ tokens: defTokens,
958
+ });
959
+ toolTokens += defTokens;
1083
960
  }
1084
- const schema = {
1085
- name: def.name,
1086
- description: def.description ?? '',
1087
- parameters: def.parameters ?? {},
1088
- };
1089
- const defTokens = tokenCounter(
1090
- new SystemMessage(JSON.stringify(schema))
1091
- );
1092
- this.toolsDetail.push({
1093
- name: def.name || 'unknown',
1094
- tokens: defTokens,
1095
- });
1096
- toolTokens += defTokens;
1097
961
  }
1098
962
 
1099
963
  // Store total tool tokens for breakdown reporting
@@ -1264,7 +1128,10 @@ export class AgentContext {
1264
1128
  }
1265
1129
 
1266
1130
  /** Traditional mode: filter actual tool instances */
1267
- const filtered = this.getEffectiveInstanceTools();
1131
+ const filtered =
1132
+ !this.tools || !this.toolRegistry
1133
+ ? this.tools
1134
+ : this.filterToolsForBinding(this.tools);
1268
1135
 
1269
1136
  if (this.graphTools && this.graphTools.length > 0) {
1270
1137
  return [...(filtered ?? []), ...this.graphTools];
@@ -1279,11 +1146,21 @@ export class AgentContext {
1279
1146
  return this.graphTools ?? [];
1280
1147
  }
1281
1148
 
1282
- /* Reuse `getActiveToolDefinitions()` so the binding gate matches the
1283
- * accounting filter exactly (single source of truth). */
1284
- const schemaTools = createSchemaOnlyTools(
1285
- this.getActiveToolDefinitions()
1286
- ) as t.GraphTools;
1149
+ const defsToInclude = this.toolDefinitions.filter((def) => {
1150
+ const allowedCallers = def.allowed_callers ?? ['direct'];
1151
+ if (!allowedCallers.includes('direct')) {
1152
+ return false;
1153
+ }
1154
+ if (
1155
+ def.defer_loading === true &&
1156
+ !this.discoveredToolNames.has(def.name)
1157
+ ) {
1158
+ return false;
1159
+ }
1160
+ return true;
1161
+ });
1162
+
1163
+ const schemaTools = createSchemaOnlyTools(defsToInclude) as t.GraphTools;
1287
1164
 
1288
1165
  const allTools = [...schemaTools];
1289
1166
 
@@ -1291,9 +1168,6 @@ export class AgentContext {
1291
1168
  allTools.push(...this.graphTools);
1292
1169
  }
1293
1170
 
1294
- /* In event-driven mode, instance tools are appended UNFILTERED (matching
1295
- * `getEffectiveInstanceTools()`'s event-driven branch). Deferred /
1296
- * non-direct logic is represented in `toolDefinitions`, not here. */
1297
1171
  if (this.tools && this.tools.length > 0) {
1298
1172
  allTools.push(...this.tools);
1299
1173
  }