devsper 2.1.6__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.
Files changed (375) hide show
  1. devsper/__init__.py +14 -0
  2. devsper/agents/a2a/__init__.py +27 -0
  3. devsper/agents/a2a/client.py +126 -0
  4. devsper/agents/a2a/discovery.py +24 -0
  5. devsper/agents/a2a/server.py +128 -0
  6. devsper/agents/a2a/tool_adapter.py +68 -0
  7. devsper/agents/a2a/types.py +49 -0
  8. devsper/agents/agent.py +602 -0
  9. devsper/agents/critic.py +80 -0
  10. devsper/agents/message_bus.py +124 -0
  11. devsper/agents/roles.py +181 -0
  12. devsper/agents/run_agent.py +78 -0
  13. devsper/analytics/__init__.py +5 -0
  14. devsper/analytics/tool_analytics.py +78 -0
  15. devsper/audit/__init__.py +5 -0
  16. devsper/audit/logger.py +214 -0
  17. devsper/bus/__init__.py +29 -0
  18. devsper/bus/backends/__init__.py +5 -0
  19. devsper/bus/backends/base.py +38 -0
  20. devsper/bus/backends/memory.py +55 -0
  21. devsper/bus/backends/redis.py +146 -0
  22. devsper/bus/message.py +56 -0
  23. devsper/bus/schema_version.py +3 -0
  24. devsper/bus/topics.py +19 -0
  25. devsper/cache/__init__.py +6 -0
  26. devsper/cache/embedding_index.py +98 -0
  27. devsper/cache/hashing.py +24 -0
  28. devsper/cache/store.py +153 -0
  29. devsper/cache/task_cache.py +191 -0
  30. devsper/cli/__init__.py +6 -0
  31. devsper/cli/commands/reg.py +733 -0
  32. devsper/cli/github_oauth.py +157 -0
  33. devsper/cli/init.py +637 -0
  34. devsper/cli/main.py +2956 -0
  35. devsper/cli/run_progress.py +103 -0
  36. devsper/cli/ui/__init__.py +65 -0
  37. devsper/cli/ui/components.py +94 -0
  38. devsper/cli/ui/errors.py +104 -0
  39. devsper/cli/ui/logging.py +120 -0
  40. devsper/cli/ui/onboarding.py +102 -0
  41. devsper/cli/ui/progress.py +43 -0
  42. devsper/cli/ui/run_view.py +308 -0
  43. devsper/cli/ui/theme.py +40 -0
  44. devsper/cluster/__init__.py +29 -0
  45. devsper/cluster/election.py +84 -0
  46. devsper/cluster/local.py +97 -0
  47. devsper/cluster/node_info.py +77 -0
  48. devsper/cluster/registry.py +71 -0
  49. devsper/cluster/router.py +117 -0
  50. devsper/cluster/state_backend.py +105 -0
  51. devsper/compliance/__init__.py +5 -0
  52. devsper/compliance/pii.py +147 -0
  53. devsper/config/__init__.py +52 -0
  54. devsper/config/config_loader.py +121 -0
  55. devsper/config/defaults.py +77 -0
  56. devsper/config/resolver.py +342 -0
  57. devsper/config/schema.py +237 -0
  58. devsper/credentials/__init__.py +19 -0
  59. devsper/credentials/cli.py +197 -0
  60. devsper/credentials/migration.py +124 -0
  61. devsper/credentials/store.py +142 -0
  62. devsper/dashboard/__init__.py +9 -0
  63. devsper/dashboard/dashboard.py +87 -0
  64. devsper/dev/__init__.py +25 -0
  65. devsper/dev/builder.py +195 -0
  66. devsper/dev/debugger.py +95 -0
  67. devsper/dev/repo_index.py +138 -0
  68. devsper/dev/sandbox.py +203 -0
  69. devsper/dev/scaffold.py +122 -0
  70. devsper/embeddings/__init__.py +5 -0
  71. devsper/embeddings/service.py +36 -0
  72. devsper/explainability/__init__.py +14 -0
  73. devsper/explainability/decision_tree.py +104 -0
  74. devsper/explainability/rationale.py +38 -0
  75. devsper/explainability/simulation.py +56 -0
  76. devsper/hitl/__init__.py +13 -0
  77. devsper/hitl/approval.py +160 -0
  78. devsper/hitl/escalation.py +95 -0
  79. devsper/intelligence/__init__.py +9 -0
  80. devsper/intelligence/adaptation.py +88 -0
  81. devsper/intelligence/analysis/__init__.py +19 -0
  82. devsper/intelligence/analysis/analyzer.py +71 -0
  83. devsper/intelligence/analysis/cost_estimator.py +66 -0
  84. devsper/intelligence/analysis/formatter.py +103 -0
  85. devsper/intelligence/analysis/run_report.py +402 -0
  86. devsper/intelligence/learning_engine.py +92 -0
  87. devsper/intelligence/strategies/__init__.py +23 -0
  88. devsper/intelligence/strategies/base.py +14 -0
  89. devsper/intelligence/strategies/code_analysis_strategy.py +33 -0
  90. devsper/intelligence/strategies/data_science_strategy.py +33 -0
  91. devsper/intelligence/strategies/document_pipeline_strategy.py +33 -0
  92. devsper/intelligence/strategies/experiment_strategy.py +33 -0
  93. devsper/intelligence/strategies/research_strategy.py +34 -0
  94. devsper/intelligence/strategy_selector.py +84 -0
  95. devsper/intelligence/synthesis.py +132 -0
  96. devsper/intelligence/task_optimizer.py +92 -0
  97. devsper/knowledge/__init__.py +5 -0
  98. devsper/knowledge/extractor.py +204 -0
  99. devsper/knowledge/knowledge_graph.py +184 -0
  100. devsper/knowledge/query.py +285 -0
  101. devsper/memory/__init__.py +35 -0
  102. devsper/memory/consolidation.py +138 -0
  103. devsper/memory/embeddings.py +60 -0
  104. devsper/memory/memory_index.py +97 -0
  105. devsper/memory/memory_router.py +62 -0
  106. devsper/memory/memory_store.py +221 -0
  107. devsper/memory/memory_types.py +54 -0
  108. devsper/memory/namespaces.py +45 -0
  109. devsper/memory/scoring.py +77 -0
  110. devsper/memory/summarizer.py +52 -0
  111. devsper/nodes/__init__.py +5 -0
  112. devsper/nodes/controller.py +449 -0
  113. devsper/nodes/rpc.py +127 -0
  114. devsper/nodes/single.py +161 -0
  115. devsper/nodes/worker.py +506 -0
  116. devsper/orchestration/__init__.py +19 -0
  117. devsper/orchestration/meta_planner.py +239 -0
  118. devsper/orchestration/priority_queue.py +61 -0
  119. devsper/plugins/__init__.py +19 -0
  120. devsper/plugins/marketplace/__init__.py +0 -0
  121. devsper/plugins/plugin_loader.py +70 -0
  122. devsper/plugins/plugin_registry.py +34 -0
  123. devsper/plugins/registry.py +83 -0
  124. devsper/protocols/__init__.py +6 -0
  125. devsper/providers/__init__.py +17 -0
  126. devsper/providers/anthropic.py +84 -0
  127. devsper/providers/base.py +75 -0
  128. devsper/providers/complexity_router.py +94 -0
  129. devsper/providers/gemini.py +36 -0
  130. devsper/providers/github.py +180 -0
  131. devsper/providers/model_router.py +40 -0
  132. devsper/providers/openai.py +105 -0
  133. devsper/providers/router/__init__.py +21 -0
  134. devsper/providers/router/backends/__init__.py +19 -0
  135. devsper/providers/router/backends/anthropic_backend.py +111 -0
  136. devsper/providers/router/backends/custom_backend.py +138 -0
  137. devsper/providers/router/backends/gemini_backend.py +89 -0
  138. devsper/providers/router/backends/github_backend.py +165 -0
  139. devsper/providers/router/backends/ollama_backend.py +104 -0
  140. devsper/providers/router/backends/openai_backend.py +142 -0
  141. devsper/providers/router/backends/vllm_backend.py +35 -0
  142. devsper/providers/router/base.py +60 -0
  143. devsper/providers/router/factory.py +92 -0
  144. devsper/providers/router/legacy.py +101 -0
  145. devsper/providers/router/router.py +135 -0
  146. devsper/reasoning/__init__.py +12 -0
  147. devsper/reasoning/graph.py +59 -0
  148. devsper/reasoning/nodes.py +20 -0
  149. devsper/reasoning/store.py +67 -0
  150. devsper/runtime/__init__.py +12 -0
  151. devsper/runtime/health.py +88 -0
  152. devsper/runtime/replay.py +53 -0
  153. devsper/runtime/replay_engine.py +142 -0
  154. devsper/runtime/run_history.py +204 -0
  155. devsper/runtime/telemetry.py +116 -0
  156. devsper/runtime/visualize.py +58 -0
  157. devsper/sandbox/__init__.py +13 -0
  158. devsper/sandbox/sandbox.py +161 -0
  159. devsper/swarm/checkpointer.py +65 -0
  160. devsper/swarm/executor.py +558 -0
  161. devsper/swarm/map_reduce.py +44 -0
  162. devsper/swarm/planner.py +197 -0
  163. devsper/swarm/prefetcher.py +91 -0
  164. devsper/swarm/scheduler.py +153 -0
  165. devsper/swarm/speculation.py +47 -0
  166. devsper/swarm/swarm.py +562 -0
  167. devsper/tools/__init__.py +33 -0
  168. devsper/tools/base.py +29 -0
  169. devsper/tools/code_intelligence/__init__.py +13 -0
  170. devsper/tools/code_intelligence/api_surface_extractor.py +73 -0
  171. devsper/tools/code_intelligence/architecture_analyzer.py +65 -0
  172. devsper/tools/code_intelligence/codebase_indexer.py +71 -0
  173. devsper/tools/code_intelligence/dependency_graph_builder.py +67 -0
  174. devsper/tools/code_intelligence/design_pattern_detector.py +62 -0
  175. devsper/tools/code_intelligence/large_function_detector.py +68 -0
  176. devsper/tools/code_intelligence/module_responsibility_mapper.py +56 -0
  177. devsper/tools/code_intelligence/parallel_codebase_analysis.py +44 -0
  178. devsper/tools/code_intelligence/refactor_candidate_detector.py +81 -0
  179. devsper/tools/code_intelligence/repository_semantic_index.py +61 -0
  180. devsper/tools/code_intelligence/test_coverage_estimator.py +62 -0
  181. devsper/tools/coding/__init__.py +12 -0
  182. devsper/tools/coding/analyze_code_complexity.py +48 -0
  183. devsper/tools/coding/dependency_analyzer.py +42 -0
  184. devsper/tools/coding/extract_functions.py +38 -0
  185. devsper/tools/coding/format_python.py +50 -0
  186. devsper/tools/coding/generate_docstrings.py +40 -0
  187. devsper/tools/coding/generate_unit_tests.py +42 -0
  188. devsper/tools/coding/lint_python.py +51 -0
  189. devsper/tools/coding/refactor_function.py +41 -0
  190. devsper/tools/coding/repo_structure_map.py +54 -0
  191. devsper/tools/coding/run_python.py +53 -0
  192. devsper/tools/data/__init__.py +12 -0
  193. devsper/tools/data/column_type_detection.py +64 -0
  194. devsper/tools/data/csv_summary.py +52 -0
  195. devsper/tools/data/dataframe_filter.py +51 -0
  196. devsper/tools/data/dataframe_groupby.py +47 -0
  197. devsper/tools/data/dataframe_stats.py +38 -0
  198. devsper/tools/data/dataset_sampling.py +55 -0
  199. devsper/tools/data/dataset_schema.py +45 -0
  200. devsper/tools/data/json_pretty_print.py +37 -0
  201. devsper/tools/data/json_query.py +46 -0
  202. devsper/tools/data/missing_value_report.py +47 -0
  203. devsper/tools/data_science/__init__.py +13 -0
  204. devsper/tools/data_science/correlation_heatmap.py +72 -0
  205. devsper/tools/data_science/dataset_bias_detector.py +49 -0
  206. devsper/tools/data_science/dataset_distribution_report.py +64 -0
  207. devsper/tools/data_science/dataset_drift_detector.py +64 -0
  208. devsper/tools/data_science/dataset_outlier_detector.py +65 -0
  209. devsper/tools/data_science/dataset_profile.py +76 -0
  210. devsper/tools/data_science/distributed_dataset_processor.py +54 -0
  211. devsper/tools/data_science/feature_engineering_suggestions.py +69 -0
  212. devsper/tools/data_science/feature_importance_estimator.py +82 -0
  213. devsper/tools/data_science/model_input_validator.py +59 -0
  214. devsper/tools/data_science/time_series_analyzer.py +57 -0
  215. devsper/tools/documents/__init__.py +11 -0
  216. devsper/tools/documents/_docproc.py +56 -0
  217. devsper/tools/documents/document_to_markdown.py +29 -0
  218. devsper/tools/documents/extract_document_images.py +39 -0
  219. devsper/tools/documents/extract_document_text.py +29 -0
  220. devsper/tools/documents/extract_equations.py +36 -0
  221. devsper/tools/documents/extract_tables.py +47 -0
  222. devsper/tools/documents/summarize_document.py +42 -0
  223. devsper/tools/documents/write_latex_document.py +133 -0
  224. devsper/tools/documents/write_markdown_document.py +89 -0
  225. devsper/tools/documents/write_word_document.py +149 -0
  226. devsper/tools/experiments/__init__.py +13 -0
  227. devsper/tools/experiments/bootstrap_estimator.py +54 -0
  228. devsper/tools/experiments/experiment_report_generator.py +50 -0
  229. devsper/tools/experiments/experiment_tracker.py +36 -0
  230. devsper/tools/experiments/grid_search_runner.py +50 -0
  231. devsper/tools/experiments/model_benchmark_runner.py +45 -0
  232. devsper/tools/experiments/monte_carlo_experiment.py +38 -0
  233. devsper/tools/experiments/parameter_sweep_runner.py +51 -0
  234. devsper/tools/experiments/result_comparator.py +58 -0
  235. devsper/tools/experiments/simulation_runner.py +43 -0
  236. devsper/tools/experiments/statistical_significance_test.py +56 -0
  237. devsper/tools/experiments/swarm_map_reduce.py +42 -0
  238. devsper/tools/filesystem/__init__.py +12 -0
  239. devsper/tools/filesystem/append_file.py +42 -0
  240. devsper/tools/filesystem/file_hash.py +40 -0
  241. devsper/tools/filesystem/file_line_count.py +36 -0
  242. devsper/tools/filesystem/file_metadata.py +38 -0
  243. devsper/tools/filesystem/file_preview.py +55 -0
  244. devsper/tools/filesystem/find_large_files.py +50 -0
  245. devsper/tools/filesystem/list_directory.py +39 -0
  246. devsper/tools/filesystem/read_file.py +35 -0
  247. devsper/tools/filesystem/search_files.py +60 -0
  248. devsper/tools/filesystem/write_file.py +41 -0
  249. devsper/tools/flagship/__init__.py +15 -0
  250. devsper/tools/flagship/distributed_document_analysis.py +77 -0
  251. devsper/tools/flagship/docproc_corpus_pipeline.py +91 -0
  252. devsper/tools/flagship/repository_semantic_map.py +99 -0
  253. devsper/tools/flagship/research_graph_builder.py +111 -0
  254. devsper/tools/flagship/swarm_experiment_runner.py +86 -0
  255. devsper/tools/knowledge/__init__.py +10 -0
  256. devsper/tools/knowledge/citation_graph_builder.py +69 -0
  257. devsper/tools/knowledge/concept_frequency_analyzer.py +74 -0
  258. devsper/tools/knowledge/corpus_builder.py +66 -0
  259. devsper/tools/knowledge/cross_document_entity_linker.py +71 -0
  260. devsper/tools/knowledge/document_corpus_summary.py +68 -0
  261. devsper/tools/knowledge/document_topic_extractor.py +58 -0
  262. devsper/tools/knowledge/knowledge_graph_extractor.py +58 -0
  263. devsper/tools/knowledge/timeline_extractor.py +59 -0
  264. devsper/tools/math/__init__.py +12 -0
  265. devsper/tools/math/calculate_expression.py +52 -0
  266. devsper/tools/math/correlation.py +44 -0
  267. devsper/tools/math/distribution_summary.py +39 -0
  268. devsper/tools/math/histogram.py +53 -0
  269. devsper/tools/math/linear_regression.py +47 -0
  270. devsper/tools/math/matrix_multiply.py +38 -0
  271. devsper/tools/math/mean_std.py +35 -0
  272. devsper/tools/math/monte_carlo_simulation.py +43 -0
  273. devsper/tools/math/polynomial_fit.py +40 -0
  274. devsper/tools/math/random_sample.py +36 -0
  275. devsper/tools/mcp/__init__.py +23 -0
  276. devsper/tools/mcp/adapter.py +53 -0
  277. devsper/tools/mcp/client.py +235 -0
  278. devsper/tools/mcp/discovery.py +53 -0
  279. devsper/tools/memory/__init__.py +16 -0
  280. devsper/tools/memory/delete_memory.py +25 -0
  281. devsper/tools/memory/list_memory.py +34 -0
  282. devsper/tools/memory/search_memory.py +36 -0
  283. devsper/tools/memory/store_memory.py +47 -0
  284. devsper/tools/memory/summarize_memory.py +41 -0
  285. devsper/tools/memory/tag_memory.py +47 -0
  286. devsper/tools/pipelines.py +92 -0
  287. devsper/tools/registry.py +39 -0
  288. devsper/tools/research/__init__.py +12 -0
  289. devsper/tools/research/arxiv_download.py +55 -0
  290. devsper/tools/research/arxiv_search.py +58 -0
  291. devsper/tools/research/citation_extractor.py +35 -0
  292. devsper/tools/research/duckduckgo_search.py +42 -0
  293. devsper/tools/research/paper_metadata_extractor.py +45 -0
  294. devsper/tools/research/paper_summarizer.py +41 -0
  295. devsper/tools/research/research_question_generator.py +39 -0
  296. devsper/tools/research/topic_cluster.py +46 -0
  297. devsper/tools/research/web_search.py +47 -0
  298. devsper/tools/research/wikipedia_lookup.py +50 -0
  299. devsper/tools/research_advanced/__init__.py +14 -0
  300. devsper/tools/research_advanced/citation_context_extractor.py +60 -0
  301. devsper/tools/research_advanced/literature_review_generator.py +79 -0
  302. devsper/tools/research_advanced/methodology_extractor.py +58 -0
  303. devsper/tools/research_advanced/paper_contribution_extractor.py +50 -0
  304. devsper/tools/research_advanced/paper_dataset_identifier.py +49 -0
  305. devsper/tools/research_advanced/paper_method_comparator.py +62 -0
  306. devsper/tools/research_advanced/paper_similarity_search.py +69 -0
  307. devsper/tools/research_advanced/paper_trend_analyzer.py +69 -0
  308. devsper/tools/research_advanced/parallel_document_analyzer.py +56 -0
  309. devsper/tools/research_advanced/research_gap_finder.py +71 -0
  310. devsper/tools/research_advanced/research_topic_mapper.py +69 -0
  311. devsper/tools/research_advanced/swarm_literature_review.py +58 -0
  312. devsper/tools/scoring/__init__.py +52 -0
  313. devsper/tools/scoring/report.py +44 -0
  314. devsper/tools/scoring/scorer.py +39 -0
  315. devsper/tools/scoring/selector.py +61 -0
  316. devsper/tools/scoring/store.py +267 -0
  317. devsper/tools/selector.py +130 -0
  318. devsper/tools/system/__init__.py +12 -0
  319. devsper/tools/system/cpu_usage.py +22 -0
  320. devsper/tools/system/disk_usage.py +35 -0
  321. devsper/tools/system/environment_variables.py +29 -0
  322. devsper/tools/system/memory_usage.py +23 -0
  323. devsper/tools/system/pip_install.py +44 -0
  324. devsper/tools/system/pip_search.py +29 -0
  325. devsper/tools/system/process_list.py +34 -0
  326. devsper/tools/system/python_package_list.py +40 -0
  327. devsper/tools/system/run_shell_command.py +51 -0
  328. devsper/tools/system/system_info.py +26 -0
  329. devsper/tools/tool_runner.py +122 -0
  330. devsper/tui/__init__.py +5 -0
  331. devsper/tui/activity_feed_view.py +73 -0
  332. devsper/tui/adaptive_tasks_view.py +75 -0
  333. devsper/tui/agent_role_view.py +35 -0
  334. devsper/tui/app.py +395 -0
  335. devsper/tui/dashboard_screen.py +290 -0
  336. devsper/tui/dev_view.py +99 -0
  337. devsper/tui/inject_screen.py +73 -0
  338. devsper/tui/knowledge_graph_view.py +46 -0
  339. devsper/tui/layout.py +43 -0
  340. devsper/tui/logs_view.py +83 -0
  341. devsper/tui/memory_view.py +58 -0
  342. devsper/tui/performance_view.py +33 -0
  343. devsper/tui/reasoning_graph_view.py +39 -0
  344. devsper/tui/results_view.py +139 -0
  345. devsper/tui/swarm_view.py +37 -0
  346. devsper/tui/task_detail_screen.py +55 -0
  347. devsper/tui/task_view.py +103 -0
  348. devsper/types/event.py +97 -0
  349. devsper/types/exceptions.py +21 -0
  350. devsper/types/swarm.py +41 -0
  351. devsper/types/task.py +80 -0
  352. devsper/upgrade/__init__.py +21 -0
  353. devsper/upgrade/changelog.py +124 -0
  354. devsper/upgrade/cli.py +145 -0
  355. devsper/upgrade/installer.py +103 -0
  356. devsper/upgrade/notifier.py +52 -0
  357. devsper/upgrade/version_check.py +121 -0
  358. devsper/utils/event_logger.py +88 -0
  359. devsper/utils/http.py +43 -0
  360. devsper/utils/models.py +54 -0
  361. devsper/visualization/__init__.py +5 -0
  362. devsper/visualization/dag_export.py +67 -0
  363. devsper/workflow/__init__.py +18 -0
  364. devsper/workflow/conditions.py +157 -0
  365. devsper/workflow/context.py +108 -0
  366. devsper/workflow/loader.py +156 -0
  367. devsper/workflow/resolver.py +109 -0
  368. devsper/workflow/runner.py +562 -0
  369. devsper/workflow/schema.py +63 -0
  370. devsper/workflow/validator.py +128 -0
  371. devsper-2.1.6.dist-info/METADATA +346 -0
  372. devsper-2.1.6.dist-info/RECORD +375 -0
  373. devsper-2.1.6.dist-info/WHEEL +4 -0
  374. devsper-2.1.6.dist-info/entry_points.txt +3 -0
  375. devsper-2.1.6.dist-info/licenses/LICENSE +639 -0
devsper/swarm/swarm.py ADDED
@@ -0,0 +1,562 @@
1
+ """
2
+ Swarm: entrypoint for users. Orchestrates planner → scheduler → executor → results.
3
+
4
+ User code:
5
+ swarm = Swarm(worker_count=4)
6
+ result = swarm.run("Analyze diffusion model research")
7
+ # Or with config file:
8
+ swarm = Swarm(config="devsper.toml")
9
+ result = swarm.run("analyze diffusion models")
10
+ """
11
+
12
+ import asyncio
13
+ import json
14
+ import os
15
+ import threading
16
+ from pathlib import Path
17
+ from datetime import datetime, timezone
18
+
19
+ from devsper.types.task import Task
20
+ from devsper.types.event import Event, events
21
+ from devsper.utils.event_logger import EventLog
22
+ from devsper.utils.models import resolve_model
23
+
24
+ from devsper.swarm.planner import Planner
25
+ from devsper.swarm.scheduler import Scheduler
26
+ from devsper.swarm.executor import Executor
27
+ from devsper.agents.agent import Agent
28
+
29
+
30
+ def _fake_config():
31
+ """Minimal config for single-node when no config file loaded."""
32
+ class N:
33
+ mode = "single"
34
+ class C:
35
+ events_dir = ".devsper/events"
36
+ nodes = N()
37
+ return C()
38
+
39
+
40
+ def _persist_dag(scheduler: Scheduler, event_log: EventLog) -> None:
41
+ """Write task DAG to events dir as {run_id}_dag.json for graph export."""
42
+ run_id = getattr(event_log, "run_id", None)
43
+ if not run_id:
44
+ return
45
+ log_path = getattr(event_log, "log_path", None)
46
+ if not log_path:
47
+ return
48
+ events_dir = os.path.dirname(log_path)
49
+ nodes = [
50
+ {"id": t.id, "description": (t.description or "")[:200]}
51
+ for t in scheduler._tasks.values()
52
+ ]
53
+ edges = list(scheduler._graph.edges())
54
+ path = os.path.join(events_dir, f"{run_id}_dag.json")
55
+ with open(path, "w", encoding="utf-8") as f:
56
+ json.dump({"nodes": nodes, "edges": edges}, f, indent=0)
57
+
58
+
59
+ class Swarm:
60
+ """Orchestrates planner, scheduler, executor, and agent. Single entrypoint for running a task."""
61
+
62
+ def __init__(
63
+ self,
64
+ worker_count: int | None = None,
65
+ worker_model: str | None = None,
66
+ planner_model: str | None = None,
67
+ event_log: EventLog | None = None,
68
+ adaptive: bool | None = None,
69
+ memory_router=None,
70
+ store_swarm_memory: bool = True,
71
+ use_tools: bool | None = None,
72
+ config: str | Path | object | None = None,
73
+ ) -> None:
74
+ # Load from config file or config object if provided
75
+ cfg = None
76
+ if config is not None:
77
+ if isinstance(config, (str, Path)):
78
+ from devsper.config import get_config
79
+
80
+ cfg = get_config(config_path=str(config))
81
+ else:
82
+ cfg = config
83
+ if cfg is not None:
84
+ self.worker_count = (
85
+ worker_count
86
+ if worker_count is not None
87
+ else getattr(cfg.swarm, "workers", 4)
88
+ )
89
+ worker_raw = worker_model if worker_model is not None else cfg.models.worker
90
+ planner_raw = (
91
+ planner_model if planner_model is not None else cfg.models.planner
92
+ )
93
+ self.worker_model = resolve_model(worker_raw, "analysis")
94
+ self.planner_model = resolve_model(planner_raw, "planning")
95
+ self.adaptive = (
96
+ adaptive
97
+ if adaptive is not None
98
+ else getattr(cfg.swarm, "adaptive_planning", False)
99
+ or getattr(cfg.swarm, "adaptive_execution", False)
100
+ )
101
+ self.use_tools = use_tools if use_tools is not None else True
102
+ self.speculative_execution = getattr(
103
+ cfg.swarm, "speculative_execution", False
104
+ )
105
+ self.cache_enabled = getattr(cfg.swarm, "cache_enabled", False)
106
+ self.parallel_tools = getattr(cfg.swarm, "parallel_tools", True)
107
+ self.message_bus_enabled = getattr(cfg.swarm, "message_bus_enabled", True)
108
+ self.prefetch_enabled = getattr(cfg.swarm, "prefetch_enabled", True)
109
+ self._config = cfg
110
+ # v1.10.5: register MCP server tools from config
111
+ mcp_servers = getattr(getattr(cfg, "mcp", None), "servers", None) or []
112
+ for server_config in mcp_servers:
113
+ try:
114
+ from devsper.tools.mcp import register_mcp_server
115
+ register_mcp_server(server_config)
116
+ except Exception:
117
+ pass # don't fail Swarm init if MCP server unreachable
118
+ # v1.10.5: register A2A agent tools from config (auto_discover)
119
+ a2a_agents = getattr(getattr(cfg, "a2a", None), "agents", None) or []
120
+ for agent_config in a2a_agents:
121
+ if not getattr(agent_config, "auto_discover", True):
122
+ continue
123
+ try:
124
+ from devsper.agents.a2a.discovery import register_a2a_agent
125
+ register_a2a_agent(agent_config)
126
+ except Exception:
127
+ pass
128
+ else:
129
+ self.worker_count = worker_count if worker_count is not None else 4
130
+ worker_raw = worker_model if worker_model is not None else "mock"
131
+ planner_raw = planner_model if planner_model is not None else "mock"
132
+ self.worker_model = resolve_model(worker_raw, "analysis")
133
+ self.planner_model = resolve_model(planner_raw, "planning")
134
+ self.adaptive = adaptive if adaptive is not None else False
135
+ self.use_tools = use_tools if use_tools is not None else False
136
+ self.speculative_execution = False
137
+ self.cache_enabled = False
138
+ self.parallel_tools = True
139
+ self.message_bus_enabled = True
140
+ self.prefetch_enabled = True
141
+ self._config = None
142
+ self.event_log = event_log or EventLog()
143
+ self.memory_router = memory_router
144
+ self.store_swarm_memory = store_swarm_memory
145
+ self._last_scheduler: Scheduler | None = None
146
+ self._last_reasoning_store = None
147
+ self._pause_event = threading.Event()
148
+ self._pause_event.set()
149
+
150
+ def pause(self) -> None:
151
+ """Pause the executor: currently-running tasks finish, no new tasks start."""
152
+ self._pause_event.clear()
153
+
154
+ def resume(self) -> None:
155
+ """Resume the executor so new tasks can be picked."""
156
+ self._pause_event.set()
157
+
158
+ def run(self, user_task: str, hitl_resolver: object = None) -> dict[str, str]:
159
+ """
160
+ Create root task → plan subtasks → add to scheduler → run executor → return task_id → result.
161
+ hitl_resolver: optional (approval, policy) -> bool for in-process approval prompts.
162
+ """
163
+ self._emit(events.SWARM_STARTED, {"user_task": user_task[:200]})
164
+
165
+ root = Task(id="root", description=user_task, dependencies=[])
166
+ from devsper.intelligence.strategy_selector import StrategySelector
167
+ from devsper.intelligence.strategies import get_strategy_for
168
+
169
+ knowledge_graph = None
170
+ if self._config is not None:
171
+ kg_cfg = getattr(self._config, "knowledge", None)
172
+ if kg_cfg and (getattr(kg_cfg, "guide_planning", False) or getattr(kg_cfg, "auto_extract", False)):
173
+ from devsper.knowledge.knowledge_graph import KnowledgeGraph
174
+ from devsper.memory.memory_store import get_default_store
175
+ knowledge_graph = KnowledgeGraph(store=get_default_store())
176
+ knowledge_graph.load()
177
+ knowledge_graph.build_from_memory(merge=True)
178
+ selector = StrategySelector()
179
+ selected = selector.select(root)
180
+ strategy_instance = get_strategy_for(selected)
181
+ prompt_suffix = selector.suggest_planner_prompt_suffix(selected)
182
+ guide_planning = False
183
+ min_confidence = 0.30
184
+ if self._config is not None and getattr(self._config, "knowledge", None):
185
+ guide_planning = getattr(self._config.knowledge, "guide_planning", False)
186
+ min_confidence = getattr(self._config.knowledge, "min_confidence", 0.30)
187
+ planner = Planner(
188
+ model_name=self.planner_model,
189
+ event_log=self.event_log,
190
+ strategy=strategy_instance,
191
+ prompt_suffix=prompt_suffix,
192
+ knowledge_graph=knowledge_graph,
193
+ guide_planning=guide_planning,
194
+ min_confidence=min_confidence,
195
+ )
196
+ subtasks = planner.plan(root)
197
+
198
+ scheduler = Scheduler()
199
+ scheduler.add_tasks(subtasks)
200
+ scheduler.run_id = getattr(self.event_log, "run_id", "") or ""
201
+ _persist_dag(scheduler, self.event_log)
202
+
203
+ from devsper.reasoning.store import ReasoningStore
204
+ from devsper.agents.message_bus import SwarmMessageBus
205
+
206
+ message_bus = None
207
+ if getattr(self, "message_bus_enabled", True):
208
+ message_bus = SwarmMessageBus(event_log=self.event_log)
209
+
210
+ # Build HITL once for both single-node and executor paths
211
+ hitl_enabled = False
212
+ hitl_escalation_checker = None
213
+ hitl_approval_store = None
214
+ hitl_notifier = None
215
+ if self._config is not None:
216
+ hitl_cfg = getattr(self._config, "hitl", None)
217
+ if hitl_cfg and getattr(hitl_cfg, "enabled", False):
218
+ from devsper.hitl.escalation import EscalationChecker, EscalationPolicy, EscalationTrigger
219
+ from devsper.hitl.approval import ApprovalStore, ApprovalNotifier
220
+ policies: list[EscalationPolicy] = []
221
+ for p in getattr(hitl_cfg, "policies", []) or []:
222
+ triggers = [
223
+ EscalationTrigger(type=getattr(t, "type", "confidence_below"), threshold=getattr(t, "threshold", 0.5))
224
+ for t in getattr(p, "triggers", []) or []
225
+ ]
226
+ policies.append(
227
+ EscalationPolicy(
228
+ triggers=triggers,
229
+ approvers=getattr(p, "approvers", []) or [],
230
+ timeout_seconds=getattr(p, "timeout_seconds", 3600),
231
+ on_timeout=getattr(p, "on_timeout", "auto_approve"),
232
+ )
233
+ )
234
+ if policies:
235
+ hitl_enabled = True
236
+ hitl_escalation_checker = EscalationChecker(policies)
237
+ hitl_approval_store = ApprovalStore(getattr(self._config, "data_dir", ".devsper"))
238
+ hitl_notifier = ApprovalNotifier()
239
+
240
+ nodes_mode = "distributed" # no config -> use executor path (v1.9 behavior)
241
+ if self._config is not None:
242
+ nodes_cfg = getattr(self._config, "nodes", None)
243
+ nodes_mode = getattr(nodes_cfg, "mode", "single") if nodes_cfg else "single"
244
+ if nodes_mode == "single" and self._config is not None:
245
+ def _agent_factory(cfg):
246
+ rs = ReasoningStore()
247
+ mb = SwarmMessageBus(event_log=self.event_log) if getattr(self, "message_bus_enabled", True) else None
248
+ return Agent(
249
+ model_name=self.worker_model,
250
+ event_log=self.event_log,
251
+ memory_router=self.memory_router,
252
+ store_result_to_memory=False,
253
+ use_tools=self.use_tools,
254
+ reasoning_store=rs,
255
+ user_task=user_task,
256
+ parallel_tools=getattr(self, "parallel_tools", True),
257
+ message_bus=mb,
258
+ )
259
+ from devsper.nodes.single import create_single_node
260
+ single_node = create_single_node(
261
+ config=self._config or _fake_config(),
262
+ scheduler=scheduler,
263
+ event_log=self.event_log,
264
+ memory_router=self.memory_router,
265
+ agent_factory=_agent_factory,
266
+ user_task=user_task,
267
+ message_bus=message_bus,
268
+ hitl_enabled=hitl_enabled,
269
+ hitl_escalation_checker=hitl_escalation_checker,
270
+ hitl_approval_store=hitl_approval_store,
271
+ hitl_notifier=hitl_notifier,
272
+ hitl_resolver=hitl_resolver,
273
+ )
274
+ async def _run_single():
275
+ await single_node.start()
276
+ return await single_node.run_until_finished()
277
+ results = asyncio.run(_run_single())
278
+ self._last_scheduler = scheduler
279
+ self._last_reasoning_store = None
280
+ if self.store_swarm_memory and self.memory_router and results:
281
+ self._store_swarm_memory(user_task, scheduler)
282
+ self._emit(events.SWARM_FINISHED, {"task_count": len(results)})
283
+ try:
284
+ from devsper.intelligence.analysis.run_report import build_report_from_events
285
+ from devsper.runtime.run_history import RunHistory
286
+ log_path = getattr(self.event_log, "log_path", None)
287
+ if log_path:
288
+ events_dir = os.path.dirname(log_path)
289
+ run_id = getattr(self.event_log, "run_id", None)
290
+ if run_id:
291
+ report = build_report_from_events(run_id, events_dir)
292
+ RunHistory().record_run(report)
293
+ if self._config and getattr(getattr(self._config, "knowledge", None), "auto_extract", False):
294
+ from devsper.knowledge.knowledge_graph import KnowledgeGraph
295
+ from devsper.knowledge.extractor import KnowledgeExtractor
296
+ from devsper.memory.memory_store import get_default_store
297
+ kg = KnowledgeGraph(store=get_default_store())
298
+ kg.load()
299
+ kg.build_from_memory(merge=True)
300
+ completed_tasks = self.last_completed_tasks
301
+ min_conf = getattr(self._config.knowledge, "min_confidence", 0.60)
302
+ extractor = KnowledgeExtractor(min_confidence=min_conf)
303
+ try:
304
+ asyncio.get_event_loop().run_until_complete(
305
+ extractor.extract_from_run(
306
+ run_id, completed_tasks, kg, event_log=self.event_log
307
+ )
308
+ )
309
+ except Exception:
310
+ loop = asyncio.new_event_loop()
311
+ loop.run_until_complete(
312
+ extractor.extract_from_run(
313
+ run_id, completed_tasks, kg, event_log=self.event_log
314
+ )
315
+ )
316
+ except Exception:
317
+ pass
318
+ return results
319
+
320
+ reasoning_store = ReasoningStore()
321
+ agent = Agent(
322
+ model_name=self.worker_model,
323
+ event_log=self.event_log,
324
+ memory_router=self.memory_router,
325
+ store_result_to_memory=False,
326
+ use_tools=self.use_tools,
327
+ reasoning_store=reasoning_store,
328
+ user_task=user_task,
329
+ parallel_tools=getattr(self, "parallel_tools", True),
330
+ message_bus=message_bus,
331
+ )
332
+ audit_logger = None
333
+ if self._config and getattr(getattr(self._config, "compliance", None), "audit_logging", False):
334
+ run_id = getattr(self.event_log, "run_id", "") or ""
335
+ if run_id:
336
+ from devsper.audit.logger import AuditLogger
337
+ audit_logger = AuditLogger(
338
+ getattr(self._config, "data_dir", ".devsper"),
339
+ run_id=run_id,
340
+ )
341
+ agent.audit_logger = audit_logger
342
+ agent.audit_run_id = run_id
343
+ task_cache = None
344
+ semantic_cache = None
345
+ if getattr(self, "cache_enabled", False):
346
+ from devsper.cache import TaskCache
347
+
348
+ task_cache = TaskCache()
349
+ cfg = getattr(self, "_config", None)
350
+ if cfg and getattr(getattr(cfg, "cache", None), "semantic", False):
351
+ from devsper.cache.task_cache import SemanticTaskCache
352
+
353
+ cache_cfg = cfg.cache
354
+ semantic_cache = SemanticTaskCache(
355
+ similarity_threshold=getattr(cache_cfg, "similarity_threshold", 0.92),
356
+ max_age_hours=getattr(cache_cfg, "max_age_hours", 168.0),
357
+ )
358
+ complexity_router = None
359
+ models_config = None
360
+ if self._config is not None:
361
+ from devsper.providers.complexity_router import TaskComplexityRouter
362
+
363
+ complexity_router = TaskComplexityRouter()
364
+ models_config = self._config.models
365
+
366
+ critic_agent = None
367
+ critic_enabled = False
368
+ critic_roles: list[str] = []
369
+ fast_model = self.worker_model
370
+ if self._config is not None:
371
+ critic_enabled = getattr(self._config.swarm, "critic_enabled", False)
372
+ critic_roles = list(
373
+ getattr(self._config.swarm, "critic_roles", [])
374
+ or ["research", "analysis", "code"]
375
+ )
376
+ fast_model = getattr(self._config.models, "fast", None) or self.worker_model
377
+ if critic_enabled:
378
+ from devsper.agents.critic import CriticAgent
379
+ critic_agent = CriticAgent(event_log=self.event_log)
380
+
381
+ prefetcher = None
382
+ if getattr(self, "speculative_execution", False) and getattr(
383
+ self, "prefetch_enabled", True
384
+ ):
385
+ from devsper.swarm.prefetcher import TaskPrefetcher
386
+ from devsper.tools.selector import get_tools_for_task
387
+ try:
388
+ from devsper.tools.scoring import get_default_score_store
389
+ score_store = get_default_score_store()
390
+ except Exception:
391
+ score_store = None
392
+ prefetch_max_age = 30.0
393
+ if self._config is not None:
394
+ prefetch_max_age = getattr(
395
+ self._config.swarm, "prefetch_max_age_seconds", 30.0
396
+ )
397
+ prefetcher = TaskPrefetcher(
398
+ memory_router=self.memory_router,
399
+ tool_selector=lambda desc, role=None, score_store=None: get_tools_for_task(
400
+ desc or "", role=role, score_store=score_store
401
+ ),
402
+ score_store=score_store,
403
+ max_age_seconds=prefetch_max_age,
404
+ )
405
+
406
+ bus = None
407
+ checkpointer = None
408
+ if self._config is not None:
409
+ try:
410
+ from devsper.bus import get_bus
411
+ bus = get_bus(self._config)
412
+ except Exception:
413
+ pass
414
+ if getattr(getattr(self._config, "swarm", None), "checkpoint_enabled", True):
415
+ from devsper.swarm.checkpointer import SchedulerCheckpointer
416
+ checkpointer = SchedulerCheckpointer(
417
+ events_dir=getattr(self._config, "events_dir", ".devsper/events"),
418
+ interval_tasks=getattr(
419
+ getattr(self._config, "swarm", None), "checkpoint_interval", 10
420
+ ),
421
+ )
422
+
423
+ from devsper.config import get_config
424
+ sandbox_config = getattr(get_config(), "sandbox", None)
425
+ executor = Executor(
426
+ scheduler=scheduler,
427
+ agent=agent,
428
+ worker_count=self.worker_count,
429
+ event_log=self.event_log,
430
+ planner=planner if self.adaptive else None,
431
+ adaptive=self.adaptive,
432
+ speculative_execution=getattr(self, "speculative_execution", False),
433
+ task_cache=task_cache,
434
+ pause_event=self._pause_event,
435
+ semantic_cache=semantic_cache,
436
+ complexity_router=complexity_router,
437
+ models_config=models_config,
438
+ streaming_dag=True,
439
+ critic_agent=critic_agent,
440
+ critic_enabled=critic_enabled,
441
+ critic_roles=critic_roles,
442
+ fast_model=fast_model,
443
+ prefetcher=prefetcher,
444
+ bus=bus,
445
+ checkpointer=checkpointer,
446
+ sandbox_config=sandbox_config,
447
+ audit_logger=audit_logger,
448
+ hitl_enabled=hitl_enabled,
449
+ hitl_escalation_checker=hitl_escalation_checker,
450
+ hitl_approval_store=hitl_approval_store,
451
+ hitl_notifier=hitl_notifier,
452
+ hitl_resolver=hitl_resolver,
453
+ )
454
+ executor.run_sync()
455
+
456
+ self._last_scheduler = scheduler
457
+ self._last_reasoning_store = reasoning_store
458
+ results = scheduler.get_results()
459
+ if self.store_swarm_memory and self.memory_router and results:
460
+ self._store_swarm_memory(user_task, scheduler)
461
+ self._emit(events.SWARM_FINISHED, {"task_count": len(results)})
462
+ try:
463
+ from devsper.intelligence.analysis.run_report import build_report_from_events
464
+ from devsper.runtime.run_history import RunHistory
465
+ log_path = getattr(self.event_log, "log_path", None)
466
+ if log_path:
467
+ events_dir = os.path.dirname(log_path)
468
+ run_id = getattr(self.event_log, "run_id", None)
469
+ if run_id:
470
+ report = build_report_from_events(run_id, events_dir)
471
+ RunHistory().record_run(report)
472
+ if self._config and getattr(getattr(self._config, "knowledge", None), "auto_extract", False):
473
+ from devsper.knowledge.knowledge_graph import KnowledgeGraph
474
+ from devsper.knowledge.extractor import KnowledgeExtractor
475
+ from devsper.memory.memory_store import get_default_store
476
+ kg = KnowledgeGraph(store=get_default_store())
477
+ kg.load()
478
+ kg.build_from_memory(merge=True)
479
+ completed_tasks = self.last_completed_tasks
480
+ min_conf = getattr(self._config.knowledge, "min_confidence", 0.60)
481
+ extractor = KnowledgeExtractor(min_confidence=min_conf)
482
+ try:
483
+ asyncio.get_event_loop().run_until_complete(
484
+ extractor.extract_from_run(
485
+ run_id, completed_tasks, kg, event_log=self.event_log
486
+ )
487
+ )
488
+ except Exception:
489
+ loop = asyncio.new_event_loop()
490
+ loop.run_until_complete(
491
+ extractor.extract_from_run(
492
+ run_id, completed_tasks, kg, event_log=self.event_log
493
+ )
494
+ )
495
+ except Exception:
496
+ pass
497
+ return results
498
+
499
+ @property
500
+ def last_completed_tasks(self) -> list[Task]:
501
+ """After run(), return completed tasks (id, description, result) for report building."""
502
+ if self._last_scheduler is None:
503
+ return []
504
+ return self._last_scheduler.get_completed_tasks()
505
+
506
+ def map_reduce(
507
+ self, dataset: list, map_fn, reduce_fn, worker_count: int | None = None
508
+ ):
509
+ """
510
+ First-class map-reduce: run map_fn on each item in parallel, then reduce_fn on results.
511
+ Uses the same worker pool pattern as the executor.
512
+ """
513
+ from devsper.swarm.map_reduce import map_reduce as _map_reduce
514
+
515
+ workers = worker_count if worker_count is not None else self.worker_count
516
+ return _map_reduce(dataset, map_fn, reduce_fn, worker_count=workers)
517
+
518
+ def _store_swarm_memory(self, user_task: str, scheduler: Scheduler) -> None:
519
+ """Store important outputs (research findings, summaries, results) into memory after run."""
520
+ from devsper.memory.memory_store import (
521
+ MemoryStore,
522
+ get_default_store,
523
+ generate_memory_id,
524
+ )
525
+ from devsper.memory.memory_types import MemoryRecord, MemoryType
526
+ from devsper.memory.memory_index import MemoryIndex
527
+
528
+ store = getattr(self.memory_router, "store", None)
529
+ if not isinstance(store, MemoryStore):
530
+ store = get_default_store()
531
+ index = getattr(self.memory_router, "index", None) or MemoryIndex(store)
532
+ for task in scheduler.get_completed_tasks():
533
+ content = (task.result or "").strip()
534
+ if not content or len(content) < 10:
535
+ continue
536
+ desc = (task.description or "").lower()
537
+ if "research" in desc or "paper" in desc or "literature" in desc:
538
+ mt = MemoryType.RESEARCH
539
+ elif "code" in desc or "codebase" in desc or "analyze" in desc:
540
+ mt = MemoryType.ARTIFACT
541
+ elif "data" in desc or "dataset" in desc or "experiment" in desc:
542
+ mt = MemoryType.SEMANTIC
543
+ else:
544
+ mt = MemoryType.EPISODIC
545
+ run_id = getattr(self.event_log, "run_id", "") or ""
546
+ record = MemoryRecord(
547
+ id=generate_memory_id(),
548
+ memory_type=mt,
549
+ source_task=task.id,
550
+ content=content[:15000],
551
+ tags=["swarm", "task", task.id, user_task[:100]],
552
+ run_id=run_id,
553
+ )
554
+ record = index.ensure_embedding(record)
555
+ store.store(record)
556
+
557
+ def _emit(self, event_type: events, payload: dict) -> None:
558
+ self.event_log.append_event(
559
+ Event(
560
+ timestamp=datetime.now(timezone.utc), type=event_type, payload=payload
561
+ )
562
+ )
@@ -0,0 +1,33 @@
1
+ """
2
+ devsper tool system: base, registry, tool_runner, and all categorized tools.
3
+
4
+ Importing this package triggers registration of all tools via category __init__.py.
5
+ """
6
+
7
+ from devsper.tools.base import Tool
8
+ from devsper.tools.registry import register, get, list_tools
9
+ from devsper.tools.tool_runner import run_tool
10
+
11
+ from devsper.tools import filesystem
12
+ from devsper.tools import research
13
+ from devsper.tools import coding
14
+ from devsper.tools import data
15
+ from devsper.tools import math as math_tools
16
+ from devsper.tools import system
17
+ from devsper.tools import documents
18
+ from devsper.tools import knowledge
19
+ from devsper.tools import research_advanced
20
+ from devsper.tools import code_intelligence
21
+ from devsper.tools import data_science
22
+ from devsper.tools import experiments
23
+ from devsper.tools import flagship
24
+ from devsper.tools import memory
25
+
26
+ # Load plugins from entry_points (devsper.plugins)
27
+ try:
28
+ from devsper.plugins.plugin_loader import load_plugins
29
+ load_plugins()
30
+ except Exception:
31
+ pass
32
+
33
+ __all__ = ["Tool", "register", "get", "list_tools", "run_tool"]
devsper/tools/base.py ADDED
@@ -0,0 +1,29 @@
1
+ """
2
+ Base tool interface for the devsper tool system.
3
+
4
+ All tools are stateless and must return strings so agents can parse the output.
5
+ """
6
+
7
+ from abc import ABC, abstractmethod
8
+
9
+
10
+ class Tool(ABC):
11
+ """
12
+ Base class for all devsper tools.
13
+
14
+ Tools are stateless. They accept keyword arguments matching input_schema
15
+ and return a string result for the agent to consume.
16
+
17
+ category: optional label for filtering (e.g. "research", "coding", "documents").
18
+ If unset, the tool selector may infer from the tool's module path.
19
+ """
20
+
21
+ name: str = ""
22
+ description: str = ""
23
+ input_schema: dict = {}
24
+ category: str = ""
25
+
26
+ @abstractmethod
27
+ def run(self, **kwargs) -> str:
28
+ """Execute the tool with the given arguments. Returns a string result."""
29
+ ...
@@ -0,0 +1,13 @@
1
+ """Codebase intelligence tools: indexing, dependencies, architecture, API, patterns."""
2
+
3
+ from devsper.tools.code_intelligence.codebase_indexer import CodebaseIndexerTool
4
+ from devsper.tools.code_intelligence.repository_semantic_index import RepositorySemanticIndexTool
5
+ from devsper.tools.code_intelligence.dependency_graph_builder import DependencyGraphBuilderTool
6
+ from devsper.tools.code_intelligence.architecture_analyzer import ArchitectureAnalyzerTool
7
+ from devsper.tools.code_intelligence.api_surface_extractor import ApiSurfaceExtractorTool
8
+ from devsper.tools.code_intelligence.test_coverage_estimator import TestCoverageEstimatorTool
9
+ from devsper.tools.code_intelligence.module_responsibility_mapper import ModuleResponsibilityMapperTool
10
+ from devsper.tools.code_intelligence.design_pattern_detector import DesignPatternDetectorTool
11
+ from devsper.tools.code_intelligence.refactor_candidate_detector import RefactorCandidateDetectorTool
12
+ from devsper.tools.code_intelligence.large_function_detector import LargeFunctionDetectorTool
13
+ from devsper.tools.code_intelligence.parallel_codebase_analysis import ParallelCodebaseAnalysisTool