@code-yeongyu/senpi 2026.8.11-2 → 2026.8.11-3

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 (256) hide show
  1. package/CHANGELOG.md +66 -1
  2. package/dist/cli-main.d.ts +1 -1
  3. package/dist/cli-main.d.ts.map +1 -1
  4. package/dist/cli-main.js +1 -0
  5. package/dist/cli-main.js.map +1 -1
  6. package/dist/cli.d.ts +1 -1
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +1 -0
  9. package/dist/cli.js.map +1 -1
  10. package/dist/core/agent-session.d.ts +8 -2
  11. package/dist/core/agent-session.d.ts.map +1 -1
  12. package/dist/core/agent-session.js +63 -7
  13. package/dist/core/agent-session.js.map +1 -1
  14. package/dist/core/extensions/builtin/claude-sdk-oauth/availability.d.ts +2 -0
  15. package/dist/core/extensions/builtin/claude-sdk-oauth/availability.d.ts.map +1 -0
  16. package/dist/core/extensions/builtin/claude-sdk-oauth/availability.js +24 -0
  17. package/dist/core/extensions/builtin/claude-sdk-oauth/availability.js.map +1 -0
  18. package/dist/core/extensions/builtin/claude-sdk-oauth/index.d.ts +4 -0
  19. package/dist/core/extensions/builtin/claude-sdk-oauth/index.d.ts.map +1 -1
  20. package/dist/core/extensions/builtin/claude-sdk-oauth/index.js +5 -2
  21. package/dist/core/extensions/builtin/claude-sdk-oauth/index.js.map +1 -1
  22. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.d.ts +6 -1
  23. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.d.ts.map +1 -1
  24. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js +16 -0
  25. package/dist/core/extensions/builtin/claude-sdk-oauth/oauth-login.js.map +1 -1
  26. package/dist/core/extensions/builtin/goal/transitions.js +2 -1
  27. package/dist/core/extensions/builtin/goal/transitions.js.map +1 -1
  28. package/dist/core/extensions/builtin/imagegen/auth.d.ts +45 -0
  29. package/dist/core/extensions/builtin/imagegen/auth.d.ts.map +1 -0
  30. package/dist/core/extensions/builtin/imagegen/auth.js +137 -0
  31. package/dist/core/extensions/builtin/imagegen/auth.js.map +1 -0
  32. package/dist/core/extensions/builtin/imagegen/index.d.ts +5 -0
  33. package/dist/core/extensions/builtin/imagegen/index.d.ts.map +1 -0
  34. package/dist/core/extensions/builtin/imagegen/index.js +46 -0
  35. package/dist/core/extensions/builtin/imagegen/index.js.map +1 -0
  36. package/dist/core/extensions/builtin/imagegen/paths.d.ts +26 -0
  37. package/dist/core/extensions/builtin/imagegen/paths.d.ts.map +1 -0
  38. package/dist/core/extensions/builtin/imagegen/paths.js +52 -0
  39. package/dist/core/extensions/builtin/imagegen/paths.js.map +1 -0
  40. package/dist/core/extensions/builtin/imagegen/skill/SKILL.md +67 -0
  41. package/dist/core/extensions/builtin/imagegen/state.d.ts +26 -0
  42. package/dist/core/extensions/builtin/imagegen/state.d.ts.map +1 -0
  43. package/dist/core/extensions/builtin/imagegen/state.js +35 -0
  44. package/dist/core/extensions/builtin/imagegen/state.js.map +1 -0
  45. package/dist/core/extensions/builtin/imagegen/tool.d.ts +31 -0
  46. package/dist/core/extensions/builtin/imagegen/tool.d.ts.map +1 -0
  47. package/dist/core/extensions/builtin/imagegen/tool.js +174 -0
  48. package/dist/core/extensions/builtin/imagegen/tool.js.map +1 -0
  49. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  50. package/dist/core/extensions/builtin/index.js +9 -1
  51. package/dist/core/extensions/builtin/index.js.map +1 -1
  52. package/dist/core/extensions/builtin/mcp/control-inventory.d.ts +14 -0
  53. package/dist/core/extensions/builtin/mcp/control-inventory.d.ts.map +1 -0
  54. package/dist/core/extensions/builtin/mcp/control-inventory.js +22 -0
  55. package/dist/core/extensions/builtin/mcp/control-inventory.js.map +1 -0
  56. package/dist/core/extensions/builtin/mcp/expose/native-search.d.ts +2 -44
  57. package/dist/core/extensions/builtin/mcp/expose/native-search.d.ts.map +1 -1
  58. package/dist/core/extensions/builtin/mcp/expose/native-search.js +3 -97
  59. package/dist/core/extensions/builtin/mcp/expose/native-search.js.map +1 -1
  60. package/dist/core/extensions/builtin/mcp/expose/proxy.d.ts.map +1 -1
  61. package/dist/core/extensions/builtin/mcp/expose/proxy.js +15 -4
  62. package/dist/core/extensions/builtin/mcp/expose/proxy.js.map +1 -1
  63. package/dist/core/extensions/builtin/mcp/expose/session.d.ts +2 -1
  64. package/dist/core/extensions/builtin/mcp/expose/session.d.ts.map +1 -1
  65. package/dist/core/extensions/builtin/mcp/expose/session.js +2 -2
  66. package/dist/core/extensions/builtin/mcp/expose/session.js.map +1 -1
  67. package/dist/core/extensions/builtin/mcp/expose/tier-b.d.ts +13 -11
  68. package/dist/core/extensions/builtin/mcp/expose/tier-b.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/mcp/expose/tier-b.js +58 -59
  70. package/dist/core/extensions/builtin/mcp/expose/tier-b.js.map +1 -1
  71. package/dist/core/extensions/builtin/mcp/index.d.ts.map +1 -1
  72. package/dist/core/extensions/builtin/mcp/index.js +28 -36
  73. package/dist/core/extensions/builtin/mcp/index.js.map +1 -1
  74. package/dist/core/extensions/builtin/mcp/service-register.d.ts +2 -1
  75. package/dist/core/extensions/builtin/mcp/service-register.d.ts.map +1 -1
  76. package/dist/core/extensions/builtin/mcp/service-register.js +2 -2
  77. package/dist/core/extensions/builtin/mcp/service-register.js.map +1 -1
  78. package/dist/core/extensions/builtin/mcp/service-types.d.ts +4 -0
  79. package/dist/core/extensions/builtin/mcp/service-types.d.ts.map +1 -1
  80. package/dist/core/extensions/builtin/mcp/service-types.js.map +1 -1
  81. package/dist/core/extensions/builtin/mcp/service.d.ts +6 -11
  82. package/dist/core/extensions/builtin/mcp/service.d.ts.map +1 -1
  83. package/dist/core/extensions/builtin/mcp/service.js +79 -41
  84. package/dist/core/extensions/builtin/mcp/service.js.map +1 -1
  85. package/dist/core/extensions/builtin/mcp/wrap.d.ts +2 -0
  86. package/dist/core/extensions/builtin/mcp/wrap.d.ts.map +1 -1
  87. package/dist/core/extensions/builtin/mcp/wrap.js +3 -0
  88. package/dist/core/extensions/builtin/mcp/wrap.js.map +1 -1
  89. package/dist/core/extensions/builtin/openai-image-gen/externalize.d.ts +27 -0
  90. package/dist/core/extensions/builtin/openai-image-gen/externalize.d.ts.map +1 -0
  91. package/dist/core/extensions/builtin/openai-image-gen/externalize.js +133 -0
  92. package/dist/core/extensions/builtin/openai-image-gen/externalize.js.map +1 -0
  93. package/dist/core/extensions/builtin/openai-image-gen/gate.d.ts +21 -0
  94. package/dist/core/extensions/builtin/openai-image-gen/gate.d.ts.map +1 -0
  95. package/dist/core/extensions/builtin/openai-image-gen/gate.js +63 -0
  96. package/dist/core/extensions/builtin/openai-image-gen/gate.js.map +1 -0
  97. package/dist/core/extensions/builtin/openai-image-gen/index.d.ts +14 -0
  98. package/dist/core/extensions/builtin/openai-image-gen/index.d.ts.map +1 -0
  99. package/dist/core/extensions/builtin/openai-image-gen/index.js +77 -0
  100. package/dist/core/extensions/builtin/openai-image-gen/index.js.map +1 -0
  101. package/dist/core/extensions/builtin/openai-image-gen/inject.d.ts +15 -0
  102. package/dist/core/extensions/builtin/openai-image-gen/inject.d.ts.map +1 -0
  103. package/dist/core/extensions/builtin/openai-image-gen/inject.js +42 -0
  104. package/dist/core/extensions/builtin/openai-image-gen/inject.js.map +1 -0
  105. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -1
  106. package/dist/core/extensions/builtin/terminal/monitor-notify.js +8 -1
  107. package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -1
  108. package/dist/core/extensions/builtin/terminal/notify.d.ts +3 -1
  109. package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
  110. package/dist/core/extensions/builtin/terminal/notify.js +4 -1
  111. package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
  112. package/dist/core/extensions/builtin/tool-search/engine/bm25.d.ts +22 -0
  113. package/dist/core/extensions/builtin/tool-search/engine/bm25.d.ts.map +1 -0
  114. package/dist/core/extensions/builtin/{mcp/expose → tool-search/engine}/bm25.js +16 -31
  115. package/dist/core/extensions/builtin/tool-search/engine/bm25.js.map +1 -0
  116. package/dist/core/extensions/builtin/tool-search/engine/document.d.ts +14 -0
  117. package/dist/core/extensions/builtin/tool-search/engine/document.d.ts.map +1 -0
  118. package/dist/core/extensions/builtin/tool-search/engine/document.js +2 -0
  119. package/dist/core/extensions/builtin/tool-search/engine/document.js.map +1 -0
  120. package/dist/core/extensions/builtin/tool-search/engine/marker.d.ts +55 -0
  121. package/dist/core/extensions/builtin/tool-search/engine/marker.d.ts.map +1 -0
  122. package/dist/core/extensions/builtin/tool-search/engine/marker.js +189 -0
  123. package/dist/core/extensions/builtin/tool-search/engine/marker.js.map +1 -0
  124. package/dist/core/extensions/builtin/tool-search/index.d.ts +7 -0
  125. package/dist/core/extensions/builtin/tool-search/index.d.ts.map +1 -0
  126. package/dist/core/extensions/builtin/tool-search/index.js +71 -0
  127. package/dist/core/extensions/builtin/tool-search/index.js.map +1 -0
  128. package/dist/core/extensions/builtin/tool-search/native-search.d.ts +52 -0
  129. package/dist/core/extensions/builtin/tool-search/native-search.d.ts.map +1 -0
  130. package/dist/core/extensions/builtin/tool-search/native-search.js +116 -0
  131. package/dist/core/extensions/builtin/tool-search/native-search.js.map +1 -0
  132. package/dist/core/extensions/builtin/tool-search/service.d.ts +38 -0
  133. package/dist/core/extensions/builtin/tool-search/service.d.ts.map +1 -0
  134. package/dist/core/extensions/builtin/tool-search/service.js +200 -0
  135. package/dist/core/extensions/builtin/tool-search/service.js.map +1 -0
  136. package/dist/core/extensions/builtin/tool-search/tool.d.ts +21 -0
  137. package/dist/core/extensions/builtin/tool-search/tool.d.ts.map +1 -0
  138. package/dist/core/extensions/builtin/tool-search/tool.js +95 -0
  139. package/dist/core/extensions/builtin/tool-search/tool.js.map +1 -0
  140. package/dist/core/extensions/loader.d.ts.map +1 -1
  141. package/dist/core/extensions/loader.js +3 -0
  142. package/dist/core/extensions/loader.js.map +1 -1
  143. package/dist/core/extensions/types.d.ts +44 -4
  144. package/dist/core/extensions/types.d.ts.map +1 -1
  145. package/dist/core/extensions/types.js +11 -0
  146. package/dist/core/extensions/types.js.map +1 -1
  147. package/dist/core/provider-composer.d.ts +10 -1
  148. package/dist/core/provider-composer.d.ts.map +1 -1
  149. package/dist/core/provider-composer.js +9 -0
  150. package/dist/core/provider-composer.js.map +1 -1
  151. package/dist/modes/provider-native-rendering.d.ts.map +1 -1
  152. package/dist/modes/provider-native-rendering.js +33 -0
  153. package/dist/modes/provider-native-rendering.js.map +1 -1
  154. package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
  155. package/dist/modes/rpc/connection-handler.js +130 -4
  156. package/dist/modes/rpc/connection-handler.js.map +1 -1
  157. package/dist/modes/rpc/rpc-types.d.ts +31 -0
  158. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  159. package/dist/modes/rpc/rpc-types.js.map +1 -1
  160. package/dist/senpi +1 -0
  161. package/dist/valid-cwd.d.ts +2 -0
  162. package/dist/valid-cwd.d.ts.map +1 -0
  163. package/dist/valid-cwd.js +14 -0
  164. package/dist/valid-cwd.js.map +1 -0
  165. package/docs/environment-variables.md +7 -0
  166. package/docs/extensions.md +50 -13
  167. package/docs/mcp.md +2 -0
  168. package/docs/rpc.md +54 -0
  169. package/docs/skills.md +8 -0
  170. package/examples/extensions/searchable-tools.ts +49 -0
  171. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +12 -0
  172. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  173. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  174. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +5 -1
  175. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  176. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts +4 -1
  177. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
  178. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +2 -0
  179. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
  180. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +9 -0
  181. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  182. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  183. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  184. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  185. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +7 -3
  186. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  187. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.d.ts +8 -0
  188. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.d.ts.map +1 -0
  189. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.js +222 -0
  190. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.js.map +1 -0
  191. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.lazy.d.ts +3 -0
  192. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.lazy.d.ts.map +1 -0
  193. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.lazy.js +10 -0
  194. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.lazy.js.map +1 -0
  195. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.d.ts.map +1 -1
  196. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js +113 -4
  197. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses-shared.js.map +1 -1
  198. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  199. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +1 -0
  200. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  201. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.d.ts +5 -0
  202. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.d.ts.map +1 -1
  203. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js +2 -1
  204. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js.map +1 -1
  205. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts +10 -0
  206. package/node_modules/@earendil-works/pi-ai/dist/auth/types.d.ts.map +1 -1
  207. package/node_modules/@earendil-works/pi-ai/dist/auth/types.js.map +1 -1
  208. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +32 -0
  209. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  210. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +32 -0
  211. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  212. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  213. package/node_modules/@earendil-works/pi-ai/dist/models.js +36 -13
  214. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  215. package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.d.ts +2 -0
  216. package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.d.ts.map +1 -1
  217. package/node_modules/@earendil-works/pi-ai/dist/openai-responses-compat.js.map +1 -1
  218. package/node_modules/@earendil-works/pi-ai/dist/providers/all.d.ts.map +1 -1
  219. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js +2 -1
  220. package/node_modules/@earendil-works/pi-ai/dist/providers/all.js.map +1 -1
  221. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  222. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  223. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -1
  224. package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.json +1 -1
  225. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  226. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  227. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  228. package/node_modules/@earendil-works/pi-ai/dist/providers/images/register-builtins.d.ts +1 -0
  229. package/node_modules/@earendil-works/pi-ai/dist/providers/images/register-builtins.d.ts.map +1 -1
  230. package/node_modules/@earendil-works/pi-ai/dist/providers/images/register-builtins.js +18 -0
  231. package/node_modules/@earendil-works/pi-ai/dist/providers/images/register-builtins.js.map +1 -1
  232. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-images.d.ts +3 -0
  233. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-images.d.ts.map +1 -0
  234. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-images.js +16 -0
  235. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-images.js.map +1 -0
  236. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +1 -1
  237. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  238. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  239. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
  240. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +7 -0
  241. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  242. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  243. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  244. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  245. package/package.json +8 -8
  246. package/dist/core/extensions/builtin/mcp/expose/bm25.d.ts +0 -30
  247. package/dist/core/extensions/builtin/mcp/expose/bm25.d.ts.map +0 -1
  248. package/dist/core/extensions/builtin/mcp/expose/bm25.js.map +0 -1
  249. package/dist/core/extensions/builtin/mcp/expose/lazy-activate.d.ts +0 -15
  250. package/dist/core/extensions/builtin/mcp/expose/lazy-activate.d.ts.map +0 -1
  251. package/dist/core/extensions/builtin/mcp/expose/lazy-activate.js +0 -33
  252. package/dist/core/extensions/builtin/mcp/expose/lazy-activate.js.map +0 -1
  253. package/dist/core/extensions/builtin/mcp/expose/tool-search.d.ts +0 -43
  254. package/dist/core/extensions/builtin/mcp/expose/tool-search.d.ts.map +0 -1
  255. package/dist/core/extensions/builtin/mcp/expose/tool-search.js +0 -125
  256. package/dist/core/extensions/builtin/mcp/expose/tool-search.js.map +0 -1
@@ -1,15 +0,0 @@
1
- export interface LazySearchableTool {
2
- readonly name: string;
3
- }
4
- export interface LazyActivationState {
5
- readonly searchable: readonly LazySearchableTool[];
6
- readonly active: readonly string[];
7
- }
8
- export interface LazyToolActivatorDeps {
9
- readonly getSearchable: () => readonly LazySearchableTool[];
10
- readonly getActiveTools: () => readonly string[];
11
- readonly activate: (names: readonly string[]) => void;
12
- }
13
- export declare function resolveLazyActivationTargets(requested: readonly string[], state: LazyActivationState): readonly string[];
14
- export declare function createLazyToolActivator(deps: LazyToolActivatorDeps): (toolName: string) => boolean;
15
- //# sourceMappingURL=lazy-activate.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lazy-activate.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/mcp/expose/lazy-activate.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,UAAU,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACnD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,SAAS,kBAAkB,EAAE,CAAC;IAC5D,QAAQ,CAAC,cAAc,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;CACtD;AAED,wBAAgB,4BAA4B,CAC3C,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,KAAK,EAAE,mBAAmB,GACxB,SAAS,MAAM,EAAE,CASnB;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,qBAAqB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAUlG"}
@@ -1,33 +0,0 @@
1
- // Lazy tool activation for code-mode (eval) callers.
2
- //
3
- // An eval cell that names an MCP tool held inactive by SEARCH-mode exposure used
4
- // to fail with `inactive_tool`, even though tool_search may promote that exact
5
- // tool. Eligibility is therefore the tier-B searchable catalog and nothing else:
6
- // permission-denied tools, `list_changed` rug-pull additions, removed-tool
7
- // tombstones, and model-gated tools (look_at / read_video) are never eligible.
8
- // Activation is delegated to the tier-B `activate()` path so stub-swap, name
9
- // filtering, and active-set ordering keep their existing semantics.
10
- export function resolveLazyActivationTargets(requested, state) {
11
- const eligible = new Set(state.searchable.map((tool) => tool.name));
12
- const active = new Set(state.active);
13
- const targets = [];
14
- for (const name of requested) {
15
- if (!eligible.has(name) || active.has(name) || targets.includes(name))
16
- continue;
17
- targets.push(name);
18
- }
19
- return targets;
20
- }
21
- export function createLazyToolActivator(deps) {
22
- return (toolName) => {
23
- const targets = resolveLazyActivationTargets([toolName], {
24
- searchable: deps.getSearchable(),
25
- active: deps.getActiveTools(),
26
- });
27
- if (targets.length === 0)
28
- return false;
29
- deps.activate(targets);
30
- return true;
31
- };
32
- }
33
- //# sourceMappingURL=lazy-activate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lazy-activate.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/mcp/expose/lazy-activate.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,iFAAiF;AACjF,+EAA+E;AAC/E,iFAAiF;AACjF,2EAA2E;AAC3E,+EAA+E;AAC/E,6EAA6E;AAC7E,oEAAoE;AAiBpE,MAAM,UAAU,4BAA4B,CAC3C,SAA4B,EAC5B,KAA0B;IAE1B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,SAAS;QAChF,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAA2B;IAClE,OAAO,CAAC,QAAgB,EAAW,EAAE;QACpC,MAAM,OAAO,GAAG,4BAA4B,CAAC,CAAC,QAAQ,CAAC,EAAE;YACxD,UAAU,EAAE,IAAI,CAAC,aAAa,EAAE;YAChC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE;SAC7B,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACb,CAAC,CAAC;AACH,CAAC","sourcesContent":["// Lazy tool activation for code-mode (eval) callers.\n//\n// An eval cell that names an MCP tool held inactive by SEARCH-mode exposure used\n// to fail with `inactive_tool`, even though tool_search may promote that exact\n// tool. Eligibility is therefore the tier-B searchable catalog and nothing else:\n// permission-denied tools, `list_changed` rug-pull additions, removed-tool\n// tombstones, and model-gated tools (look_at / read_video) are never eligible.\n// Activation is delegated to the tier-B `activate()` path so stub-swap, name\n// filtering, and active-set ordering keep their existing semantics.\n\nexport interface LazySearchableTool {\n\treadonly name: string;\n}\n\nexport interface LazyActivationState {\n\treadonly searchable: readonly LazySearchableTool[];\n\treadonly active: readonly string[];\n}\n\nexport interface LazyToolActivatorDeps {\n\treadonly getSearchable: () => readonly LazySearchableTool[];\n\treadonly getActiveTools: () => readonly string[];\n\treadonly activate: (names: readonly string[]) => void;\n}\n\nexport function resolveLazyActivationTargets(\n\trequested: readonly string[],\n\tstate: LazyActivationState,\n): readonly string[] {\n\tconst eligible = new Set(state.searchable.map((tool) => tool.name));\n\tconst active = new Set(state.active);\n\tconst targets: string[] = [];\n\tfor (const name of requested) {\n\t\tif (!eligible.has(name) || active.has(name) || targets.includes(name)) continue;\n\t\ttargets.push(name);\n\t}\n\treturn targets;\n}\n\nexport function createLazyToolActivator(deps: LazyToolActivatorDeps): (toolName: string) => boolean {\n\treturn (toolName: string): boolean => {\n\t\tconst targets = resolveLazyActivationTargets([toolName], {\n\t\t\tsearchable: deps.getSearchable(),\n\t\t\tactive: deps.getActiveTools(),\n\t\t});\n\t\tif (targets.length === 0) return false;\n\t\tdeps.activate(targets);\n\t\treturn true;\n\t};\n}\n"]}
@@ -1,43 +0,0 @@
1
- import { Type } from "typebox";
2
- import type { ToolDefinition } from "../../../types.ts";
3
- import { type Bm25Doc } from "./bm25.ts";
4
- export declare const TOOL_SEARCH_TOOL_NAME = "tool_search";
5
- /** Stable, machine-parseable marker embedded in every activating result so
6
- * activations survive compaction/restart. Kept human-readable on purpose. */
7
- export declare const TOOL_SEARCH_ACTIVATION_MARKER = "[tool_search:activated]";
8
- export type SearchableMcpTool = Bm25Doc;
9
- export interface McpSearchDeps {
10
- /** Full current catalog (all MCP tools, active or not) to rank over. */
11
- getSearchableTools(): readonly SearchableMcpTool[];
12
- /** Current active tool names (includes non-MCP tools). */
13
- getActiveTools(): string[];
14
- /** Replace the active set. Implementations should preserve registration. */
15
- setActiveTools(names: readonly string[]): void;
16
- }
17
- export interface McpSearchDetails {
18
- query: string;
19
- activated: string[];
20
- }
21
- declare const ParamsSchema: Type.TObject<{
22
- query: Type.TString;
23
- server: Type.TOptional<Type.TString>;
24
- }>;
25
- type McpSearchTool = ToolDefinition<typeof ParamsSchema, McpSearchDetails, unknown>;
26
- export declare function createMcpSearchTool(deps: McpSearchDeps): McpSearchTool;
27
- interface RankedMatch {
28
- readonly name: string;
29
- readonly doc: SearchableMcpTool;
30
- }
31
- export declare function buildMcpSearchResultText(query: string, matches: readonly RankedMatch[], server: string | undefined): string;
32
- /**
33
- * Replay tool_search activations recorded in prior history so a
34
- * compacted/restarted session restores its active tool set without re-searching.
35
- * Only names still present in `validNames` are restored (removed tools stay
36
- * dropped). Deterministic: returns a de-duplicated, sorted list.
37
- */
38
- export declare function rehydrateActiveToolsFromHistory(messages: readonly unknown[], validNames: ReadonlySet<string>): string[];
39
- /** Stable union: dedupe and sort so the active-tools array is byte-stable
40
- * across turns (prompt-cache friendly). */
41
- export declare function unionStable(current: readonly string[], added: readonly string[]): string[];
42
- export {};
43
- //# sourceMappingURL=tool-search.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tool-search.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/mcp/expose/tool-search.ts"],"names":[],"mappings":"AAYA,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,KAAK,OAAO,EAAkB,MAAM,WAAW,CAAC;AAEzD,eAAO,MAAM,qBAAqB,gBAAgB,CAAC;AACnD;6EAC6E;AAC7E,eAAO,MAAM,6BAA6B,4BAA4B,CAAC;AAGvE,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAExC,MAAM,WAAW,aAAa;IAC7B,wEAAwE;IACxE,kBAAkB,IAAI,SAAS,iBAAiB,EAAE,CAAC;IACnD,0DAA0D;IAC1D,cAAc,IAAI,MAAM,EAAE,CAAC;IAC3B,4EAA4E;IAC5E,cAAc,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,QAAA,MAAM,YAAY;;;EAGhB,CAAC;AAGH,KAAK,aAAa,GAAG,cAAc,CAAC,OAAO,YAAY,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;AAEpF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,CAmCtE;AAED,UAAU,WAAW;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC;CAChC;AAED,wBAAgB,wBAAwB,CACvC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,MAAM,EAAE,MAAM,GAAG,SAAS,GACxB,MAAM,CAgBR;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC9C,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,GAC7B,MAAM,EAAE,CAUV;AAsBD;2CAC2C;AAC3C,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAE1F"}
@@ -1,125 +0,0 @@
1
- // tool_search tool + promotion engine (todo 31).
2
- //
3
- // `tool_search` is an always-active tool that ranks the full MCP catalog with
4
- // the local BM25 engine and PROMOTES matched tools into the active set via
5
- // setActiveTools (effective the NEXT turn — senpi semantics). Promotion state
6
- // is derivable from history: each result embeds a stable activation marker so a
7
- // compaction/restart can replay activations at session_start
8
- // (rehydrateActiveToolsFromHistory). Activated tools persist for the session;
9
- // there is no auto-eviction in v1. Every setActiveTools call is stable-sorted.
10
- import { Text } from "@earendil-works/pi-tui";
11
- import { Type } from "typebox";
12
- import { buildBm25Index } from "./bm25.js";
13
- export const TOOL_SEARCH_TOOL_NAME = "tool_search";
14
- /** Stable, machine-parseable marker embedded in every activating result so
15
- * activations survive compaction/restart. Kept human-readable on purpose. */
16
- export const TOOL_SEARCH_ACTIVATION_MARKER = "[tool_search:activated]";
17
- const MAX_RESULTS = 10;
18
- const ParamsSchema = Type.Object({
19
- query: Type.String({ description: "Natural-language description of the capability you need." }),
20
- server: Type.Optional(Type.String({ description: "Optional: restrict the search to a single MCP server name." })),
21
- });
22
- export function createMcpSearchTool(deps) {
23
- return {
24
- name: TOOL_SEARCH_TOOL_NAME,
25
- label: "MCP tool search",
26
- description: "Search the catalog of available MCP tools by capability. Matched tools are activated and become callable on your NEXT turn. Use this before calling an MCP tool that is not already active.",
27
- promptSnippet: "Search MCP servers for a tool by capability; matched tools activate next turn.",
28
- parameters: ParamsSchema,
29
- executionMode: "parallel",
30
- async execute(_toolCallId, params) {
31
- const searchable = deps.getSearchableTools();
32
- const index = buildBm25Index(searchable);
33
- const matches = index.search(params.query, MAX_RESULTS, params.server ? { server: params.server } : {});
34
- const activated = matches.map((match) => match.name);
35
- if (activated.length > 0) {
36
- deps.setActiveTools(unionStable(deps.getActiveTools(), activated));
37
- }
38
- const text = buildMcpSearchResultText(params.query, matches, params.server);
39
- return {
40
- content: [{ type: "text", text }],
41
- details: { activated, query: params.query },
42
- };
43
- },
44
- renderCall(args, theme) {
45
- const filter = args.server ? ` @${args.server}` : "";
46
- return new Text(theme.fg("toolTitle", theme.bold(`${TOOL_SEARCH_TOOL_NAME} "${args.query}"${filter}`)), 0, 0);
47
- },
48
- renderResult(result, options, theme) {
49
- const count = result.details?.activated.length ?? 0;
50
- const title = options.isPartial
51
- ? `${TOOL_SEARCH_TOOL_NAME}: searching`
52
- : `${TOOL_SEARCH_TOOL_NAME}: ${count} tool(s) activated`;
53
- return new Text(theme.fg("toolOutput", title), 0, 0);
54
- },
55
- };
56
- }
57
- export function buildMcpSearchResultText(query, matches, server) {
58
- const scope = server ? ` on server "${server}"` : "";
59
- if (matches.length === 0) {
60
- return `No MCP tools matched "${query}"${scope}. No tools were activated; try different keywords or run tool_search with a broader query. Your active tool set is unchanged.`;
61
- }
62
- const bullets = matches
63
- .map((match) => `- ${match.name} — ${oneLine(match.doc.description) ?? "(no description)"}`)
64
- .join("\n");
65
- const names = matches.map((match) => match.name).join(" ");
66
- return [
67
- `Found ${matches.length} MCP tool(s) matching "${query}"${scope}. They are now active and callable from your NEXT turn:`,
68
- "",
69
- bullets,
70
- "",
71
- `${TOOL_SEARCH_ACTIVATION_MARKER} ${names}`,
72
- ].join("\n");
73
- }
74
- /**
75
- * Replay tool_search activations recorded in prior history so a
76
- * compacted/restarted session restores its active tool set without re-searching.
77
- * Only names still present in `validNames` are restored (removed tools stay
78
- * dropped). Deterministic: returns a de-duplicated, sorted list.
79
- */
80
- export function rehydrateActiveToolsFromHistory(messages, validNames) {
81
- const restored = new Set();
82
- for (const message of messages) {
83
- for (const segment of extractActivationSegments(message)) {
84
- for (const name of segment.trim().split(/\s+/)) {
85
- if (name.length > 0 && validNames.has(name))
86
- restored.add(name);
87
- }
88
- }
89
- }
90
- return [...restored].sort();
91
- }
92
- function extractActivationSegments(message) {
93
- let blob;
94
- try {
95
- blob = JSON.stringify(message) ?? "";
96
- }
97
- catch {
98
- return [];
99
- }
100
- const segments = [];
101
- let cursor = blob.indexOf(TOOL_SEARCH_ACTIVATION_MARKER);
102
- while (cursor >= 0) {
103
- const rest = blob.slice(cursor + TOOL_SEARCH_ACTIVATION_MARKER.length);
104
- // Tool names are [a-zA-Z0-9_-]; stop at the first JSON string terminator
105
- // (quote / escape) or newline so we never swallow the rest of the blob.
106
- const end = rest.search(/["\\\n]/);
107
- segments.push(end < 0 ? rest : rest.slice(0, end));
108
- cursor = blob.indexOf(TOOL_SEARCH_ACTIVATION_MARKER, cursor + TOOL_SEARCH_ACTIVATION_MARKER.length);
109
- }
110
- return segments;
111
- }
112
- /** Stable union: dedupe and sort so the active-tools array is byte-stable
113
- * across turns (prompt-cache friendly). */
114
- export function unionStable(current, added) {
115
- return [...new Set([...current, ...added])].sort();
116
- }
117
- function oneLine(text) {
118
- if (text === undefined)
119
- return undefined;
120
- const collapsed = text.replace(/\s+/g, " ").trim();
121
- if (collapsed.length === 0)
122
- return undefined;
123
- return collapsed.length <= 100 ? collapsed : `${collapsed.slice(0, 97)}...`;
124
- }
125
- //# sourceMappingURL=tool-search.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tool-search.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/mcp/expose/tool-search.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,EAAE;AACF,8EAA8E;AAC9E,2EAA2E;AAC3E,8EAA8E;AAC9E,gFAAgF;AAChF,6DAA6D;AAC7D,8EAA8E;AAC9E,+EAA+E;AAG/E,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,EAAgB,cAAc,EAAE,MAAM,WAAW,CAAC;AAEzD,MAAM,CAAC,MAAM,qBAAqB,GAAG,aAAa,CAAC;AACnD;6EAC6E;AAC7E,MAAM,CAAC,MAAM,6BAA6B,GAAG,yBAAyB,CAAC;AACvE,MAAM,WAAW,GAAG,EAAE,CAAC;AAkBvB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;IAChC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,0DAA0D,EAAE,CAAC;IAC/F,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4DAA4D,EAAE,CAAC,CAAC;CACjH,CAAC,CAAC;AAKH,MAAM,UAAU,mBAAmB,CAAC,IAAmB;IACtD,OAAO;QACN,IAAI,EAAE,qBAAqB;QAC3B,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACV,6LAA6L;QAC9L,aAAa,EAAE,gFAAgF;QAC/F,UAAU,EAAE,YAAY;QACxB,aAAa,EAAE,UAAU;QACzB,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,MAAc;YACxC,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC7C,MAAM,KAAK,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;YACzC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACxG,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACrD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC;YACpE,CAAC;YACD,MAAM,IAAI,GAAG,wBAAwB,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAC5E,OAAO;gBACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;gBACjC,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE;aAC3C,CAAC;QACH,CAAC;QACD,UAAU,CAAC,IAAI,EAAE,KAAK;YACrB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,qBAAqB,KAAK,IAAI,CAAC,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/G,CAAC;QACD,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK;YAClC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,MAAM,IAAI,CAAC,CAAC;YACpD,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS;gBAC9B,CAAC,CAAC,GAAG,qBAAqB,aAAa;gBACvC,CAAC,CAAC,GAAG,qBAAqB,KAAK,KAAK,oBAAoB,CAAC;YAC1D,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACtD,CAAC;KACD,CAAC;AACH,CAAC;AAOD,MAAM,UAAU,wBAAwB,CACvC,KAAa,EACb,OAA+B,EAC/B,MAA0B;IAE1B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,eAAe,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACrD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,yBAAyB,KAAK,IAAI,KAAK,+HAA+H,CAAC;IAC/K,CAAC;IACD,MAAM,OAAO,GAAG,OAAO;SACrB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,IAAI,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,kBAAkB,EAAE,CAAC;SAC3F,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3D,OAAO;QACN,SAAS,OAAO,CAAC,MAAM,0BAA0B,KAAK,IAAI,KAAK,yDAAyD;QACxH,EAAE;QACF,OAAO;QACP,EAAE;QACF,GAAG,6BAA6B,IAAI,KAAK,EAAE;KAC3C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,+BAA+B,CAC9C,QAA4B,EAC5B,UAA+B;IAE/B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAChC,KAAK,MAAM,OAAO,IAAI,yBAAyB,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1D,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBAChD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACjE,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED,SAAS,yBAAyB,CAAC,OAAgB;IAClD,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACJ,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAC;IACX,CAAC;IACD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;IACzD,OAAO,MAAM,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,6BAA6B,CAAC,MAAM,CAAC,CAAC;QACvE,yEAAyE;QACzE,wEAAwE;QACxE,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACnC,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QACnD,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,6BAA6B,EAAE,MAAM,GAAG,6BAA6B,CAAC,MAAM,CAAC,CAAC;IACrG,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED;2CAC2C;AAC3C,MAAM,UAAU,WAAW,CAAC,OAA0B,EAAE,KAAwB;IAC/E,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AACpD,CAAC;AAED,SAAS,OAAO,CAAC,IAAwB;IACxC,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACnD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7C,OAAO,SAAS,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC;AAC7E,CAAC","sourcesContent":["// tool_search tool + promotion engine (todo 31).\n//\n// `tool_search` is an always-active tool that ranks the full MCP catalog with\n// the local BM25 engine and PROMOTES matched tools into the active set via\n// setActiveTools (effective the NEXT turn — senpi semantics). Promotion state\n// is derivable from history: each result embeds a stable activation marker so a\n// compaction/restart can replay activations at session_start\n// (rehydrateActiveToolsFromHistory). Activated tools persist for the session;\n// there is no auto-eviction in v1. Every setActiveTools call is stable-sorted.\n\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport { Text } from \"@earendil-works/pi-tui\";\nimport { type Static, Type } from \"typebox\";\nimport type { ToolDefinition } from \"../../../types.ts\";\nimport { type Bm25Doc, buildBm25Index } from \"./bm25.ts\";\n\nexport const TOOL_SEARCH_TOOL_NAME = \"tool_search\";\n/** Stable, machine-parseable marker embedded in every activating result so\n * activations survive compaction/restart. Kept human-readable on purpose. */\nexport const TOOL_SEARCH_ACTIVATION_MARKER = \"[tool_search:activated]\";\nconst MAX_RESULTS = 10;\n\nexport type SearchableMcpTool = Bm25Doc;\n\nexport interface McpSearchDeps {\n\t/** Full current catalog (all MCP tools, active or not) to rank over. */\n\tgetSearchableTools(): readonly SearchableMcpTool[];\n\t/** Current active tool names (includes non-MCP tools). */\n\tgetActiveTools(): string[];\n\t/** Replace the active set. Implementations should preserve registration. */\n\tsetActiveTools(names: readonly string[]): void;\n}\n\nexport interface McpSearchDetails {\n\tquery: string;\n\tactivated: string[];\n}\n\nconst ParamsSchema = Type.Object({\n\tquery: Type.String({ description: \"Natural-language description of the capability you need.\" }),\n\tserver: Type.Optional(Type.String({ description: \"Optional: restrict the search to a single MCP server name.\" })),\n});\ntype Params = Static<typeof ParamsSchema>;\n\ntype McpSearchTool = ToolDefinition<typeof ParamsSchema, McpSearchDetails, unknown>;\n\nexport function createMcpSearchTool(deps: McpSearchDeps): McpSearchTool {\n\treturn {\n\t\tname: TOOL_SEARCH_TOOL_NAME,\n\t\tlabel: \"MCP tool search\",\n\t\tdescription:\n\t\t\t\"Search the catalog of available MCP tools by capability. Matched tools are activated and become callable on your NEXT turn. Use this before calling an MCP tool that is not already active.\",\n\t\tpromptSnippet: \"Search MCP servers for a tool by capability; matched tools activate next turn.\",\n\t\tparameters: ParamsSchema,\n\t\texecutionMode: \"parallel\",\n\t\tasync execute(_toolCallId, params: Params): Promise<AgentToolResult<McpSearchDetails>> {\n\t\t\tconst searchable = deps.getSearchableTools();\n\t\t\tconst index = buildBm25Index(searchable);\n\t\t\tconst matches = index.search(params.query, MAX_RESULTS, params.server ? { server: params.server } : {});\n\t\t\tconst activated = matches.map((match) => match.name);\n\t\t\tif (activated.length > 0) {\n\t\t\t\tdeps.setActiveTools(unionStable(deps.getActiveTools(), activated));\n\t\t\t}\n\t\t\tconst text = buildMcpSearchResultText(params.query, matches, params.server);\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text }],\n\t\t\t\tdetails: { activated, query: params.query },\n\t\t\t};\n\t\t},\n\t\trenderCall(args, theme) {\n\t\t\tconst filter = args.server ? ` @${args.server}` : \"\";\n\t\t\treturn new Text(theme.fg(\"toolTitle\", theme.bold(`${TOOL_SEARCH_TOOL_NAME} \"${args.query}\"${filter}`)), 0, 0);\n\t\t},\n\t\trenderResult(result, options, theme) {\n\t\t\tconst count = result.details?.activated.length ?? 0;\n\t\t\tconst title = options.isPartial\n\t\t\t\t? `${TOOL_SEARCH_TOOL_NAME}: searching`\n\t\t\t\t: `${TOOL_SEARCH_TOOL_NAME}: ${count} tool(s) activated`;\n\t\t\treturn new Text(theme.fg(\"toolOutput\", title), 0, 0);\n\t\t},\n\t};\n}\n\ninterface RankedMatch {\n\treadonly name: string;\n\treadonly doc: SearchableMcpTool;\n}\n\nexport function buildMcpSearchResultText(\n\tquery: string,\n\tmatches: readonly RankedMatch[],\n\tserver: string | undefined,\n): string {\n\tconst scope = server ? ` on server \"${server}\"` : \"\";\n\tif (matches.length === 0) {\n\t\treturn `No MCP tools matched \"${query}\"${scope}. No tools were activated; try different keywords or run tool_search with a broader query. Your active tool set is unchanged.`;\n\t}\n\tconst bullets = matches\n\t\t.map((match) => `- ${match.name} — ${oneLine(match.doc.description) ?? \"(no description)\"}`)\n\t\t.join(\"\\n\");\n\tconst names = matches.map((match) => match.name).join(\" \");\n\treturn [\n\t\t`Found ${matches.length} MCP tool(s) matching \"${query}\"${scope}. They are now active and callable from your NEXT turn:`,\n\t\t\"\",\n\t\tbullets,\n\t\t\"\",\n\t\t`${TOOL_SEARCH_ACTIVATION_MARKER} ${names}`,\n\t].join(\"\\n\");\n}\n\n/**\n * Replay tool_search activations recorded in prior history so a\n * compacted/restarted session restores its active tool set without re-searching.\n * Only names still present in `validNames` are restored (removed tools stay\n * dropped). Deterministic: returns a de-duplicated, sorted list.\n */\nexport function rehydrateActiveToolsFromHistory(\n\tmessages: readonly unknown[],\n\tvalidNames: ReadonlySet<string>,\n): string[] {\n\tconst restored = new Set<string>();\n\tfor (const message of messages) {\n\t\tfor (const segment of extractActivationSegments(message)) {\n\t\t\tfor (const name of segment.trim().split(/\\s+/)) {\n\t\t\t\tif (name.length > 0 && validNames.has(name)) restored.add(name);\n\t\t\t}\n\t\t}\n\t}\n\treturn [...restored].sort();\n}\n\nfunction extractActivationSegments(message: unknown): string[] {\n\tlet blob: string;\n\ttry {\n\t\tblob = JSON.stringify(message) ?? \"\";\n\t} catch {\n\t\treturn [];\n\t}\n\tconst segments: string[] = [];\n\tlet cursor = blob.indexOf(TOOL_SEARCH_ACTIVATION_MARKER);\n\twhile (cursor >= 0) {\n\t\tconst rest = blob.slice(cursor + TOOL_SEARCH_ACTIVATION_MARKER.length);\n\t\t// Tool names are [a-zA-Z0-9_-]; stop at the first JSON string terminator\n\t\t// (quote / escape) or newline so we never swallow the rest of the blob.\n\t\tconst end = rest.search(/[\"\\\\\\n]/);\n\t\tsegments.push(end < 0 ? rest : rest.slice(0, end));\n\t\tcursor = blob.indexOf(TOOL_SEARCH_ACTIVATION_MARKER, cursor + TOOL_SEARCH_ACTIVATION_MARKER.length);\n\t}\n\treturn segments;\n}\n\n/** Stable union: dedupe and sort so the active-tools array is byte-stable\n * across turns (prompt-cache friendly). */\nexport function unionStable(current: readonly string[], added: readonly string[]): string[] {\n\treturn [...new Set([...current, ...added])].sort();\n}\n\nfunction oneLine(text: string | undefined): string | undefined {\n\tif (text === undefined) return undefined;\n\tconst collapsed = text.replace(/\\s+/g, \" \").trim();\n\tif (collapsed.length === 0) return undefined;\n\treturn collapsed.length <= 100 ? collapsed : `${collapsed.slice(0, 97)}...`;\n}\n"]}