agentpool 2.1.9__py3-none-any.whl

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.

Potentially problematic release.


This version of agentpool might be problematic. Click here for more details.

Files changed (474) hide show
  1. acp/README.md +64 -0
  2. acp/__init__.py +172 -0
  3. acp/__main__.py +10 -0
  4. acp/acp_requests.py +285 -0
  5. acp/agent/__init__.py +6 -0
  6. acp/agent/connection.py +256 -0
  7. acp/agent/implementations/__init__.py +6 -0
  8. acp/agent/implementations/debug_server/__init__.py +1 -0
  9. acp/agent/implementations/debug_server/cli.py +79 -0
  10. acp/agent/implementations/debug_server/debug.html +234 -0
  11. acp/agent/implementations/debug_server/debug_server.py +496 -0
  12. acp/agent/implementations/testing.py +91 -0
  13. acp/agent/protocol.py +65 -0
  14. acp/bridge/README.md +162 -0
  15. acp/bridge/__init__.py +6 -0
  16. acp/bridge/__main__.py +91 -0
  17. acp/bridge/bridge.py +246 -0
  18. acp/bridge/py.typed +0 -0
  19. acp/bridge/settings.py +15 -0
  20. acp/client/__init__.py +7 -0
  21. acp/client/connection.py +251 -0
  22. acp/client/implementations/__init__.py +7 -0
  23. acp/client/implementations/default_client.py +185 -0
  24. acp/client/implementations/headless_client.py +266 -0
  25. acp/client/implementations/noop_client.py +110 -0
  26. acp/client/protocol.py +61 -0
  27. acp/connection.py +280 -0
  28. acp/exceptions.py +46 -0
  29. acp/filesystem.py +524 -0
  30. acp/notifications.py +832 -0
  31. acp/py.typed +0 -0
  32. acp/schema/__init__.py +265 -0
  33. acp/schema/agent_plan.py +30 -0
  34. acp/schema/agent_requests.py +126 -0
  35. acp/schema/agent_responses.py +256 -0
  36. acp/schema/base.py +39 -0
  37. acp/schema/capabilities.py +230 -0
  38. acp/schema/client_requests.py +247 -0
  39. acp/schema/client_responses.py +96 -0
  40. acp/schema/common.py +81 -0
  41. acp/schema/content_blocks.py +188 -0
  42. acp/schema/mcp.py +82 -0
  43. acp/schema/messages.py +171 -0
  44. acp/schema/notifications.py +82 -0
  45. acp/schema/protocol_stuff.md +3 -0
  46. acp/schema/session_state.py +160 -0
  47. acp/schema/session_updates.py +419 -0
  48. acp/schema/slash_commands.py +51 -0
  49. acp/schema/terminal.py +15 -0
  50. acp/schema/tool_call.py +347 -0
  51. acp/stdio.py +250 -0
  52. acp/task/__init__.py +53 -0
  53. acp/task/debug.py +197 -0
  54. acp/task/dispatcher.py +93 -0
  55. acp/task/queue.py +69 -0
  56. acp/task/sender.py +82 -0
  57. acp/task/state.py +87 -0
  58. acp/task/supervisor.py +93 -0
  59. acp/terminal_handle.py +30 -0
  60. acp/tool_call_reporter.py +199 -0
  61. acp/tool_call_state.py +178 -0
  62. acp/transports.py +104 -0
  63. acp/utils.py +240 -0
  64. agentpool/__init__.py +63 -0
  65. agentpool/__main__.py +7 -0
  66. agentpool/agents/__init__.py +30 -0
  67. agentpool/agents/acp_agent/__init__.py +5 -0
  68. agentpool/agents/acp_agent/acp_agent.py +837 -0
  69. agentpool/agents/acp_agent/acp_converters.py +294 -0
  70. agentpool/agents/acp_agent/client_handler.py +317 -0
  71. agentpool/agents/acp_agent/session_state.py +44 -0
  72. agentpool/agents/agent.py +1264 -0
  73. agentpool/agents/agui_agent/__init__.py +19 -0
  74. agentpool/agents/agui_agent/agui_agent.py +677 -0
  75. agentpool/agents/agui_agent/agui_converters.py +423 -0
  76. agentpool/agents/agui_agent/chunk_transformer.py +204 -0
  77. agentpool/agents/agui_agent/event_types.py +83 -0
  78. agentpool/agents/agui_agent/helpers.py +192 -0
  79. agentpool/agents/architect.py +71 -0
  80. agentpool/agents/base_agent.py +177 -0
  81. agentpool/agents/claude_code_agent/__init__.py +11 -0
  82. agentpool/agents/claude_code_agent/claude_code_agent.py +1021 -0
  83. agentpool/agents/claude_code_agent/converters.py +243 -0
  84. agentpool/agents/context.py +105 -0
  85. agentpool/agents/events/__init__.py +61 -0
  86. agentpool/agents/events/builtin_handlers.py +129 -0
  87. agentpool/agents/events/event_emitter.py +320 -0
  88. agentpool/agents/events/events.py +561 -0
  89. agentpool/agents/events/tts_handlers.py +186 -0
  90. agentpool/agents/interactions.py +419 -0
  91. agentpool/agents/slashed_agent.py +244 -0
  92. agentpool/agents/sys_prompts.py +178 -0
  93. agentpool/agents/tool_wrapping.py +184 -0
  94. agentpool/base_provider.py +28 -0
  95. agentpool/common_types.py +226 -0
  96. agentpool/config_resources/__init__.py +16 -0
  97. agentpool/config_resources/acp_assistant.yml +24 -0
  98. agentpool/config_resources/agents.yml +109 -0
  99. agentpool/config_resources/agents_template.yml +18 -0
  100. agentpool/config_resources/agui_test.yml +18 -0
  101. agentpool/config_resources/claude_code_agent.yml +16 -0
  102. agentpool/config_resources/claude_style_subagent.md +30 -0
  103. agentpool/config_resources/external_acp_agents.yml +77 -0
  104. agentpool/config_resources/opencode_style_subagent.md +19 -0
  105. agentpool/config_resources/tts_test_agents.yml +78 -0
  106. agentpool/delegation/__init__.py +8 -0
  107. agentpool/delegation/base_team.py +504 -0
  108. agentpool/delegation/message_flow_tracker.py +39 -0
  109. agentpool/delegation/pool.py +1129 -0
  110. agentpool/delegation/team.py +325 -0
  111. agentpool/delegation/teamrun.py +343 -0
  112. agentpool/docs/__init__.py +5 -0
  113. agentpool/docs/gen_examples.py +42 -0
  114. agentpool/docs/utils.py +370 -0
  115. agentpool/functional/__init__.py +20 -0
  116. agentpool/functional/py.typed +0 -0
  117. agentpool/functional/run.py +80 -0
  118. agentpool/functional/structure.py +136 -0
  119. agentpool/hooks/__init__.py +20 -0
  120. agentpool/hooks/agent_hooks.py +247 -0
  121. agentpool/hooks/base.py +119 -0
  122. agentpool/hooks/callable.py +140 -0
  123. agentpool/hooks/command.py +180 -0
  124. agentpool/hooks/prompt.py +122 -0
  125. agentpool/jinja_filters.py +132 -0
  126. agentpool/log.py +224 -0
  127. agentpool/mcp_server/__init__.py +17 -0
  128. agentpool/mcp_server/client.py +429 -0
  129. agentpool/mcp_server/constants.py +32 -0
  130. agentpool/mcp_server/conversions.py +172 -0
  131. agentpool/mcp_server/helpers.py +47 -0
  132. agentpool/mcp_server/manager.py +232 -0
  133. agentpool/mcp_server/message_handler.py +164 -0
  134. agentpool/mcp_server/registries/__init__.py +1 -0
  135. agentpool/mcp_server/registries/official_registry_client.py +345 -0
  136. agentpool/mcp_server/registries/pulsemcp_client.py +88 -0
  137. agentpool/mcp_server/tool_bridge.py +548 -0
  138. agentpool/messaging/__init__.py +58 -0
  139. agentpool/messaging/compaction.py +928 -0
  140. agentpool/messaging/connection_manager.py +319 -0
  141. agentpool/messaging/context.py +66 -0
  142. agentpool/messaging/event_manager.py +426 -0
  143. agentpool/messaging/events.py +39 -0
  144. agentpool/messaging/message_container.py +209 -0
  145. agentpool/messaging/message_history.py +491 -0
  146. agentpool/messaging/messagenode.py +377 -0
  147. agentpool/messaging/messages.py +655 -0
  148. agentpool/messaging/processing.py +76 -0
  149. agentpool/mime_utils.py +95 -0
  150. agentpool/models/__init__.py +21 -0
  151. agentpool/models/acp_agents/__init__.py +22 -0
  152. agentpool/models/acp_agents/base.py +308 -0
  153. agentpool/models/acp_agents/mcp_capable.py +790 -0
  154. agentpool/models/acp_agents/non_mcp.py +842 -0
  155. agentpool/models/agents.py +450 -0
  156. agentpool/models/agui_agents.py +89 -0
  157. agentpool/models/claude_code_agents.py +238 -0
  158. agentpool/models/file_agents.py +116 -0
  159. agentpool/models/file_parsing.py +367 -0
  160. agentpool/models/manifest.py +658 -0
  161. agentpool/observability/__init__.py +9 -0
  162. agentpool/observability/observability_registry.py +97 -0
  163. agentpool/prompts/__init__.py +1 -0
  164. agentpool/prompts/base.py +27 -0
  165. agentpool/prompts/builtin_provider.py +75 -0
  166. agentpool/prompts/conversion_manager.py +95 -0
  167. agentpool/prompts/convert.py +96 -0
  168. agentpool/prompts/manager.py +204 -0
  169. agentpool/prompts/parts/zed.md +33 -0
  170. agentpool/prompts/prompts.py +581 -0
  171. agentpool/py.typed +0 -0
  172. agentpool/queries/tree-sitter-language-pack/README.md +7 -0
  173. agentpool/queries/tree-sitter-language-pack/arduino-tags.scm +5 -0
  174. agentpool/queries/tree-sitter-language-pack/c-tags.scm +9 -0
  175. agentpool/queries/tree-sitter-language-pack/chatito-tags.scm +16 -0
  176. agentpool/queries/tree-sitter-language-pack/clojure-tags.scm +7 -0
  177. agentpool/queries/tree-sitter-language-pack/commonlisp-tags.scm +122 -0
  178. agentpool/queries/tree-sitter-language-pack/cpp-tags.scm +15 -0
  179. agentpool/queries/tree-sitter-language-pack/csharp-tags.scm +26 -0
  180. agentpool/queries/tree-sitter-language-pack/d-tags.scm +26 -0
  181. agentpool/queries/tree-sitter-language-pack/dart-tags.scm +92 -0
  182. agentpool/queries/tree-sitter-language-pack/elisp-tags.scm +5 -0
  183. agentpool/queries/tree-sitter-language-pack/elixir-tags.scm +54 -0
  184. agentpool/queries/tree-sitter-language-pack/elm-tags.scm +19 -0
  185. agentpool/queries/tree-sitter-language-pack/gleam-tags.scm +41 -0
  186. agentpool/queries/tree-sitter-language-pack/go-tags.scm +42 -0
  187. agentpool/queries/tree-sitter-language-pack/java-tags.scm +20 -0
  188. agentpool/queries/tree-sitter-language-pack/javascript-tags.scm +88 -0
  189. agentpool/queries/tree-sitter-language-pack/lua-tags.scm +34 -0
  190. agentpool/queries/tree-sitter-language-pack/matlab-tags.scm +10 -0
  191. agentpool/queries/tree-sitter-language-pack/ocaml-tags.scm +115 -0
  192. agentpool/queries/tree-sitter-language-pack/ocaml_interface-tags.scm +98 -0
  193. agentpool/queries/tree-sitter-language-pack/pony-tags.scm +39 -0
  194. agentpool/queries/tree-sitter-language-pack/properties-tags.scm +5 -0
  195. agentpool/queries/tree-sitter-language-pack/python-tags.scm +14 -0
  196. agentpool/queries/tree-sitter-language-pack/r-tags.scm +21 -0
  197. agentpool/queries/tree-sitter-language-pack/racket-tags.scm +12 -0
  198. agentpool/queries/tree-sitter-language-pack/ruby-tags.scm +64 -0
  199. agentpool/queries/tree-sitter-language-pack/rust-tags.scm +60 -0
  200. agentpool/queries/tree-sitter-language-pack/solidity-tags.scm +43 -0
  201. agentpool/queries/tree-sitter-language-pack/swift-tags.scm +51 -0
  202. agentpool/queries/tree-sitter-language-pack/udev-tags.scm +20 -0
  203. agentpool/queries/tree-sitter-languages/README.md +24 -0
  204. agentpool/queries/tree-sitter-languages/c-tags.scm +9 -0
  205. agentpool/queries/tree-sitter-languages/c_sharp-tags.scm +46 -0
  206. agentpool/queries/tree-sitter-languages/cpp-tags.scm +15 -0
  207. agentpool/queries/tree-sitter-languages/dart-tags.scm +91 -0
  208. agentpool/queries/tree-sitter-languages/elisp-tags.scm +8 -0
  209. agentpool/queries/tree-sitter-languages/elixir-tags.scm +54 -0
  210. agentpool/queries/tree-sitter-languages/elm-tags.scm +19 -0
  211. agentpool/queries/tree-sitter-languages/fortran-tags.scm +15 -0
  212. agentpool/queries/tree-sitter-languages/go-tags.scm +30 -0
  213. agentpool/queries/tree-sitter-languages/haskell-tags.scm +3 -0
  214. agentpool/queries/tree-sitter-languages/hcl-tags.scm +77 -0
  215. agentpool/queries/tree-sitter-languages/java-tags.scm +20 -0
  216. agentpool/queries/tree-sitter-languages/javascript-tags.scm +88 -0
  217. agentpool/queries/tree-sitter-languages/julia-tags.scm +60 -0
  218. agentpool/queries/tree-sitter-languages/kotlin-tags.scm +27 -0
  219. agentpool/queries/tree-sitter-languages/matlab-tags.scm +10 -0
  220. agentpool/queries/tree-sitter-languages/ocaml-tags.scm +115 -0
  221. agentpool/queries/tree-sitter-languages/ocaml_interface-tags.scm +98 -0
  222. agentpool/queries/tree-sitter-languages/php-tags.scm +26 -0
  223. agentpool/queries/tree-sitter-languages/python-tags.scm +12 -0
  224. agentpool/queries/tree-sitter-languages/ql-tags.scm +26 -0
  225. agentpool/queries/tree-sitter-languages/ruby-tags.scm +64 -0
  226. agentpool/queries/tree-sitter-languages/rust-tags.scm +60 -0
  227. agentpool/queries/tree-sitter-languages/scala-tags.scm +65 -0
  228. agentpool/queries/tree-sitter-languages/typescript-tags.scm +41 -0
  229. agentpool/queries/tree-sitter-languages/zig-tags.scm +3 -0
  230. agentpool/repomap.py +1231 -0
  231. agentpool/resource_providers/__init__.py +17 -0
  232. agentpool/resource_providers/aggregating.py +54 -0
  233. agentpool/resource_providers/base.py +172 -0
  234. agentpool/resource_providers/codemode/__init__.py +9 -0
  235. agentpool/resource_providers/codemode/code_executor.py +215 -0
  236. agentpool/resource_providers/codemode/default_prompt.py +19 -0
  237. agentpool/resource_providers/codemode/helpers.py +83 -0
  238. agentpool/resource_providers/codemode/progress_executor.py +212 -0
  239. agentpool/resource_providers/codemode/provider.py +150 -0
  240. agentpool/resource_providers/codemode/remote_mcp_execution.py +143 -0
  241. agentpool/resource_providers/codemode/remote_provider.py +171 -0
  242. agentpool/resource_providers/filtering.py +42 -0
  243. agentpool/resource_providers/mcp_provider.py +246 -0
  244. agentpool/resource_providers/plan_provider.py +196 -0
  245. agentpool/resource_providers/pool.py +69 -0
  246. agentpool/resource_providers/static.py +289 -0
  247. agentpool/running/__init__.py +20 -0
  248. agentpool/running/decorators.py +56 -0
  249. agentpool/running/discovery.py +101 -0
  250. agentpool/running/executor.py +284 -0
  251. agentpool/running/injection.py +111 -0
  252. agentpool/running/py.typed +0 -0
  253. agentpool/running/run_nodes.py +87 -0
  254. agentpool/server.py +122 -0
  255. agentpool/sessions/__init__.py +13 -0
  256. agentpool/sessions/manager.py +302 -0
  257. agentpool/sessions/models.py +71 -0
  258. agentpool/sessions/session.py +239 -0
  259. agentpool/sessions/store.py +163 -0
  260. agentpool/skills/__init__.py +5 -0
  261. agentpool/skills/manager.py +120 -0
  262. agentpool/skills/registry.py +210 -0
  263. agentpool/skills/skill.py +36 -0
  264. agentpool/storage/__init__.py +17 -0
  265. agentpool/storage/manager.py +419 -0
  266. agentpool/storage/serialization.py +136 -0
  267. agentpool/talk/__init__.py +13 -0
  268. agentpool/talk/registry.py +128 -0
  269. agentpool/talk/stats.py +159 -0
  270. agentpool/talk/talk.py +604 -0
  271. agentpool/tasks/__init__.py +20 -0
  272. agentpool/tasks/exceptions.py +25 -0
  273. agentpool/tasks/registry.py +33 -0
  274. agentpool/testing.py +129 -0
  275. agentpool/text_templates/__init__.py +39 -0
  276. agentpool/text_templates/system_prompt.jinja +30 -0
  277. agentpool/text_templates/tool_call_default.jinja +13 -0
  278. agentpool/text_templates/tool_call_markdown.jinja +25 -0
  279. agentpool/text_templates/tool_call_simple.jinja +5 -0
  280. agentpool/tools/__init__.py +16 -0
  281. agentpool/tools/base.py +269 -0
  282. agentpool/tools/exceptions.py +9 -0
  283. agentpool/tools/manager.py +255 -0
  284. agentpool/tools/tool_call_info.py +87 -0
  285. agentpool/ui/__init__.py +2 -0
  286. agentpool/ui/base.py +89 -0
  287. agentpool/ui/mock_provider.py +81 -0
  288. agentpool/ui/stdlib_provider.py +150 -0
  289. agentpool/utils/__init__.py +44 -0
  290. agentpool/utils/baseregistry.py +185 -0
  291. agentpool/utils/count_tokens.py +62 -0
  292. agentpool/utils/dag.py +184 -0
  293. agentpool/utils/importing.py +206 -0
  294. agentpool/utils/inspection.py +334 -0
  295. agentpool/utils/model_capabilities.py +25 -0
  296. agentpool/utils/network.py +28 -0
  297. agentpool/utils/now.py +22 -0
  298. agentpool/utils/parse_time.py +87 -0
  299. agentpool/utils/result_utils.py +35 -0
  300. agentpool/utils/signatures.py +305 -0
  301. agentpool/utils/streams.py +112 -0
  302. agentpool/utils/tasks.py +186 -0
  303. agentpool/vfs_registry.py +250 -0
  304. agentpool-2.1.9.dist-info/METADATA +336 -0
  305. agentpool-2.1.9.dist-info/RECORD +474 -0
  306. agentpool-2.1.9.dist-info/WHEEL +4 -0
  307. agentpool-2.1.9.dist-info/entry_points.txt +14 -0
  308. agentpool-2.1.9.dist-info/licenses/LICENSE +22 -0
  309. agentpool_cli/__init__.py +34 -0
  310. agentpool_cli/__main__.py +66 -0
  311. agentpool_cli/agent.py +175 -0
  312. agentpool_cli/cli_types.py +23 -0
  313. agentpool_cli/common.py +163 -0
  314. agentpool_cli/create.py +175 -0
  315. agentpool_cli/history.py +217 -0
  316. agentpool_cli/log.py +78 -0
  317. agentpool_cli/py.typed +0 -0
  318. agentpool_cli/run.py +84 -0
  319. agentpool_cli/serve_acp.py +177 -0
  320. agentpool_cli/serve_api.py +69 -0
  321. agentpool_cli/serve_mcp.py +74 -0
  322. agentpool_cli/serve_vercel.py +233 -0
  323. agentpool_cli/store.py +171 -0
  324. agentpool_cli/task.py +84 -0
  325. agentpool_cli/utils.py +104 -0
  326. agentpool_cli/watch.py +54 -0
  327. agentpool_commands/__init__.py +180 -0
  328. agentpool_commands/agents.py +199 -0
  329. agentpool_commands/base.py +45 -0
  330. agentpool_commands/commands.py +58 -0
  331. agentpool_commands/completers.py +110 -0
  332. agentpool_commands/connections.py +175 -0
  333. agentpool_commands/markdown_utils.py +31 -0
  334. agentpool_commands/models.py +62 -0
  335. agentpool_commands/prompts.py +78 -0
  336. agentpool_commands/py.typed +0 -0
  337. agentpool_commands/read.py +77 -0
  338. agentpool_commands/resources.py +210 -0
  339. agentpool_commands/session.py +48 -0
  340. agentpool_commands/tools.py +269 -0
  341. agentpool_commands/utils.py +189 -0
  342. agentpool_commands/workers.py +163 -0
  343. agentpool_config/__init__.py +53 -0
  344. agentpool_config/builtin_tools.py +265 -0
  345. agentpool_config/commands.py +237 -0
  346. agentpool_config/conditions.py +301 -0
  347. agentpool_config/converters.py +30 -0
  348. agentpool_config/durable.py +331 -0
  349. agentpool_config/event_handlers.py +600 -0
  350. agentpool_config/events.py +153 -0
  351. agentpool_config/forward_targets.py +251 -0
  352. agentpool_config/hook_conditions.py +331 -0
  353. agentpool_config/hooks.py +241 -0
  354. agentpool_config/jinja.py +206 -0
  355. agentpool_config/knowledge.py +41 -0
  356. agentpool_config/loaders.py +350 -0
  357. agentpool_config/mcp_server.py +243 -0
  358. agentpool_config/nodes.py +202 -0
  359. agentpool_config/observability.py +191 -0
  360. agentpool_config/output_types.py +55 -0
  361. agentpool_config/pool_server.py +267 -0
  362. agentpool_config/prompt_hubs.py +105 -0
  363. agentpool_config/prompts.py +185 -0
  364. agentpool_config/py.typed +0 -0
  365. agentpool_config/resources.py +33 -0
  366. agentpool_config/session.py +119 -0
  367. agentpool_config/skills.py +17 -0
  368. agentpool_config/storage.py +288 -0
  369. agentpool_config/system_prompts.py +190 -0
  370. agentpool_config/task.py +162 -0
  371. agentpool_config/teams.py +52 -0
  372. agentpool_config/tools.py +112 -0
  373. agentpool_config/toolsets.py +1033 -0
  374. agentpool_config/workers.py +86 -0
  375. agentpool_prompts/__init__.py +1 -0
  376. agentpool_prompts/braintrust_hub.py +235 -0
  377. agentpool_prompts/fabric.py +75 -0
  378. agentpool_prompts/langfuse_hub.py +79 -0
  379. agentpool_prompts/promptlayer_provider.py +59 -0
  380. agentpool_prompts/py.typed +0 -0
  381. agentpool_server/__init__.py +9 -0
  382. agentpool_server/a2a_server/__init__.py +5 -0
  383. agentpool_server/a2a_server/a2a_types.py +41 -0
  384. agentpool_server/a2a_server/server.py +190 -0
  385. agentpool_server/a2a_server/storage.py +81 -0
  386. agentpool_server/acp_server/__init__.py +22 -0
  387. agentpool_server/acp_server/acp_agent.py +786 -0
  388. agentpool_server/acp_server/acp_tools.py +43 -0
  389. agentpool_server/acp_server/commands/__init__.py +18 -0
  390. agentpool_server/acp_server/commands/acp_commands.py +594 -0
  391. agentpool_server/acp_server/commands/debug_commands.py +376 -0
  392. agentpool_server/acp_server/commands/docs_commands/__init__.py +39 -0
  393. agentpool_server/acp_server/commands/docs_commands/fetch_repo.py +169 -0
  394. agentpool_server/acp_server/commands/docs_commands/get_schema.py +176 -0
  395. agentpool_server/acp_server/commands/docs_commands/get_source.py +110 -0
  396. agentpool_server/acp_server/commands/docs_commands/git_diff.py +111 -0
  397. agentpool_server/acp_server/commands/docs_commands/helpers.py +33 -0
  398. agentpool_server/acp_server/commands/docs_commands/url_to_markdown.py +90 -0
  399. agentpool_server/acp_server/commands/spawn.py +210 -0
  400. agentpool_server/acp_server/converters.py +235 -0
  401. agentpool_server/acp_server/input_provider.py +338 -0
  402. agentpool_server/acp_server/server.py +288 -0
  403. agentpool_server/acp_server/session.py +969 -0
  404. agentpool_server/acp_server/session_manager.py +313 -0
  405. agentpool_server/acp_server/syntax_detection.py +250 -0
  406. agentpool_server/acp_server/zed_tools.md +90 -0
  407. agentpool_server/aggregating_server.py +309 -0
  408. agentpool_server/agui_server/__init__.py +11 -0
  409. agentpool_server/agui_server/server.py +128 -0
  410. agentpool_server/base.py +189 -0
  411. agentpool_server/http_server.py +164 -0
  412. agentpool_server/mcp_server/__init__.py +6 -0
  413. agentpool_server/mcp_server/server.py +314 -0
  414. agentpool_server/mcp_server/zed_wrapper.py +110 -0
  415. agentpool_server/openai_api_server/__init__.py +5 -0
  416. agentpool_server/openai_api_server/completions/__init__.py +1 -0
  417. agentpool_server/openai_api_server/completions/helpers.py +81 -0
  418. agentpool_server/openai_api_server/completions/models.py +98 -0
  419. agentpool_server/openai_api_server/responses/__init__.py +1 -0
  420. agentpool_server/openai_api_server/responses/helpers.py +74 -0
  421. agentpool_server/openai_api_server/responses/models.py +96 -0
  422. agentpool_server/openai_api_server/server.py +242 -0
  423. agentpool_server/py.typed +0 -0
  424. agentpool_storage/__init__.py +9 -0
  425. agentpool_storage/base.py +310 -0
  426. agentpool_storage/file_provider.py +378 -0
  427. agentpool_storage/formatters.py +129 -0
  428. agentpool_storage/memory_provider.py +396 -0
  429. agentpool_storage/models.py +108 -0
  430. agentpool_storage/py.typed +0 -0
  431. agentpool_storage/session_store.py +262 -0
  432. agentpool_storage/sql_provider/__init__.py +21 -0
  433. agentpool_storage/sql_provider/cli.py +146 -0
  434. agentpool_storage/sql_provider/models.py +249 -0
  435. agentpool_storage/sql_provider/queries.py +15 -0
  436. agentpool_storage/sql_provider/sql_provider.py +444 -0
  437. agentpool_storage/sql_provider/utils.py +234 -0
  438. agentpool_storage/text_log_provider.py +275 -0
  439. agentpool_toolsets/__init__.py +15 -0
  440. agentpool_toolsets/builtin/__init__.py +33 -0
  441. agentpool_toolsets/builtin/agent_management.py +239 -0
  442. agentpool_toolsets/builtin/chain.py +288 -0
  443. agentpool_toolsets/builtin/code.py +398 -0
  444. agentpool_toolsets/builtin/debug.py +291 -0
  445. agentpool_toolsets/builtin/execution_environment.py +381 -0
  446. agentpool_toolsets/builtin/file_edit/__init__.py +11 -0
  447. agentpool_toolsets/builtin/file_edit/file_edit.py +747 -0
  448. agentpool_toolsets/builtin/file_edit/fuzzy_matcher/__init__.py +5 -0
  449. agentpool_toolsets/builtin/file_edit/fuzzy_matcher/example_usage.py +311 -0
  450. agentpool_toolsets/builtin/file_edit/fuzzy_matcher/streaming_fuzzy_matcher.py +443 -0
  451. agentpool_toolsets/builtin/history.py +36 -0
  452. agentpool_toolsets/builtin/integration.py +85 -0
  453. agentpool_toolsets/builtin/skills.py +77 -0
  454. agentpool_toolsets/builtin/subagent_tools.py +324 -0
  455. agentpool_toolsets/builtin/tool_management.py +90 -0
  456. agentpool_toolsets/builtin/user_interaction.py +52 -0
  457. agentpool_toolsets/builtin/workers.py +128 -0
  458. agentpool_toolsets/composio_toolset.py +96 -0
  459. agentpool_toolsets/config_creation.py +192 -0
  460. agentpool_toolsets/entry_points.py +47 -0
  461. agentpool_toolsets/fsspec_toolset/__init__.py +7 -0
  462. agentpool_toolsets/fsspec_toolset/diagnostics.py +115 -0
  463. agentpool_toolsets/fsspec_toolset/grep.py +450 -0
  464. agentpool_toolsets/fsspec_toolset/helpers.py +631 -0
  465. agentpool_toolsets/fsspec_toolset/streaming_diff_parser.py +249 -0
  466. agentpool_toolsets/fsspec_toolset/toolset.py +1384 -0
  467. agentpool_toolsets/mcp_run_toolset.py +61 -0
  468. agentpool_toolsets/notifications.py +146 -0
  469. agentpool_toolsets/openapi.py +118 -0
  470. agentpool_toolsets/py.typed +0 -0
  471. agentpool_toolsets/search_toolset.py +202 -0
  472. agentpool_toolsets/semantic_memory_toolset.py +536 -0
  473. agentpool_toolsets/streaming_tools.py +265 -0
  474. agentpool_toolsets/vfs_toolset.py +124 -0
@@ -0,0 +1,310 @@
1
+ """Storage provider base class."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections import defaultdict
6
+ from datetime import datetime
7
+ from typing import TYPE_CHECKING, Any, Literal, Self
8
+ from uuid import uuid4
9
+
10
+ from agentpool.utils.tasks import TaskManager
11
+
12
+
13
+ if TYPE_CHECKING:
14
+ from collections.abc import Sequence
15
+ from datetime import datetime
16
+ from types import TracebackType
17
+
18
+ from pydantic_ai import FinishReason
19
+
20
+ from agentpool.common_types import JsonValue
21
+ from agentpool.messaging import ChatMessage, TokenCost
22
+ from agentpool_config.session import SessionQuery
23
+ from agentpool_config.storage import BaseStorageProviderConfig
24
+ from agentpool_storage.models import ConversationData, QueryFilters, StatsFilters
25
+
26
+
27
+ class StoredMessage:
28
+ """Base class for stored message data."""
29
+
30
+ id: str
31
+ conversation_id: str
32
+ timestamp: datetime
33
+ role: str
34
+ content: str
35
+ name: str | None = None
36
+ model: str | None = None
37
+ token_usage: dict[str, int] | None = None
38
+ cost: float | None = None
39
+ response_time: float | None = None
40
+ forwarded_from: list[str] | None = None
41
+
42
+
43
+ class StoredConversation:
44
+ """Base class for stored conversation data."""
45
+
46
+ id: str
47
+ agent_name: str
48
+ start_time: datetime
49
+ total_tokens: int = 0
50
+ total_cost: float = 0.0
51
+
52
+
53
+ class StorageProvider:
54
+ """Base class for storage providers."""
55
+
56
+ can_load_history: bool = False
57
+ """Whether this provider supports loading history."""
58
+
59
+ def __init__(self, config: BaseStorageProviderConfig) -> None:
60
+ super().__init__()
61
+ self.config = config
62
+ self.task_manager = TaskManager()
63
+ self.log_messages = config.log_messages
64
+ self.log_conversations = config.log_conversations
65
+ self.log_commands = config.log_commands
66
+ self.log_context = config.log_context
67
+
68
+ async def __aenter__(self) -> Self:
69
+ """Initialize provider resources."""
70
+ return self
71
+
72
+ async def __aexit__(
73
+ self,
74
+ exc_type: type[BaseException] | None,
75
+ exc_val: BaseException | None,
76
+ exc_tb: TracebackType | None,
77
+ ) -> None:
78
+ """Clean up provider resources."""
79
+ self.cleanup()
80
+
81
+ def cleanup(self) -> None:
82
+ """Clean up resources."""
83
+
84
+ def should_log_agent(self, agent_name: str) -> bool:
85
+ """Check if this provider should log the given agent."""
86
+ return self.config.agents is None or agent_name in self.config.agents
87
+
88
+ async def filter_messages(self, query: SessionQuery) -> list[ChatMessage[str]]:
89
+ """Get messages matching query (if supported)."""
90
+ msg = f"{self.__class__.__name__} does not support loading history"
91
+ raise NotImplementedError(msg)
92
+
93
+ async def log_message(
94
+ self,
95
+ *,
96
+ conversation_id: str,
97
+ message_id: str,
98
+ content: str,
99
+ role: str,
100
+ name: str | None = None,
101
+ cost_info: TokenCost | None = None,
102
+ model: str | None = None,
103
+ response_time: float | None = None,
104
+ forwarded_from: list[str] | None = None,
105
+ provider_name: str | None = None,
106
+ provider_response_id: str | None = None,
107
+ messages: str | None = None,
108
+ finish_reason: FinishReason | None = None,
109
+ ) -> None:
110
+ """Log a message (if supported)."""
111
+
112
+ async def log_conversation(
113
+ self,
114
+ *,
115
+ conversation_id: str,
116
+ node_name: str,
117
+ start_time: datetime | None = None,
118
+ ) -> None:
119
+ """Log a conversation (if supported)."""
120
+
121
+ async def update_conversation_title(
122
+ self,
123
+ conversation_id: str,
124
+ title: str,
125
+ ) -> None:
126
+ """Update the title of a conversation.
127
+
128
+ Args:
129
+ conversation_id: ID of the conversation to update
130
+ title: New title for the conversation
131
+ """
132
+
133
+ async def get_conversation_title(
134
+ self,
135
+ conversation_id: str,
136
+ ) -> str | None:
137
+ """Get the title of a conversation.
138
+
139
+ Args:
140
+ conversation_id: ID of the conversation
141
+
142
+ Returns:
143
+ The conversation title, or None if not set or conversation doesn't exist.
144
+ """
145
+ return None
146
+
147
+ async def log_command(
148
+ self,
149
+ *,
150
+ agent_name: str,
151
+ session_id: str,
152
+ command: str,
153
+ context_type: type | None = None,
154
+ metadata: dict[str, JsonValue] | None = None,
155
+ ) -> None:
156
+ """Log a command (if supported)."""
157
+
158
+ async def get_commands(
159
+ self,
160
+ agent_name: str,
161
+ session_id: str,
162
+ *,
163
+ limit: int | None = None,
164
+ current_session_only: bool = False,
165
+ ) -> list[str]:
166
+ """Get command history (if supported)."""
167
+ msg = f"{self.__class__.__name__} does not support retrieving commands"
168
+ raise NotImplementedError(msg)
169
+
170
+ async def log_context_message(
171
+ self,
172
+ *,
173
+ conversation_id: str,
174
+ content: str,
175
+ role: str,
176
+ name: str | None = None,
177
+ model: str | None = None,
178
+ message_id: str | None = None,
179
+ metadata: dict[str, Any] | None = None,
180
+ ) -> None:
181
+ """Log a context message if context logging is enabled."""
182
+ if not self.log_context:
183
+ return
184
+
185
+ await self.log_message(
186
+ conversation_id=conversation_id,
187
+ message_id=message_id or str(uuid4()),
188
+ content=content,
189
+ role=role,
190
+ name=name,
191
+ model=model,
192
+ )
193
+
194
+ async def get_conversations(
195
+ self,
196
+ filters: QueryFilters,
197
+ ) -> list[tuple[ConversationData, Sequence[ChatMessage[str]]]]:
198
+ """Get filtered conversations with their messages.
199
+
200
+ Args:
201
+ filters: Query filters to apply
202
+ """
203
+ msg = f"{self.__class__.__name__} does not support conversation queries"
204
+ raise NotImplementedError(msg)
205
+
206
+ async def get_filtered_conversations(
207
+ self,
208
+ agent_name: str | None = None,
209
+ period: str | None = None,
210
+ since: datetime | None = None,
211
+ query: str | None = None,
212
+ model: str | None = None,
213
+ limit: int | None = None,
214
+ *,
215
+ compact: bool = False,
216
+ include_tokens: bool = False,
217
+ ) -> list[ConversationData]:
218
+ """Get filtered conversations with formatted output.
219
+
220
+ Args:
221
+ agent_name: Filter by agent name
222
+ period: Time period to include (e.g. "1h", "2d")
223
+ since: Only show conversations after this time
224
+ query: Search in message content
225
+ model: Filter by model used
226
+ limit: Maximum number of conversations
227
+ compact: Only show first/last message of each conversation
228
+ include_tokens: Include token usage statistics
229
+ """
230
+ msg = f"{self.__class__.__name__} does not support filtered conversations"
231
+ raise NotImplementedError(msg)
232
+
233
+ async def get_conversation_stats(
234
+ self,
235
+ filters: StatsFilters,
236
+ ) -> dict[str, dict[str, Any]]:
237
+ """Get conversation statistics grouped by specified criterion.
238
+
239
+ Args:
240
+ filters: Filters for statistics query
241
+ """
242
+ msg = f"{self.__class__.__name__} does not support statistics"
243
+ raise NotImplementedError(msg)
244
+
245
+ def aggregate_stats(
246
+ self,
247
+ rows: Sequence[tuple[str | None, str | None, datetime, TokenCost | None]],
248
+ group_by: Literal["agent", "model", "hour", "day"],
249
+ ) -> dict[str, dict[str, Any]]:
250
+ """Aggregate statistics data by specified grouping.
251
+
252
+ Args:
253
+ rows: Raw stats data (model, agent, timestamp, token_usage)
254
+ group_by: How to group the statistics
255
+ """
256
+ stats: dict[str, dict[str, Any]] = defaultdict(
257
+ lambda: {"total_tokens": 0, "messages": 0, "models": set()}
258
+ )
259
+
260
+ for model, agent, timestamp, token_usage in rows:
261
+ match group_by:
262
+ case "agent":
263
+ key = agent or "unknown"
264
+ case "model":
265
+ key = model or "unknown"
266
+ case "hour":
267
+ key = timestamp.strftime("%Y-%m-%d %H:00")
268
+ case "day":
269
+ key = timestamp.strftime("%Y-%m-%d")
270
+
271
+ entry = stats[key]
272
+ entry["messages"] += 1
273
+ if token_usage:
274
+ entry["total_tokens"] += token_usage.token_usage.total_tokens
275
+ if model:
276
+ entry["models"].add(model)
277
+
278
+ return stats
279
+
280
+ async def reset(
281
+ self,
282
+ *,
283
+ agent_name: str | None = None,
284
+ hard: bool = False,
285
+ ) -> tuple[int, int]:
286
+ """Reset storage, optionally for specific agent only.
287
+
288
+ Args:
289
+ agent_name: Only reset data for this agent
290
+ hard: Whether to completely reset storage (e.g., recreate tables)
291
+
292
+ Returns:
293
+ Tuple of (conversations deleted, messages deleted)
294
+ """
295
+ raise NotImplementedError
296
+
297
+ async def get_conversation_counts(
298
+ self,
299
+ *,
300
+ agent_name: str | None = None,
301
+ ) -> tuple[int, int]:
302
+ """Get counts of conversations and messages.
303
+
304
+ Args:
305
+ agent_name: Only count data for this agent
306
+
307
+ Returns:
308
+ Tuple of (conversation count, message count)
309
+ """
310
+ raise NotImplementedError
@@ -0,0 +1,378 @@
1
+ """File provider implementation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from datetime import datetime
6
+ from decimal import Decimal
7
+ from typing import TYPE_CHECKING, TypedDict, cast
8
+
9
+ from pydantic_ai import RunUsage
10
+ from upathtools import to_upath
11
+
12
+ from agentpool.common_types import JsonValue, MessageRole # noqa: TC001
13
+ from agentpool.log import get_logger
14
+ from agentpool.messaging import ChatMessage, TokenCost
15
+ from agentpool.storage import deserialize_messages
16
+ from agentpool.utils.now import get_now
17
+ from agentpool_storage.base import StorageProvider
18
+ from agentpool_storage.models import TokenUsage
19
+
20
+
21
+ if TYPE_CHECKING:
22
+ from pydantic_ai import FinishReason
23
+ from yamling import FormatType
24
+
25
+ from agentpool_config.session import SessionQuery
26
+ from agentpool_config.storage import FileStorageConfig
27
+
28
+ logger = get_logger(__name__)
29
+
30
+
31
+ class MessageData(TypedDict):
32
+ """Data structure for storing message information."""
33
+
34
+ message_id: str
35
+ conversation_id: str
36
+ content: str
37
+ role: str
38
+ timestamp: str
39
+ name: str | None
40
+ model: str | None
41
+ cost: Decimal | None
42
+ token_usage: TokenUsage | None
43
+ response_time: float | None
44
+ forwarded_from: list[str] | None
45
+ provider_name: str | None
46
+ provider_response_id: str | None
47
+ messages: str | None
48
+ finish_reason: FinishReason | None
49
+
50
+
51
+ class ConversationData(TypedDict):
52
+ """Data structure for storing conversation information."""
53
+
54
+ id: str
55
+ agent_name: str
56
+ title: str | None
57
+ start_time: str
58
+
59
+
60
+ class CommandData(TypedDict):
61
+ """Data structure for storing command information."""
62
+
63
+ agent_name: str
64
+ session_id: str
65
+ command: str
66
+ timestamp: str
67
+ context_type: str | None
68
+ metadata: dict[str, JsonValue]
69
+
70
+
71
+ class StorageData(TypedDict):
72
+ """Data structure for storing storage information."""
73
+
74
+ messages: list[MessageData]
75
+ conversations: list[ConversationData]
76
+ commands: list[CommandData]
77
+
78
+
79
+ class FileProvider(StorageProvider):
80
+ """File-based storage using various formats.
81
+
82
+ Automatically detects format from file extension or uses specified format.
83
+ Supported formats: YAML (.yml, .yaml), JSON (.json), TOML (.toml)
84
+ """
85
+
86
+ can_load_history = True
87
+
88
+ def __init__(self, config: FileStorageConfig) -> None:
89
+ """Initialize file provider.
90
+
91
+ Args:
92
+ config: Configuration for provider
93
+ """
94
+ super().__init__(config)
95
+ self.path = to_upath(config.path)
96
+ self.format: FormatType = config.format
97
+ self.encoding = config.encoding
98
+ self._data: StorageData = {
99
+ "messages": [],
100
+ "conversations": [],
101
+ "commands": [],
102
+ }
103
+ self._load()
104
+
105
+ def _load(self) -> None:
106
+ """Load data from file if it exists."""
107
+ import yamling
108
+
109
+ if self.path.exists():
110
+ self._data = yamling.load_file(
111
+ self.path,
112
+ self.format, # pyright: ignore
113
+ verify_type=StorageData,
114
+ )
115
+ self._save()
116
+
117
+ def _save(self) -> None:
118
+ """Save current data to file."""
119
+ import yamling
120
+
121
+ self.path.parent.mkdir(parents=True, exist_ok=True)
122
+ yamling.dump_file(self._data, self.path, mode=self.format, overwrite=True)
123
+
124
+ def cleanup(self) -> None:
125
+ """Save final state."""
126
+ self._save()
127
+
128
+ async def filter_messages(self, query: SessionQuery) -> list[ChatMessage[str]]:
129
+ """Filter messages based on query."""
130
+ messages = []
131
+ for msg in self._data["messages"]:
132
+ # Apply filters
133
+ if query.name and msg["conversation_id"] != query.name:
134
+ continue
135
+ if query.agents and not (
136
+ msg["name"] in query.agents
137
+ or (
138
+ query.include_forwarded
139
+ and msg["forwarded_from"]
140
+ and any(a in query.agents for a in msg["forwarded_from"])
141
+ )
142
+ ):
143
+ continue
144
+ cutoff = query.get_time_cutoff()
145
+ timestamp = datetime.fromisoformat(msg["timestamp"])
146
+ if query.since and cutoff and (timestamp < cutoff):
147
+ continue
148
+ if query.until and datetime.fromisoformat(msg["timestamp"]) > datetime.fromisoformat(
149
+ query.until
150
+ ):
151
+ continue
152
+ if query.contains and query.contains not in msg["content"]:
153
+ continue
154
+ if query.roles and msg["role"] not in query.roles:
155
+ continue
156
+
157
+ # Convert to ChatMessage
158
+ cost_info = None
159
+ if msg["token_usage"]:
160
+ usage = msg["token_usage"]
161
+ cost = Decimal(msg["cost"] or 0.0)
162
+ cost_info = TokenCost(
163
+ token_usage=RunUsage(
164
+ input_tokens=usage["prompt"],
165
+ output_tokens=usage["completion"],
166
+ ),
167
+ total_cost=cost,
168
+ )
169
+
170
+ chat_message = ChatMessage[str](
171
+ content=msg["content"],
172
+ conversation_id=msg["conversation_id"],
173
+ role=cast(MessageRole, msg["role"]),
174
+ name=msg["name"],
175
+ model_name=msg["model"],
176
+ cost_info=cost_info,
177
+ response_time=msg["response_time"],
178
+ forwarded_from=msg["forwarded_from"] or [],
179
+ timestamp=datetime.fromisoformat(msg["timestamp"]),
180
+ provider_name=msg["provider_name"],
181
+ provider_response_id=msg["provider_response_id"],
182
+ messages=deserialize_messages(msg["messages"]),
183
+ finish_reason=msg["finish_reason"],
184
+ )
185
+ messages.append(chat_message)
186
+
187
+ if query.limit and len(messages) >= query.limit:
188
+ break
189
+
190
+ return messages
191
+
192
+ async def log_message(
193
+ self,
194
+ *,
195
+ message_id: str,
196
+ conversation_id: str,
197
+ content: str,
198
+ role: str,
199
+ name: str | None = None,
200
+ cost_info: TokenCost | None = None,
201
+ model: str | None = None,
202
+ response_time: float | None = None,
203
+ forwarded_from: list[str] | None = None,
204
+ provider_name: str | None = None,
205
+ provider_response_id: str | None = None,
206
+ messages: str | None = None,
207
+ finish_reason: FinishReason | None = None,
208
+ ) -> None:
209
+ """Log a new message."""
210
+ self._data["messages"].append({
211
+ "conversation_id": conversation_id,
212
+ "message_id": message_id,
213
+ "content": content,
214
+ "role": cast(MessageRole, role),
215
+ "timestamp": get_now().isoformat(),
216
+ "name": name,
217
+ "model": model,
218
+ "cost": Decimal(cost_info.total_cost) if cost_info else None,
219
+ "token_usage": TokenUsage(
220
+ prompt=cost_info.token_usage.input_tokens if cost_info else 0,
221
+ completion=cost_info.token_usage.output_tokens if cost_info else 0,
222
+ total=cost_info.token_usage.total_tokens if cost_info else 0,
223
+ ),
224
+ "response_time": response_time,
225
+ "forwarded_from": forwarded_from,
226
+ "provider_name": provider_name,
227
+ "provider_response_id": provider_response_id,
228
+ "messages": messages,
229
+ "finish_reason": finish_reason,
230
+ })
231
+ self._save()
232
+
233
+ async def log_conversation(
234
+ self,
235
+ *,
236
+ conversation_id: str,
237
+ node_name: str,
238
+ start_time: datetime | None = None,
239
+ ) -> None:
240
+ """Log a new conversation."""
241
+ conversation: ConversationData = {
242
+ "id": conversation_id,
243
+ "agent_name": node_name,
244
+ "title": None,
245
+ "start_time": (start_time or get_now()).isoformat(),
246
+ }
247
+ self._data["conversations"].append(conversation)
248
+ self._save()
249
+
250
+ async def update_conversation_title(
251
+ self,
252
+ conversation_id: str,
253
+ title: str,
254
+ ) -> None:
255
+ """Update the title of a conversation."""
256
+ for conv in self._data["conversations"]:
257
+ if conv["id"] == conversation_id:
258
+ conv["title"] = title
259
+ self._save()
260
+ return
261
+
262
+ async def get_conversation_title(
263
+ self,
264
+ conversation_id: str,
265
+ ) -> str | None:
266
+ """Get the title of a conversation."""
267
+ for conv in self._data["conversations"]:
268
+ if conv["id"] == conversation_id:
269
+ return conv.get("title")
270
+ return None
271
+
272
+ async def log_command(
273
+ self,
274
+ *,
275
+ agent_name: str,
276
+ session_id: str,
277
+ command: str,
278
+ context_type: type | None = None,
279
+ metadata: dict[str, JsonValue] | None = None,
280
+ ) -> None:
281
+ """Log a command execution."""
282
+ cmd: CommandData = {
283
+ "agent_name": agent_name,
284
+ "session_id": session_id,
285
+ "command": command,
286
+ "context_type": context_type.__name__ if context_type else None,
287
+ "metadata": metadata or {},
288
+ "timestamp": get_now().isoformat(),
289
+ }
290
+ self._data["commands"].append(cmd)
291
+ self._save()
292
+
293
+ async def get_commands(
294
+ self,
295
+ agent_name: str,
296
+ session_id: str,
297
+ *,
298
+ limit: int | None = None,
299
+ current_session_only: bool = False,
300
+ ) -> list[str]:
301
+ """Get command history."""
302
+ commands = []
303
+ for cmd in reversed(self._data["commands"]): # newest first
304
+ if current_session_only and cmd["session_id"] != session_id:
305
+ continue
306
+ if not current_session_only and cmd["agent_name"] != agent_name:
307
+ continue
308
+ commands.append(cmd["command"])
309
+ if limit and len(commands) >= limit:
310
+ break
311
+ return commands
312
+
313
+ async def reset(
314
+ self,
315
+ *,
316
+ agent_name: str | None = None,
317
+ hard: bool = False,
318
+ ) -> tuple[int, int]:
319
+ """Reset stored data."""
320
+ # Get counts first
321
+ conv_count, msg_count = await self.get_conversation_counts(agent_name=agent_name)
322
+
323
+ if hard:
324
+ if agent_name:
325
+ msg = "Hard reset cannot be used with agent_name"
326
+ raise ValueError(msg)
327
+ # Clear everything
328
+ self._data = {
329
+ "messages": [],
330
+ "conversations": [],
331
+ "commands": [],
332
+ }
333
+ self._save()
334
+ return conv_count, msg_count
335
+
336
+ if agent_name:
337
+ # Filter out data for specific agent
338
+ self._data["conversations"] = [
339
+ c for c in self._data["conversations"] if c["agent_name"] != agent_name
340
+ ]
341
+ self._data["messages"] = [
342
+ m
343
+ for m in self._data["messages"]
344
+ if m["conversation_id"]
345
+ not in {
346
+ c["id"] for c in self._data["conversations"] if c["agent_name"] == agent_name
347
+ }
348
+ ]
349
+ else:
350
+ # Clear all
351
+ self._data["messages"].clear()
352
+ self._data["conversations"].clear()
353
+ self._data["commands"].clear()
354
+
355
+ self._save()
356
+ return conv_count, msg_count
357
+
358
+ async def get_conversation_counts(
359
+ self,
360
+ *,
361
+ agent_name: str | None = None,
362
+ ) -> tuple[int, int]:
363
+ """Get conversation and message counts."""
364
+ if agent_name:
365
+ conv_count = sum(
366
+ 1 for c in self._data["conversations"] if c["agent_name"] == agent_name
367
+ )
368
+ msg_count = sum(
369
+ 1
370
+ for m in self._data["messages"]
371
+ if m["conversation_id"]
372
+ in {c["id"] for c in self._data["conversations"] if c["agent_name"] == agent_name}
373
+ )
374
+ else:
375
+ conv_count = len(self._data["conversations"])
376
+ msg_count = len(self._data["messages"])
377
+
378
+ return conv_count, msg_count