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,129 @@
1
+ """Formatting utilities."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Any, Literal, TypeGuard, assert_never
6
+
7
+ from rich.console import Console
8
+ from rich.markdown import Markdown
9
+
10
+
11
+ if TYPE_CHECKING:
12
+ from agentpool_storage.models import ConversationData
13
+
14
+
15
+ def is_conversation_data(data: Any) -> TypeGuard[ConversationData]:
16
+ """Type guard for ConversationData."""
17
+ return (
18
+ isinstance(data, dict)
19
+ and "id" in data
20
+ and "messages" in data
21
+ and "agent" in data
22
+ and "start_time" in data
23
+ )
24
+
25
+
26
+ def format_output(
27
+ data: ConversationData | list[ConversationData] | dict[str, Any],
28
+ output_format: Literal["json", "yaml", "text"] = "text",
29
+ ) -> str:
30
+ """Format data for output in specified format.
31
+
32
+ Args:
33
+ data: Data to format
34
+ output_format: Format to use (text/json/yaml)
35
+ """
36
+ import anyenv
37
+
38
+ match output_format:
39
+ case "json":
40
+ return anyenv.dump_json(data, indent=True)
41
+ case "yaml":
42
+ import yamling
43
+
44
+ return yamling.dump_yaml(data)
45
+ case "text":
46
+ console = Console(record=True)
47
+ if is_conversation_data(data):
48
+ # Single conversation
49
+ _print_conversation(console, data) # ty: ignore
50
+ elif isinstance(data, list):
51
+ # Multiple conversations
52
+ for conv in data:
53
+ if is_conversation_data(conv):
54
+ _print_conversation(console, conv)
55
+ console.print()
56
+ else:
57
+ # At this point, data must be a stats dict
58
+ stats_data: dict[str, Any] = data # type: ignore
59
+ _print_stats(console, stats_data)
60
+ return console.export_text()
61
+ case _ as unreachable:
62
+ assert_never(unreachable)
63
+
64
+
65
+ def _print_conversation(console: Console, conv: ConversationData) -> None:
66
+ """Print a conversation in text format."""
67
+ console.print(f"\n[bold blue]Conversation {conv['id']}[/]")
68
+ console.print(f"Agent: {conv['agent']}, Started: {conv['start_time']}\n")
69
+
70
+ if token_usage := conv.get("token_usage"):
71
+ console.print(
72
+ "[dim]"
73
+ f"Tokens: {token_usage['total']:,} total "
74
+ f"({token_usage['prompt']:,} prompt, "
75
+ f"{token_usage['completion']:,} completion)"
76
+ "[/]"
77
+ )
78
+ console.print()
79
+
80
+ for msg in conv["messages"]:
81
+ role_color = "green" if msg["role"] == "assistant" else "yellow"
82
+ text = f"[{role_color}]{msg['role'].title()}:[/] ({msg['timestamp']})"
83
+ console.print(text)
84
+ console.print(Markdown(msg["content"]))
85
+ if msg.get("model"):
86
+ console.print(f"[dim]Model: {msg['model']}[/]", highlight=False)
87
+ console.print()
88
+
89
+
90
+ def _print_stats(console: Console, stats: dict[str, Any]) -> None:
91
+ """Print statistics in text format."""
92
+ if "period" in stats:
93
+ console.print(f"\n[bold]Usage Statistics ({stats['period']})[/]")
94
+ console.print(f"Grouped by: {stats.get('group_by', 'unknown')}\n")
95
+
96
+ for entry in stats.get("entries", [stats]):
97
+ console.print(f"[blue]{entry['name']}[/]")
98
+ console.print(f" Messages: {entry['messages']}")
99
+ console.print(f" Total tokens: {entry['total_tokens']:,}")
100
+ if "models" in entry:
101
+ console.print(" Models: " + ", ".join(entry["models"]))
102
+ console.print()
103
+
104
+
105
+ def format_stats(
106
+ stats: dict[str, dict[str, Any]],
107
+ period: str,
108
+ group_by: str,
109
+ ) -> dict[str, Any]:
110
+ """Format statistics for output.
111
+
112
+ Args:
113
+ stats: Raw statistics data
114
+ period: Time period string (e.g. "1d")
115
+ group_by: Grouping criterion used
116
+
117
+ Returns:
118
+ Formatted statistics ready for display
119
+ """
120
+ entries = [
121
+ {
122
+ "name": key,
123
+ "messages": data["messages"],
124
+ "total_tokens": data["total_tokens"],
125
+ "models": sorted(data["models"]),
126
+ }
127
+ for key, data in stats.items()
128
+ ]
129
+ return {"period": period, "group_by": group_by, "entries": entries}
@@ -0,0 +1,396 @@
1
+ """In-memory storage provider for testing."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from datetime import datetime
6
+ from typing import TYPE_CHECKING, Any, cast
7
+
8
+ from agentpool.messaging import ChatMessage, TokenCost
9
+ from agentpool.storage import deserialize_messages
10
+ from agentpool.utils.now import get_now
11
+ from agentpool_storage.base import StorageProvider
12
+ from agentpool_storage.models import ConversationData
13
+
14
+
15
+ if TYPE_CHECKING:
16
+ from collections.abc import Sequence
17
+
18
+ from agentpool.common_types import JsonValue
19
+ from agentpool_config.session import SessionQuery
20
+ from agentpool_config.storage import MemoryStorageConfig
21
+ from agentpool_storage.models import MessageData, QueryFilters, StatsFilters, TokenUsage
22
+
23
+
24
+ class MemoryStorageProvider(StorageProvider):
25
+ """In-memory storage provider for testing."""
26
+
27
+ can_load_history = True
28
+
29
+ def __init__(self, config: MemoryStorageConfig) -> None:
30
+ super().__init__(config)
31
+ self.messages: list[dict[str, Any]] = []
32
+ self.conversations: list[dict[str, Any]] = []
33
+ self.commands: list[dict[str, Any]] = []
34
+
35
+ def cleanup(self) -> None:
36
+ """Clear all stored data."""
37
+ self.messages.clear()
38
+ self.conversations.clear()
39
+ self.commands.clear()
40
+
41
+ async def filter_messages(self, query: SessionQuery) -> list[ChatMessage[str]]:
42
+ """Filter messages from memory."""
43
+ from agentpool.messaging import ChatMessage
44
+
45
+ filtered = []
46
+ for msg in self.messages:
47
+ # Skip if conversation ID doesn't match
48
+ if query.name and msg["conversation_id"] != query.name:
49
+ continue
50
+
51
+ # Skip if agent name doesn't match
52
+ if query.agents and not (
53
+ msg["name"] in query.agents
54
+ or (
55
+ query.include_forwarded
56
+ and msg["forwarded_from"]
57
+ and any(a in query.agents for a in msg["forwarded_from"])
58
+ )
59
+ ):
60
+ continue
61
+
62
+ # Skip if before cutoff time
63
+ if query.since and (cutoff := query.get_time_cutoff()): # noqa: SIM102
64
+ if msg["timestamp"] < cutoff:
65
+ continue
66
+
67
+ # Skip if after until time
68
+ if query.until and msg["timestamp"] > datetime.fromisoformat(query.until):
69
+ continue
70
+
71
+ # Skip if content doesn't match search
72
+ if query.contains and query.contains not in msg["content"]:
73
+ continue
74
+
75
+ # Skip if role doesn't match
76
+ if query.roles and msg["role"] not in query.roles:
77
+ continue
78
+
79
+ # Convert cost info
80
+ cost_info = None
81
+ if msg["cost_info"]:
82
+ total = msg.get("cost", 0.0)
83
+ cost_info = TokenCost(token_usage=msg["cost_info"], total_cost=total)
84
+
85
+ # Create ChatMessage
86
+ chat_message = ChatMessage(
87
+ content=msg["content"],
88
+ role=msg["role"],
89
+ name=msg["name"],
90
+ model_name=msg["model"],
91
+ cost_info=cost_info,
92
+ response_time=msg["response_time"],
93
+ forwarded_from=msg["forwarded_from"] or [],
94
+ timestamp=msg["timestamp"],
95
+ provider_name=msg["provider_name"],
96
+ provider_response_id=msg["provider_response_id"],
97
+ messages=deserialize_messages(msg["messages"]),
98
+ finish_reason=msg["finish_reason"],
99
+ )
100
+ filtered.append(chat_message)
101
+
102
+ # Apply limit if specified
103
+ if query.limit and len(filtered) >= query.limit:
104
+ break
105
+
106
+ return filtered
107
+
108
+ async def log_message(
109
+ self,
110
+ *,
111
+ conversation_id: str,
112
+ message_id: str,
113
+ content: str,
114
+ role: str,
115
+ name: str | None = None,
116
+ cost_info: TokenCost | None = None,
117
+ model: str | None = None,
118
+ response_time: float | None = None,
119
+ forwarded_from: list[str] | None = None,
120
+ provider_name: str | None = None,
121
+ provider_response_id: str | None = None,
122
+ messages: str | None = None,
123
+ finish_reason: str | None = None,
124
+ ) -> None:
125
+ """Store message in memory."""
126
+ if next((i for i in self.messages if i["message_id"] == message_id), None):
127
+ msg = f"Duplicate message ID: {message_id}"
128
+ raise ValueError(msg)
129
+
130
+ self.messages.append({
131
+ "conversation_id": conversation_id,
132
+ "message_id": message_id,
133
+ "content": content,
134
+ "role": role,
135
+ "name": name,
136
+ "cost_info": cost_info.token_usage if cost_info else None,
137
+ "model": model,
138
+ "response_time": response_time,
139
+ "forwarded_from": forwarded_from,
140
+ "provider_name": provider_name,
141
+ "provider_response_id": provider_response_id,
142
+ "messages": messages,
143
+ "finish_reason": finish_reason,
144
+ "timestamp": get_now(),
145
+ })
146
+
147
+ async def log_conversation(
148
+ self,
149
+ *,
150
+ conversation_id: str,
151
+ node_name: str,
152
+ start_time: datetime | None = None,
153
+ ) -> None:
154
+ """Store conversation in memory."""
155
+ if next((i for i in self.conversations if i["id"] == conversation_id), None):
156
+ msg = f"Duplicate conversation ID: {conversation_id}"
157
+ raise ValueError(msg)
158
+ self.conversations.append({
159
+ "id": conversation_id,
160
+ "agent_name": node_name,
161
+ "title": None,
162
+ "start_time": start_time or get_now(),
163
+ })
164
+
165
+ async def update_conversation_title(
166
+ self,
167
+ conversation_id: str,
168
+ title: str,
169
+ ) -> None:
170
+ """Update the title of a conversation."""
171
+ for conv in self.conversations:
172
+ if conv["id"] == conversation_id:
173
+ conv["title"] = title
174
+ return
175
+
176
+ async def get_conversation_title(
177
+ self,
178
+ conversation_id: str,
179
+ ) -> str | None:
180
+ """Get the title of a conversation."""
181
+ for conv in self.conversations:
182
+ if conv["id"] == conversation_id:
183
+ return conv.get("title")
184
+ return None
185
+
186
+ async def log_command(
187
+ self,
188
+ *,
189
+ agent_name: str,
190
+ session_id: str,
191
+ command: str,
192
+ context_type: type | None = None,
193
+ metadata: dict[str, JsonValue] | None = None,
194
+ ) -> None:
195
+ """Store command in memory."""
196
+ self.commands.append({
197
+ "agent_name": agent_name,
198
+ "session_id": session_id,
199
+ "command": command,
200
+ "timestamp": get_now(),
201
+ "context_type": context_type.__name__ if context_type else None,
202
+ "metadata": metadata or {},
203
+ })
204
+
205
+ async def get_commands(
206
+ self,
207
+ agent_name: str,
208
+ session_id: str,
209
+ *,
210
+ limit: int | None = None,
211
+ current_session_only: bool = False,
212
+ ) -> list[str]:
213
+ """Get commands from memory."""
214
+ filtered = []
215
+ for cmd in reversed(self.commands): # newest first
216
+ if current_session_only and cmd["session_id"] != session_id:
217
+ continue
218
+ if not current_session_only and cmd["agent_name"] != agent_name:
219
+ continue
220
+ filtered.append(cmd["command"])
221
+ if limit and len(filtered) >= limit:
222
+ break
223
+ return filtered
224
+
225
+ async def get_conversations(
226
+ self,
227
+ filters: QueryFilters,
228
+ ) -> list[tuple[ConversationData, Sequence[ChatMessage[str]]]]:
229
+ """Get filtered conversations from memory."""
230
+ results: list[tuple[ConversationData, Sequence[ChatMessage[str]]]] = []
231
+
232
+ # First get matching conversations
233
+ convs = {}
234
+ for conv in self.conversations:
235
+ if filters.agent_name and conv["agent_name"] != filters.agent_name:
236
+ continue
237
+ if filters.since and conv["start_time"] < filters.since:
238
+ continue
239
+ convs[conv["id"]] = conv
240
+
241
+ # Then get messages for each conversation
242
+ for conv_id, conv in convs.items():
243
+ conv_messages: list[ChatMessage[str]] = []
244
+ for msg in self.messages:
245
+ if msg["conversation_id"] != conv_id:
246
+ continue
247
+ if filters.query and filters.query not in msg["content"]:
248
+ continue
249
+ if filters.model and msg["model"] != filters.model:
250
+ continue
251
+
252
+ cost_info = None
253
+ if msg["cost_info"]:
254
+ total = msg.get("cost", 0.0)
255
+ cost_info = TokenCost(token_usage=msg["cost_info"], total_cost=total)
256
+
257
+ chat_msg = ChatMessage[str](
258
+ content=msg["content"],
259
+ role=msg["role"],
260
+ name=msg["name"],
261
+ model_name=msg["model"],
262
+ cost_info=cost_info,
263
+ response_time=msg["response_time"],
264
+ forwarded_from=msg["forwarded_from"],
265
+ timestamp=msg["timestamp"],
266
+ )
267
+ conv_messages.append(chat_msg)
268
+
269
+ # Skip if no matching messages for content filter
270
+ if filters.query and not conv_messages:
271
+ continue
272
+
273
+ # Convert ChatMessages to MessageData format for ConversationData
274
+ message_data: list[MessageData] = [
275
+ cast(
276
+ "MessageData",
277
+ {
278
+ "role": msg.role,
279
+ "content": msg.content,
280
+ "timestamp": msg.timestamp.isoformat(),
281
+ "model": msg.model_name,
282
+ "name": msg.name,
283
+ "token_usage": msg.cost_info.token_usage if msg.cost_info else None,
284
+ "cost": msg.cost_info.total_cost if msg.cost_info else None,
285
+ "response_time": msg.response_time,
286
+ },
287
+ )
288
+ for msg in conv_messages
289
+ ]
290
+
291
+ # Create conversation data with proper MessageData
292
+ conv_data = ConversationData(
293
+ id=conv_id,
294
+ agent=conv["agent_name"],
295
+ title=conv.get("title"),
296
+ start_time=conv["start_time"].isoformat(),
297
+ messages=message_data, # Now using properly typed MessageData
298
+ token_usage=self._aggregate_token_usage(conv_messages),
299
+ )
300
+ results.append((conv_data, conv_messages))
301
+
302
+ if filters.limit and len(results) >= filters.limit:
303
+ break
304
+
305
+ return results
306
+
307
+ async def get_conversation_stats(
308
+ self,
309
+ filters: StatsFilters,
310
+ ) -> dict[str, dict[str, Any]]:
311
+ """Get statistics from memory."""
312
+ # Collect raw data
313
+ rows = []
314
+ for msg in self.messages:
315
+ if msg["timestamp"] <= filters.cutoff:
316
+ continue
317
+ if filters.agent_name and msg["name"] != filters.agent_name:
318
+ continue
319
+
320
+ cost_info = None
321
+ if msg["cost_info"]:
322
+ total = msg.get("cost", 0.0)
323
+ cost_info = TokenCost(token_usage=msg["cost_info"], total_cost=total)
324
+
325
+ rows.append((msg["model"], msg["name"], msg["timestamp"], cost_info))
326
+
327
+ # Use base class aggregation
328
+ return self.aggregate_stats(rows, filters.group_by)
329
+
330
+ @staticmethod
331
+ def _aggregate_token_usage(messages: Sequence[ChatMessage[Any]]) -> TokenUsage:
332
+ """Sum up tokens from a sequence of messages."""
333
+ total = prompt = completion = 0
334
+ for msg in messages:
335
+ if msg.cost_info:
336
+ total += msg.cost_info.token_usage.total_tokens
337
+ prompt += msg.cost_info.token_usage.input_tokens
338
+ completion += msg.cost_info.token_usage.output_tokens
339
+ return {"total": total, "prompt": prompt, "completion": completion}
340
+
341
+ async def reset(
342
+ self,
343
+ *,
344
+ agent_name: str | None = None,
345
+ hard: bool = False,
346
+ ) -> tuple[int, int]:
347
+ """Reset stored data."""
348
+ # Get counts first
349
+ conv_count, msg_count = await self.get_conversation_counts(agent_name=agent_name)
350
+
351
+ if hard:
352
+ if agent_name:
353
+ msg = "Hard reset cannot be used with agent_name"
354
+ raise ValueError(msg)
355
+ # Clear everything
356
+ self.cleanup()
357
+ return conv_count, msg_count
358
+
359
+ if agent_name:
360
+ # Filter out data for specific agent
361
+ self.conversations = [c for c in self.conversations if c["agent_name"] != agent_name]
362
+ self.messages = [
363
+ m
364
+ for m in self.messages
365
+ if m["conversation_id"]
366
+ not in {c["id"] for c in self.conversations if c["agent_name"] == agent_name}
367
+ ]
368
+ else:
369
+ # Clear all
370
+ self.messages.clear()
371
+ self.conversations.clear()
372
+ self.commands.clear()
373
+
374
+ return conv_count, msg_count
375
+
376
+ async def get_conversation_counts(
377
+ self,
378
+ *,
379
+ agent_name: str | None = None,
380
+ ) -> tuple[int, int]:
381
+ """Get conversation and message counts."""
382
+ if agent_name:
383
+ conv_count = sum(1 for c in self.conversations if c["agent_name"] == agent_name)
384
+ msg_count = sum(
385
+ 1
386
+ for m in self.messages
387
+ if any(
388
+ c["id"] == m["conversation_id"] and c["agent_name"] == agent_name
389
+ for c in self.conversations
390
+ )
391
+ )
392
+ else:
393
+ conv_count = len(self.conversations)
394
+ msg_count = len(self.messages)
395
+
396
+ return conv_count, msg_count
@@ -0,0 +1,108 @@
1
+ """Data classes for storing agent data."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from typing import TYPE_CHECKING, Literal, TypedDict
7
+
8
+
9
+ if TYPE_CHECKING:
10
+ from datetime import datetime
11
+
12
+
13
+ GroupBy = Literal["agent", "model", "hour", "day"]
14
+
15
+
16
+ class TokenUsage(TypedDict):
17
+ """Token usage statistics from model responses."""
18
+
19
+ total: int
20
+ """Total tokens used"""
21
+ prompt: int
22
+ """Tokens used in the prompt"""
23
+ completion: int
24
+ """Tokens used in the completion"""
25
+
26
+
27
+ class MessageData(TypedDict):
28
+ """Formatted message data."""
29
+
30
+ role: str
31
+ """Role of the message sender (user/assistant/system)"""
32
+
33
+ content: str
34
+ """Content of the message"""
35
+
36
+ timestamp: str
37
+ """When the message was sent (ISO format)"""
38
+
39
+ model: str | None
40
+ """Name of the model that generated this message"""
41
+
42
+ name: str | None
43
+ """Display name of the sender"""
44
+
45
+ token_usage: TokenUsage | None
46
+ """Token usage statistics if available"""
47
+
48
+ cost: float | None
49
+ """Cost of generating this message in USD"""
50
+
51
+ response_time: float | None
52
+ """Time taken to generate the response in seconds"""
53
+
54
+
55
+ class ConversationData(TypedDict):
56
+ """Formatted conversation data."""
57
+
58
+ id: str
59
+ """Unique identifier for the conversation"""
60
+
61
+ agent: str
62
+ """Name of the agent that handled this conversation"""
63
+
64
+ title: str | None
65
+ """AI-generated or user-provided conversation title"""
66
+
67
+ start_time: str
68
+ """When the conversation started (ISO format)"""
69
+
70
+ messages: list[MessageData]
71
+ """List of messages in this conversation"""
72
+
73
+ token_usage: TokenUsage | None
74
+ """Aggregated token usage for the entire conversation"""
75
+
76
+
77
+ @dataclass
78
+ class QueryFilters:
79
+ """Filters for conversation queries."""
80
+
81
+ agent_name: str | None = None
82
+ """Filter by specific agent name"""
83
+
84
+ since: datetime | None = None
85
+ """Only include conversations after this time"""
86
+
87
+ query: str | None = None
88
+ """Search term to filter message content"""
89
+
90
+ model: str | None = None
91
+ """Filter by model name"""
92
+
93
+ limit: int | None = None
94
+ """Maximum number of conversations to return"""
95
+
96
+
97
+ @dataclass
98
+ class StatsFilters:
99
+ """Filters for statistics queries."""
100
+
101
+ cutoff: datetime
102
+ """Only include data after this time"""
103
+
104
+ group_by: GroupBy
105
+ """How to group the statistics (agent/model/hour/day)"""
106
+
107
+ agent_name: str | None = None
108
+ """Filter statistics to specific agent"""
File without changes