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
@@ -0,0 +1,51 @@
1
+ """Filter a CSV by column value (simple equality). Requires pandas."""
2
+
3
+ from pathlib import Path
4
+
5
+ from devsper.tools.base import Tool
6
+ from devsper.tools.registry import register
7
+
8
+
9
+ class DataframeFilterTool(Tool):
10
+ """Filter CSV rows where column equals value. Requires pandas."""
11
+
12
+ name = "dataframe_filter"
13
+ description = "Filter CSV by column value. Returns matching rows as string. Requires pandas."
14
+ input_schema = {
15
+ "type": "object",
16
+ "properties": {
17
+ "path": {"type": "string", "description": "Path to CSV"},
18
+ "column": {"type": "string", "description": "Column name"},
19
+ "value": {"type": "string", "description": "Value to match (string)"},
20
+ },
21
+ "required": ["path", "column", "value"],
22
+ }
23
+
24
+ def run(self, **kwargs) -> str:
25
+ path = kwargs.get("path")
26
+ column = kwargs.get("column")
27
+ value = kwargs.get("value")
28
+ if not path or not isinstance(path, str):
29
+ return "Error: path must be a non-empty string"
30
+ if not column or not isinstance(column, str):
31
+ return "Error: column must be a non-empty string"
32
+ if value is None:
33
+ return "Error: value is required"
34
+ try:
35
+ import pandas as pd
36
+ except ImportError:
37
+ return "Error: pandas required. Install with: pip install pandas"
38
+ p = Path(path)
39
+ if not p.exists() or not p.is_file():
40
+ return f"Error: file not found: {path}"
41
+ try:
42
+ df = pd.read_csv(p)
43
+ if column not in df.columns:
44
+ return f"Error: column '{column}' not in {list(df.columns)}"
45
+ filtered = df[df[column].astype(str) == str(value)]
46
+ return filtered.to_string() if not filtered.empty else "No matching rows."
47
+ except Exception as e:
48
+ return f"Error: {e}"
49
+
50
+
51
+ register(DataframeFilterTool())
@@ -0,0 +1,47 @@
1
+ """Group CSV by column and show count per group. Requires pandas."""
2
+
3
+ from pathlib import Path
4
+
5
+ from devsper.tools.base import Tool
6
+ from devsper.tools.registry import register
7
+
8
+
9
+ class DataframeGroupbyTool(Tool):
10
+ """Group CSV by a column and return count per group. Requires pandas."""
11
+
12
+ name = "dataframe_groupby"
13
+ description = "Group CSV by column and show counts. Requires pandas."
14
+ input_schema = {
15
+ "type": "object",
16
+ "properties": {
17
+ "path": {"type": "string", "description": "Path to CSV"},
18
+ "column": {"type": "string", "description": "Column to group by"},
19
+ },
20
+ "required": ["path", "column"],
21
+ }
22
+
23
+ def run(self, **kwargs) -> str:
24
+ path = kwargs.get("path")
25
+ column = kwargs.get("column")
26
+ if not path or not isinstance(path, str):
27
+ return "Error: path must be a non-empty string"
28
+ if not column or not isinstance(column, str):
29
+ return "Error: column must be a non-empty string"
30
+ try:
31
+ import pandas as pd
32
+ except ImportError:
33
+ return "Error: pandas required. Install with: pip install pandas"
34
+ p = Path(path)
35
+ if not p.exists() or not p.is_file():
36
+ return f"Error: file not found: {path}"
37
+ try:
38
+ df = pd.read_csv(p)
39
+ if column not in df.columns:
40
+ return f"Error: column '{column}' not in {list(df.columns)}"
41
+ grouped = df.groupby(column).size()
42
+ return grouped.to_string()
43
+ except Exception as e:
44
+ return f"Error: {e}"
45
+
46
+
47
+ register(DataframeGroupbyTool())
@@ -0,0 +1,38 @@
1
+ """Compute basic statistics for a CSV as a dataframe (requires pandas)."""
2
+
3
+ from pathlib import Path
4
+
5
+ from devsper.tools.base import Tool
6
+ from devsper.tools.registry import register
7
+
8
+
9
+ class DataframeStatsTool(Tool):
10
+ """Load CSV as dataframe and return describe() stats. Requires pandas."""
11
+
12
+ name = "dataframe_stats"
13
+ description = "Compute summary statistics for a CSV file. Requires pandas."
14
+ input_schema = {
15
+ "type": "object",
16
+ "properties": {"path": {"type": "string", "description": "Path to CSV file"}},
17
+ "required": ["path"],
18
+ }
19
+
20
+ def run(self, **kwargs) -> str:
21
+ path = kwargs.get("path")
22
+ if not path or not isinstance(path, str):
23
+ return "Error: path must be a non-empty string"
24
+ try:
25
+ import pandas as pd
26
+ except ImportError:
27
+ return "Error: pandas required. Install with: pip install pandas"
28
+ p = Path(path)
29
+ if not p.exists() or not p.is_file():
30
+ return f"Error: file not found: {path}"
31
+ try:
32
+ df = pd.read_csv(p)
33
+ return str(df.describe())
34
+ except Exception as e:
35
+ return f"Error: {e}"
36
+
37
+
38
+ register(DataframeStatsTool())
@@ -0,0 +1,55 @@
1
+ """Sample N random rows from a CSV."""
2
+
3
+ import csv
4
+ import random
5
+ from pathlib import Path
6
+
7
+ from devsper.tools.base import Tool
8
+ from devsper.tools.registry import register
9
+
10
+
11
+ class DatasetSamplingTool(Tool):
12
+ """Return a random sample of N rows from a CSV file."""
13
+
14
+ name = "dataset_sampling"
15
+ description = "Sample N random rows from a CSV. Returns sampled rows as text."
16
+ input_schema = {
17
+ "type": "object",
18
+ "properties": {
19
+ "path": {"type": "string", "description": "Path to CSV"},
20
+ "n": {"type": "integer", "description": "Number of rows to sample"},
21
+ },
22
+ "required": ["path", "n"],
23
+ }
24
+
25
+ def run(self, **kwargs) -> str:
26
+ path = kwargs.get("path")
27
+ n = kwargs.get("n")
28
+ if not path or not isinstance(path, str):
29
+ return "Error: path must be a non-empty string"
30
+ if not isinstance(n, int) or n < 1:
31
+ return "Error: n must be a positive integer"
32
+ p = Path(path)
33
+ if not p.exists() or not p.is_file():
34
+ return f"Error: file not found: {path}"
35
+ try:
36
+ with p.open(encoding="utf-8", errors="replace", newline="") as f:
37
+ reader = csv.reader(f)
38
+ rows = list(reader)
39
+ if not rows:
40
+ return "Empty CSV."
41
+ header = rows[0]
42
+ data = rows[1:]
43
+ if n >= len(data):
44
+ sample = data
45
+ else:
46
+ sample = random.sample(data, n)
47
+ lines = [",".join(header)]
48
+ for row in sample:
49
+ lines.append(",".join(str(c) for c in row))
50
+ return "\n".join(lines)
51
+ except Exception as e:
52
+ return f"Error: {e}"
53
+
54
+
55
+ register(DatasetSamplingTool())
@@ -0,0 +1,45 @@
1
+ """Describe CSV schema: column names and sample value types."""
2
+
3
+ import csv
4
+ from pathlib import Path
5
+
6
+ from devsper.tools.base import Tool
7
+ from devsper.tools.registry import register
8
+
9
+
10
+ class DatasetSchemaTool(Tool):
11
+ """Return CSV schema: column names and a one-line description (from first row)."""
12
+
13
+ name = "dataset_schema"
14
+ description = "Describe CSV schema: column names and example types."
15
+ input_schema = {
16
+ "type": "object",
17
+ "properties": {"path": {"type": "string", "description": "Path to CSV file"}},
18
+ "required": ["path"],
19
+ }
20
+
21
+ def run(self, **kwargs) -> str:
22
+ path = kwargs.get("path")
23
+ if not path or not isinstance(path, str):
24
+ return "Error: path must be a non-empty string"
25
+ p = Path(path)
26
+ if not p.exists() or not p.is_file():
27
+ return f"Error: file not found: {path}"
28
+ try:
29
+ with p.open(encoding="utf-8", errors="replace", newline="") as f:
30
+ reader = csv.reader(f)
31
+ rows = list(reader)
32
+ if not rows:
33
+ return "Empty CSV."
34
+ header = rows[0]
35
+ sample = rows[1] if len(rows) > 1 else []
36
+ lines = [f"Columns: {len(header)}", ""]
37
+ for i, name in enumerate(header):
38
+ ex = sample[i] if i < len(sample) else ""
39
+ lines.append(f" {name}: example = {repr(ex)[:50]}")
40
+ return "\n".join(lines)
41
+ except Exception as e:
42
+ return f"Error: {e}"
43
+
44
+
45
+ register(DatasetSchemaTool())
@@ -0,0 +1,37 @@
1
+ """Pretty-print JSON with indentation."""
2
+
3
+ import json
4
+
5
+ from devsper.tools.base import Tool
6
+ from devsper.tools.registry import register
7
+
8
+
9
+ class JsonPrettyPrintTool(Tool):
10
+ """Format JSON string with indentation for readability."""
11
+
12
+ name = "json_pretty_print"
13
+ description = "Pretty-print a JSON string with indentation."
14
+ input_schema = {
15
+ "type": "object",
16
+ "properties": {
17
+ "json_str": {"type": "string", "description": "JSON string to format"},
18
+ "indent": {"type": "integer", "description": "Indent spaces (default 2)"},
19
+ },
20
+ "required": ["json_str"],
21
+ }
22
+
23
+ def run(self, **kwargs) -> str:
24
+ json_str = kwargs.get("json_str")
25
+ indent = kwargs.get("indent", 2)
26
+ if json_str is None:
27
+ return "Error: json_str is required"
28
+ if not isinstance(indent, int) or indent < 0:
29
+ indent = 2
30
+ try:
31
+ data = json.loads(json_str)
32
+ return json.dumps(data, indent=indent)
33
+ except json.JSONDecodeError as e:
34
+ return f"Invalid JSON: {e}"
35
+
36
+
37
+ register(JsonPrettyPrintTool())
@@ -0,0 +1,46 @@
1
+ """Query JSON with a simple key path (e.g. "a.b.0")."""
2
+
3
+ import json
4
+
5
+ from devsper.tools.base import Tool
6
+ from devsper.tools.registry import register
7
+
8
+
9
+ class JsonQueryTool(Tool):
10
+ """Get a value from JSON by key path. Path uses dot notation and index for arrays (e.g. data.items.0)."""
11
+
12
+ name = "json_query"
13
+ description = "Query JSON with a dot-path (e.g. key.nested.0). Returns the value as string."
14
+ input_schema = {
15
+ "type": "object",
16
+ "properties": {
17
+ "json_str": {"type": "string", "description": "JSON string"},
18
+ "path": {"type": "string", "description": "Dot-separated path, use numbers for list index"},
19
+ },
20
+ "required": ["json_str", "path"],
21
+ }
22
+
23
+ def run(self, **kwargs) -> str:
24
+ json_str = kwargs.get("json_str")
25
+ path = kwargs.get("path")
26
+ if json_str is None:
27
+ return "Error: json_str is required"
28
+ if not path or not isinstance(path, str):
29
+ return "Error: path must be a non-empty string"
30
+ try:
31
+ data = json.loads(json_str)
32
+ except json.JSONDecodeError as e:
33
+ return f"Invalid JSON: {e}"
34
+ parts = path.strip().split(".")
35
+ try:
36
+ for p in parts:
37
+ if p.isdigit():
38
+ data = data[int(p)]
39
+ else:
40
+ data = data[p]
41
+ return json.dumps(data) if not isinstance(data, str) else data
42
+ except (KeyError, IndexError, TypeError) as e:
43
+ return f"Path error: {e}"
44
+
45
+
46
+ register(JsonQueryTool())
@@ -0,0 +1,47 @@
1
+ """Report missing/empty values per column in a CSV."""
2
+
3
+ import csv
4
+ from pathlib import Path
5
+
6
+ from devsper.tools.base import Tool
7
+ from devsper.tools.registry import register
8
+
9
+
10
+ class MissingValueReportTool(Tool):
11
+ """Count missing or empty values per column in a CSV."""
12
+
13
+ name = "missing_value_report"
14
+ description = "Report count of missing/empty values per column in a CSV."
15
+ input_schema = {
16
+ "type": "object",
17
+ "properties": {"path": {"type": "string", "description": "Path to CSV file"}},
18
+ "required": ["path"],
19
+ }
20
+
21
+ def run(self, **kwargs) -> str:
22
+ path = kwargs.get("path")
23
+ if not path or not isinstance(path, str):
24
+ return "Error: path must be a non-empty string"
25
+ p = Path(path)
26
+ if not p.exists() or not p.is_file():
27
+ return f"Error: file not found: {path}"
28
+ try:
29
+ with p.open(encoding="utf-8", errors="replace", newline="") as f:
30
+ reader = csv.reader(f)
31
+ rows = list(reader)
32
+ if not rows:
33
+ return "Empty CSV."
34
+ header = rows[0]
35
+ data = rows[1:]
36
+ n_rows = len(data)
37
+ lines = [f"Total rows: {n_rows}", ""]
38
+ for col_idx, col_name in enumerate(header):
39
+ missing = sum(1 for row in data if col_idx >= len(row) or (row[col_idx] or "").strip() == "")
40
+ pct = (100 * missing / n_rows) if n_rows else 0
41
+ lines.append(f"{col_name}: {missing} missing ({pct:.1f}%)")
42
+ return "\n".join(lines)
43
+ except Exception as e:
44
+ return f"Error: {e}"
45
+
46
+
47
+ register(MissingValueReportTool())
@@ -0,0 +1,13 @@
1
+ """Data science tools: profiling, distributions, outliers, correlation, drift, bias."""
2
+
3
+ from devsper.tools.data_science.dataset_profile import DatasetProfileTool
4
+ from devsper.tools.data_science.feature_importance_estimator import FeatureImportanceEstimatorTool
5
+ from devsper.tools.data_science.dataset_distribution_report import DatasetDistributionReportTool
6
+ from devsper.tools.data_science.dataset_outlier_detector import DatasetOutlierDetectorTool
7
+ from devsper.tools.data_science.correlation_heatmap import CorrelationHeatmapTool
8
+ from devsper.tools.data_science.time_series_analyzer import TimeSeriesAnalyzerTool
9
+ from devsper.tools.data_science.model_input_validator import ModelInputValidatorTool
10
+ from devsper.tools.data_science.dataset_drift_detector import DatasetDriftDetectorTool
11
+ from devsper.tools.data_science.feature_engineering_suggestions import FeatureEngineeringSuggestionsTool
12
+ from devsper.tools.data_science.dataset_bias_detector import DatasetBiasDetectorTool
13
+ from devsper.tools.data_science.distributed_dataset_processor import DistributedDatasetProcessorTool
@@ -0,0 +1,72 @@
1
+ """Compute pairwise correlation matrix for numeric columns and return as text table."""
2
+
3
+ import csv
4
+ from pathlib import Path
5
+
6
+ from devsper.tools.base import Tool
7
+ from devsper.tools.registry import register
8
+
9
+ try:
10
+ import numpy as np
11
+ except ImportError:
12
+ np = None
13
+
14
+
15
+ class CorrelationHeatmapTool(Tool):
16
+ """
17
+ Compute pairwise correlations for numeric columns and return a text-based heatmap (matrix).
18
+ """
19
+
20
+ name = "correlation_heatmap"
21
+ description = "Compute pairwise correlation matrix for numeric columns; return as text table."
22
+ input_schema = {
23
+ "type": "object",
24
+ "properties": {
25
+ "path": {"type": "string", "description": "Path to CSV"},
26
+ "max_columns": {"type": "integer", "description": "Max columns (default 10)"},
27
+ },
28
+ "required": ["path"],
29
+ }
30
+
31
+ def run(self, **kwargs) -> str:
32
+ path = kwargs.get("path")
33
+ max_columns = kwargs.get("max_columns", 10)
34
+ if not path or not isinstance(path, str):
35
+ return "Error: path must be a non-empty string"
36
+ if not isinstance(max_columns, int) or max_columns < 1:
37
+ max_columns = 10
38
+ if np is None:
39
+ return "Error: numpy is required for this tool"
40
+ p = Path(path).resolve()
41
+ if not p.exists() or not p.is_file():
42
+ return f"Error: file not found: {path}"
43
+ try:
44
+ with p.open(encoding="utf-8", errors="replace", newline="") as f:
45
+ reader = csv.DictReader(f)
46
+ rows = list(reader)
47
+ if not rows:
48
+ return "Empty CSV."
49
+ numeric_cols = []
50
+ for col in list(rows[0].keys())[:max_columns]:
51
+ try:
52
+ arr = np.array([float(row.get(col, np.nan)) for row in rows], dtype=float)
53
+ if np.isnan(arr).all():
54
+ continue
55
+ numeric_cols.append((col, arr))
56
+ except (ValueError, TypeError):
57
+ continue
58
+ if len(numeric_cols) < 2:
59
+ return "Need at least 2 numeric columns."
60
+ names = [n for n, _ in numeric_cols]
61
+ mat = np.column_stack([a for _, a in numeric_cols])
62
+ corr = np.corrcoef(mat.T)
63
+ lines = ["Correlation matrix", "=" * 40, "Columns: " + ", ".join(names), ""]
64
+ for i, name in enumerate(names):
65
+ parts = [f"{corr[i, j]:.2f}" for j in range(len(names))]
66
+ lines.append(f" {name}: " + " ".join(parts))
67
+ return "\n".join(lines)
68
+ except Exception as e:
69
+ return f"Error: {e}"
70
+
71
+
72
+ register(CorrelationHeatmapTool())
@@ -0,0 +1,49 @@
1
+ """Detect potential bias: check balance of a categorical variable (e.g. class or group)."""
2
+
3
+ from collections import Counter
4
+
5
+ from devsper.tools.base import Tool
6
+ from devsper.tools.registry import register
7
+
8
+
9
+ class DatasetBiasDetectorTool(Tool):
10
+ """
11
+ Detect potential class/group imbalance: report distribution of a categorical variable.
12
+ """
13
+
14
+ name = "dataset_bias_detector"
15
+ description = "Detect potential bias: report balance of a categorical (e.g. class) distribution."
16
+ input_schema = {
17
+ "type": "object",
18
+ "properties": {
19
+ "values": {
20
+ "type": "array",
21
+ "items": {},
22
+ "description": "List of categorical values (e.g. labels or group IDs)",
23
+ },
24
+ "imbalance_ratio_threshold": {"type": "number", "description": "Flag if max/min count ratio > this (default 10)"},
25
+ },
26
+ "required": ["values"],
27
+ }
28
+
29
+ def run(self, **kwargs) -> str:
30
+ values = kwargs.get("values")
31
+ threshold = kwargs.get("imbalance_ratio_threshold", 10.0)
32
+ if not values or not isinstance(values, list):
33
+ return "Error: values must be a non-empty list"
34
+ counts = Counter(str(v) for v in values)
35
+ if len(counts) < 2:
36
+ return "Need at least 2 distinct categories to assess balance."
37
+ total = sum(counts.values())
38
+ max_c, min_c = max(counts.values()), min(counts.values())
39
+ ratio = max_c / min_c if min_c > 0 else float("inf")
40
+ lines = ["Bias / balance report", "=" * 40, f"Total: {total}, Categories: {len(counts)}", f"Max/min count ratio: {ratio:.1f}"]
41
+ if ratio > threshold:
42
+ lines.append("Imbalance detected (ratio > threshold).")
43
+ for label, c in counts.most_common(15):
44
+ pct = 100 * c / total
45
+ lines.append(f" {label}: {c} ({pct:.1f}%)")
46
+ return "\n".join(lines)
47
+
48
+
49
+ register(DatasetBiasDetectorTool())
@@ -0,0 +1,64 @@
1
+ """Report distribution statistics for numeric columns: mean, std, quartiles."""
2
+
3
+ import csv
4
+ from pathlib import Path
5
+
6
+ from devsper.tools.base import Tool
7
+ from devsper.tools.registry import register
8
+
9
+ try:
10
+ import numpy as np
11
+ except ImportError:
12
+ np = None
13
+
14
+
15
+ class DatasetDistributionReportTool(Tool):
16
+ """
17
+ Report distribution stats for numeric columns: mean, std, min, max, quartiles.
18
+ """
19
+
20
+ name = "dataset_distribution_report"
21
+ description = "Report distribution statistics for numeric columns in a dataset."
22
+ input_schema = {
23
+ "type": "object",
24
+ "properties": {
25
+ "path": {"type": "string", "description": "Path to CSV"},
26
+ "max_columns": {"type": "integer", "description": "Max columns to report (default 20)"},
27
+ },
28
+ "required": ["path"],
29
+ }
30
+
31
+ def run(self, **kwargs) -> str:
32
+ path = kwargs.get("path")
33
+ max_columns = kwargs.get("max_columns", 20)
34
+ if not path or not isinstance(path, str):
35
+ return "Error: path must be a non-empty string"
36
+ if not isinstance(max_columns, int) or max_columns < 1:
37
+ max_columns = 20
38
+ if np is None:
39
+ return "Error: numpy is required for this tool"
40
+ p = Path(path).resolve()
41
+ if not p.exists() or not p.is_file():
42
+ return f"Error: file not found: {path}"
43
+ try:
44
+ with p.open(encoding="utf-8", errors="replace", newline="") as f:
45
+ reader = csv.DictReader(f)
46
+ rows = list(reader)
47
+ if not rows:
48
+ return "Empty CSV."
49
+ lines = ["Distribution report", "=" * 40]
50
+ for col in list(rows[0].keys())[:max_columns]:
51
+ try:
52
+ arr = np.array([float(row.get(col, np.nan)) for row in rows], dtype=float)
53
+ arr = arr[~np.isnan(arr)]
54
+ if len(arr) < 2:
55
+ continue
56
+ lines.append(f"{col}: mean={np.mean(arr):.4f}, std={np.std(arr):.4f}, min={np.min(arr):.4f}, max={np.max(arr):.4f}, q25={np.percentile(arr, 25):.4f}, q75={np.percentile(arr, 75):.4f}")
57
+ except (ValueError, TypeError):
58
+ continue
59
+ return "\n".join(lines) if len(lines) > 1 else "No numeric columns found."
60
+ except Exception as e:
61
+ return f"Error: {e}"
62
+
63
+
64
+ register(DatasetDistributionReportTool())
@@ -0,0 +1,64 @@
1
+ """Detect simple distribution drift between two samples: compare mean and std."""
2
+
3
+ from devsper.tools.base import Tool
4
+ from devsper.tools.registry import register
5
+
6
+ try:
7
+ import numpy as np
8
+ except ImportError:
9
+ np = None
10
+
11
+
12
+ class DatasetDriftDetectorTool(Tool):
13
+ """
14
+ Detect basic drift between two numeric samples: difference in mean and std.
15
+ """
16
+
17
+ name = "dataset_drift_detector"
18
+ description = "Detect distribution drift between two numeric samples (mean, std comparison)."
19
+ input_schema = {
20
+ "type": "object",
21
+ "properties": {
22
+ "baseline": {
23
+ "type": "array",
24
+ "items": {"type": "number"},
25
+ "description": "Baseline sample",
26
+ },
27
+ "current": {
28
+ "type": "array",
29
+ "items": {"type": "number"},
30
+ "description": "Current sample",
31
+ },
32
+ "threshold_std": {"type": "number", "description": "Flag if mean diff > this many baseline stds (default 2)"},
33
+ },
34
+ "required": ["baseline", "current"],
35
+ }
36
+
37
+ def run(self, **kwargs) -> str:
38
+ baseline = kwargs.get("baseline")
39
+ current = kwargs.get("current")
40
+ threshold_std = kwargs.get("threshold_std", 2.0)
41
+ if not baseline or not isinstance(baseline, list):
42
+ return "Error: baseline must be a non-empty list of numbers"
43
+ if not current or not isinstance(current, list):
44
+ return "Error: current must be a non-empty list of numbers"
45
+ if np is None:
46
+ return "Error: numpy is required for this tool"
47
+ try:
48
+ b = np.array(baseline, dtype=float)
49
+ c = np.array(current, dtype=float)
50
+ b, c = b[~np.isnan(b)], c[~np.isnan(c)]
51
+ except (ValueError, TypeError):
52
+ return "Error: values must be numeric"
53
+ if len(b) < 2 or len(c) < 2:
54
+ return "Error: need at least 2 values per sample"
55
+ mean_b, std_b = np.mean(b), np.std(b)
56
+ mean_c, std_c = np.mean(c), np.std(c)
57
+ mean_diff = abs(mean_c - mean_b)
58
+ std_b_safe = std_b if std_b > 0 else 1e-10
59
+ z = mean_diff / std_b_safe
60
+ drift = "Drift detected" if z > threshold_std else "No significant drift"
61
+ return f"{drift}. Baseline: mean={mean_b:.4f}, std={std_b:.4f}. Current: mean={mean_c:.4f}, std={std_c:.4f}. Mean diff (in baseline stds): {z:.2f}"
62
+
63
+
64
+ register(DatasetDriftDetectorTool())