aria-code 0.167.0__py3-none-win_amd64.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 (601) hide show
  1. aria_bots/__init__.py +7 -0
  2. aria_bots/channels/README.md +97 -0
  3. aria_bots/channels/__init__.py +1 -0
  4. aria_bots/channels/approvals.py +263 -0
  5. aria_bots/channels/conversation.py +280 -0
  6. aria_bots/channels/digest.py +186 -0
  7. aria_bots/channels/registry.py +95 -0
  8. aria_bots/engine.py +144 -0
  9. aria_bots/feishu_bot.py +1385 -0
  10. aria_bots/logistics/__init__.py +1 -0
  11. aria_bots/logistics/carriers.py +253 -0
  12. aria_bots/logistics/freight.py +154 -0
  13. aria_bots/logistics/inventory.py +242 -0
  14. aria_bots/logistics/mcp_server.py +156 -0
  15. aria_bots/logistics/records.py +119 -0
  16. aria_bots/logistics/tenancy.py +152 -0
  17. aria_bots/market.py +91 -0
  18. aria_bots/relay_client.py +326 -0
  19. aria_bots/telegram_bot.py +299 -0
  20. aria_code/__init__.py +111 -0
  21. aria_code/_bin/aria-native.exe +0 -0
  22. aria_code/_bin/aria-runtime.exe +0 -0
  23. aria_code/_version.py +20 -0
  24. aria_code/account_memory.py +296 -0
  25. aria_code/account_session.py +166 -0
  26. aria_code/adk_apps/__init__.py +1 -0
  27. aria_code/adk_apps/aria_code_review/__init__.py +1 -0
  28. aria_code/adk_apps/aria_code_review/agent.py +32 -0
  29. aria_code/adk_apps/aria_research/__init__.py +1 -0
  30. aria_code/adk_apps/aria_research/agent.py +31 -0
  31. aria_code/agents/__init__.py +49 -0
  32. aria_code/agents/base.py +329 -0
  33. aria_code/agents/code_review.py +200 -0
  34. aria_code/agents/deep/__init__.py +37 -0
  35. aria_code/agents/deep/calibration_loop.py +144 -0
  36. aria_code/agents/deep/critic.py +125 -0
  37. aria_code/agents/deep/deepen.py +193 -0
  38. aria_code/agents/deep/models.py +149 -0
  39. aria_code/agents/deep/pipeline.py +164 -0
  40. aria_code/agents/deep/quant_fusion.py +192 -0
  41. aria_code/agents/deep/themes.py +95 -0
  42. aria_code/agents/deep/tiers.py +106 -0
  43. aria_code/agents/engineering/__init__.py +14 -0
  44. aria_code/agents/engineering/coder.py +222 -0
  45. aria_code/agents/engineering/tester.py +145 -0
  46. aria_code/agents/financial/__init__.py +21 -0
  47. aria_code/agents/financial/cashflow_burn.py +119 -0
  48. aria_code/agents/financial/catalyst.py +279 -0
  49. aria_code/agents/financial/corporate_finance.py +175 -0
  50. aria_code/agents/financial/debate.py +224 -0
  51. aria_code/agents/financial/earnings.py +315 -0
  52. aria_code/agents/financial/fundamental.py +178 -0
  53. aria_code/agents/financial/macro.py +111 -0
  54. aria_code/agents/financial/news.py +231 -0
  55. aria_code/agents/financial/risk.py +146 -0
  56. aria_code/agents/financial/sector.py +279 -0
  57. aria_code/agents/financial/strategist.py +121 -0
  58. aria_code/agents/financial/stripe_revenue.py +127 -0
  59. aria_code/agents/financial/synthesis.py +274 -0
  60. aria_code/agents/financial/technical.py +277 -0
  61. aria_code/agents/orchestrator.py +44 -0
  62. aria_code/agents/portfolio_agent.py +392 -0
  63. aria_code/agents/realty/__init__.py +62 -0
  64. aria_code/agents/realty/asset_diagnosis.py +152 -0
  65. aria_code/agents/realty/business_match.py +166 -0
  66. aria_code/agents/realty/cashflow_verify.py +209 -0
  67. aria_code/agents/realty/contract_rules.py +210 -0
  68. aria_code/agents/realty/energy_anomaly.py +189 -0
  69. aria_code/agents/realty/exit_settlement.py +208 -0
  70. aria_code/agents/realty/fulfillment_risk.py +206 -0
  71. aria_code/agents/realty/ops_optimize.py +160 -0
  72. aria_code/agents/realty/revenue_share.py +215 -0
  73. aria_code/agents/registry.py +168 -0
  74. aria_code/agents/signal_scheme.py +111 -0
  75. aria_code/agents/sports/__init__.py +0 -0
  76. aria_code/agents/sports/football_agent.py +197 -0
  77. aria_code/agents/supervisor.py +113 -0
  78. aria_code/agents/team.py +500 -0
  79. aria_code/agents/video/__init__.py +16 -0
  80. aria_code/agents/video/director.py +376 -0
  81. aria_code/agents/video/qa_agent.py +143 -0
  82. aria_code/agents/video/script_doctor.py +112 -0
  83. aria_code/agents/warehouse/__init__.py +25 -0
  84. aria_code/agents/warehouse/contracts.py +26 -0
  85. aria_code/agents/warehouse/dashboard.py +155 -0
  86. aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
  87. aria_code/agents/warehouse/inbound_exceptions.py +25 -0
  88. aria_code/agents/warehouse/inventory_health.py +24 -0
  89. aria_code/agents/warehouse/local_run.py +71 -0
  90. aria_code/agents/warehouse/local_snapshot.py +132 -0
  91. aria_code/agents/warehouse/logistics_cost.py +84 -0
  92. aria_code/agents/warehouse/logistics_sync.py +21 -0
  93. aria_code/agents/warehouse/navigation.schema.json +110 -0
  94. aria_code/agents/warehouse/task_agent.py +172 -0
  95. aria_code/agents/warehouse/workflow.py +31 -0
  96. aria_code/aliyun_data_client.py +4 -0
  97. aria_code/apps/README.md +12 -0
  98. aria_code/apps/__init__.py +2 -0
  99. aria_code/apps/channels/README.md +9 -0
  100. aria_code/apps/channels/__init__.py +17 -0
  101. aria_code/apps/channels/approvals.py +11 -0
  102. aria_code/apps/channels/conversation.py +11 -0
  103. aria_code/apps/channels/digest.py +11 -0
  104. aria_code/apps/channels/intake.py +92 -0
  105. aria_code/apps/channels/registry.py +11 -0
  106. aria_code/apps/channels/tradingview.py +94 -0
  107. aria_code/apps/cli/README.md +13 -0
  108. aria_code/apps/cli/__init__.py +2 -0
  109. aria_code/apps/cli/_optional.py +120 -0
  110. aria_code/apps/cli/app_server.py +656 -0
  111. aria_code/apps/cli/auto_update.py +125 -0
  112. aria_code/apps/cli/bootstrap.py +206 -0
  113. aria_code/apps/cli/broker_render.py +206 -0
  114. aria_code/apps/cli/chat_turn.py +1327 -0
  115. aria_code/apps/cli/cloud_models.py +231 -0
  116. aria_code/apps/cli/codegen_paths.py +29 -0
  117. aria_code/apps/cli/commands/__init__.py +34 -0
  118. aria_code/apps/cli/commands/_business_render.py +78 -0
  119. aria_code/apps/cli/commands/_ui.py +71 -0
  120. aria_code/apps/cli/commands/analysis_cmds.py +378 -0
  121. aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
  122. aria_code/apps/cli/commands/auth_cmds.py +215 -0
  123. aria_code/apps/cli/commands/backtest_cmds.py +2518 -0
  124. aria_code/apps/cli/commands/broker_cmds.py +1236 -0
  125. aria_code/apps/cli/commands/business_workflow_cmds.py +379 -0
  126. aria_code/apps/cli/commands/canvas_cmds.py +77 -0
  127. aria_code/apps/cli/commands/catalog.py +189 -0
  128. aria_code/apps/cli/commands/core_cmds.py +2748 -0
  129. aria_code/apps/cli/commands/data_cmds.py +521 -0
  130. aria_code/apps/cli/commands/diagnostic_cmds.py +285 -0
  131. aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
  132. aria_code/apps/cli/commands/engineering_cmds.py +399 -0
  133. aria_code/apps/cli/commands/file_cmds.py +312 -0
  134. aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
  135. aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
  136. aria_code/apps/cli/commands/market.py +544 -0
  137. aria_code/apps/cli/commands/market_cmds.py +1419 -0
  138. aria_code/apps/cli/commands/market_context.py +432 -0
  139. aria_code/apps/cli/commands/market_render.py +7 -0
  140. aria_code/apps/cli/commands/model_cmds.py +2374 -0
  141. aria_code/apps/cli/commands/ops_cmds.py +721 -0
  142. aria_code/apps/cli/commands/orchestrator_cmds.py +181 -0
  143. aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
  144. aria_code/apps/cli/commands/portfolio_cmds.py +1316 -0
  145. aria_code/apps/cli/commands/report.py +476 -0
  146. aria_code/apps/cli/commands/scaffold_templates.py +617 -0
  147. aria_code/apps/cli/commands/session_cmds.py +236 -0
  148. aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
  149. aria_code/apps/cli/commands/team.py +723 -0
  150. aria_code/apps/cli/commands/team_render.py +8 -0
  151. aria_code/apps/cli/commands/ui_cmds.py +401 -0
  152. aria_code/apps/cli/commands/warehouse_cmds.py +297 -0
  153. aria_code/apps/cli/commands/workflow_cmds.py +629 -0
  154. aria_code/apps/cli/commands/workspace_cmds.py +1543 -0
  155. aria_code/apps/cli/config_paths.py +73 -0
  156. aria_code/apps/cli/config_store.py +158 -0
  157. aria_code/apps/cli/constants.py +88 -0
  158. aria_code/apps/cli/context.py +34 -0
  159. aria_code/apps/cli/conversation_policy.py +53 -0
  160. aria_code/apps/cli/deterministic.py +200 -0
  161. aria_code/apps/cli/direct.py +48 -0
  162. aria_code/apps/cli/earnings_view.py +172 -0
  163. aria_code/apps/cli/endpoint_migration.py +64 -0
  164. aria_code/apps/cli/exec_events.py +255 -0
  165. aria_code/apps/cli/file_references.py +155 -0
  166. aria_code/apps/cli/finance_service_catalog.py +111 -0
  167. aria_code/apps/cli/football_reports.py +231 -0
  168. aria_code/apps/cli/github_app_auth.py +135 -0
  169. aria_code/apps/cli/google_login.py +239 -0
  170. aria_code/apps/cli/handlers/__init__.py +11 -0
  171. aria_code/apps/cli/handlers/broker_handlers.py +122 -0
  172. aria_code/apps/cli/handlers/chart_handlers.py +1314 -0
  173. aria_code/apps/cli/handlers/market_handlers.py +2570 -0
  174. aria_code/apps/cli/handlers/realty_handlers.py +114 -0
  175. aria_code/apps/cli/handlers/sports_handlers.py +22 -0
  176. aria_code/apps/cli/handlers/strategy_advice.py +82 -0
  177. aria_code/apps/cli/headless.py +352 -0
  178. aria_code/apps/cli/helpers.py +326 -0
  179. aria_code/apps/cli/hooks.py +180 -0
  180. aria_code/apps/cli/i18n.py +310 -0
  181. aria_code/apps/cli/intent.py +136 -0
  182. aria_code/apps/cli/intent_router.py +305 -0
  183. aria_code/apps/cli/intent_shadow.py +72 -0
  184. aria_code/apps/cli/intent_signals.py +347 -0
  185. aria_code/apps/cli/lifecycle_hooks.py +48 -0
  186. aria_code/apps/cli/local_tool_schemas.py +550 -0
  187. aria_code/apps/cli/main.py +39 -0
  188. aria_code/apps/cli/market_hours.py +100 -0
  189. aria_code/apps/cli/market_metadata.py +135 -0
  190. aria_code/apps/cli/market_universe.py +487 -0
  191. aria_code/apps/cli/message_processing.py +310 -0
  192. aria_code/apps/cli/mixin_binding.py +32 -0
  193. aria_code/apps/cli/model_catalog.py +652 -0
  194. aria_code/apps/cli/model_probe.py +169 -0
  195. aria_code/apps/cli/model_retirement.py +65 -0
  196. aria_code/apps/cli/native_branding.py +12 -0
  197. aria_code/apps/cli/native_bridge.py +118 -0
  198. aria_code/apps/cli/native_entry.py +58 -0
  199. aria_code/apps/cli/pdf_report.py +977 -0
  200. aria_code/apps/cli/plan_mode.py +139 -0
  201. aria_code/apps/cli/plotly_html.py +15 -0
  202. aria_code/apps/cli/prediction_feedback.py +202 -0
  203. aria_code/apps/cli/preflight.py +502 -0
  204. aria_code/apps/cli/project_aria.py +60 -0
  205. aria_code/apps/cli/prompt_assembly.py +78 -0
  206. aria_code/apps/cli/prompts/__init__.py +0 -0
  207. aria_code/apps/cli/prompts/coding.py +71 -0
  208. aria_code/apps/cli/prompts/select.py +193 -0
  209. aria_code/apps/cli/prompts/system_prompts.py +562 -0
  210. aria_code/apps/cli/prompts/ui.py +436 -0
  211. aria_code/apps/cli/provider_endpoints.py +237 -0
  212. aria_code/apps/cli/provider_keys.py +73 -0
  213. aria_code/apps/cli/providers/__init__.py +1 -0
  214. aria_code/apps/cli/providers/base.py +775 -0
  215. aria_code/apps/cli/providers/chat_routing.py +139 -0
  216. aria_code/apps/cli/providers/collaboration.py +98 -0
  217. aria_code/apps/cli/providers/llm/__init__.py +1 -0
  218. aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
  219. aria_code/apps/cli/providers/llm/ollama_stream.py +1574 -0
  220. aria_code/apps/cli/providers/llm/response_cache.py +60 -0
  221. aria_code/apps/cli/providers/llm/sse_stream.py +298 -0
  222. aria_code/apps/cli/providers/runtime_bridge.py +586 -0
  223. aria_code/apps/cli/providers/vertexai_stream.py +592 -0
  224. aria_code/apps/cli/release_download.py +159 -0
  225. aria_code/apps/cli/review_runner.py +111 -0
  226. aria_code/apps/cli/runtime_consumer.py +769 -0
  227. aria_code/apps/cli/sandbox.py +32 -0
  228. aria_code/apps/cli/session_export.py +120 -0
  229. aria_code/apps/cli/session_jsonl.py +208 -0
  230. aria_code/apps/cli/session_refresh.py +123 -0
  231. aria_code/apps/cli/session_store.py +125 -0
  232. aria_code/apps/cli/skills_catalog.py +273 -0
  233. aria_code/apps/cli/task_isolation.py +211 -0
  234. aria_code/apps/cli/terminal_chrome.py +412 -0
  235. aria_code/apps/cli/todo_tracker.py +190 -0
  236. aria_code/apps/cli/tool_executor.py +932 -0
  237. aria_code/apps/cli/tool_registry.py +34 -0
  238. aria_code/apps/cli/tool_scope.py +113 -0
  239. aria_code/apps/cli/tools/__init__.py +40 -0
  240. aria_code/apps/cli/tools/context.py +46 -0
  241. aria_code/apps/cli/tools/file_tools.py +181 -0
  242. aria_code/apps/cli/tools/market_tools.py +626 -0
  243. aria_code/apps/cli/tools/notebook_tools.py +111 -0
  244. aria_code/apps/cli/tools/system_tools.py +656 -0
  245. aria_code/apps/cli/tools/write_tools.py +961 -0
  246. aria_code/apps/cli/tradingview_bridge.py +529 -0
  247. aria_code/apps/cli/transactions.py +269 -0
  248. aria_code/apps/cli/turn_planning.py +137 -0
  249. aria_code/apps/cli/update_check.py +257 -0
  250. aria_code/apps/cli/updater.py +373 -0
  251. aria_code/apps/cli/utils/__init__.py +0 -0
  252. aria_code/apps/cli/utils/market_detect.py +1663 -0
  253. aria_code/apps/cli/web_login.py +136 -0
  254. aria_code/apps/cli/workflow_runner.py +127 -0
  255. aria_code/apps/cli/workspace_route.py +121 -0
  256. aria_code/apps/daemon/README.md +14 -0
  257. aria_code/apps/vscode/README.md +115 -0
  258. aria_code/apps/vscode/package.json +70 -0
  259. aria_code/aria_cli.py +5244 -0
  260. aria_code/aria_daemon.py +1372 -0
  261. aria_code/aria_feishu_bot.py +16 -0
  262. aria_code/aria_mcp_server.py +61 -0
  263. aria_code/aria_relay_client.py +4 -0
  264. aria_code/aria_telegram_bot.py +11 -0
  265. aria_code/ariarc.py +385 -0
  266. aria_code/artifacts.py +581 -0
  267. aria_code/backtest_engine.py +4 -0
  268. aria_code/backtest_report.py +4 -0
  269. aria_code/brokers/__init__.py +78 -0
  270. aria_code/brokers/automation.py +193 -0
  271. aria_code/brokers/base.py +231 -0
  272. aria_code/brokers/capabilities.py +264 -0
  273. aria_code/brokers/cn/__init__.py +10 -0
  274. aria_code/brokers/cn/easytrader_broker.py +193 -0
  275. aria_code/brokers/cn/futu_broker.py +194 -0
  276. aria_code/brokers/cn/longbridge_broker.py +190 -0
  277. aria_code/brokers/cn/tiger_broker.py +196 -0
  278. aria_code/brokers/cn/xtquant_broker.py +225 -0
  279. aria_code/brokers/config.py +414 -0
  280. aria_code/brokers/intl/__init__.py +5 -0
  281. aria_code/brokers/intl/alpaca_broker.py +183 -0
  282. aria_code/brokers/intl/ibkr_broker.py +215 -0
  283. aria_code/brokers/intl/trading212_broker.py +183 -0
  284. aria_code/brokers/intl/webull_broker.py +156 -0
  285. aria_code/brokers/paper_broker.py +266 -0
  286. aria_code/brokers/planning.py +296 -0
  287. aria_code/brokers/registry.py +213 -0
  288. aria_code/brokers/trading.py +267 -0
  289. aria_code/canva_client.py +4 -0
  290. aria_code/change_store.py +127 -0
  291. aria_code/clients/__init__.py +0 -0
  292. aria_code/clients/aliyun_data_client.py +660 -0
  293. aria_code/clients/aria_relay_client.py +16 -0
  294. aria_code/clients/canva_client.py +284 -0
  295. aria_code/clients/figma_client.py +100 -0
  296. aria_code/clients/football_data_client.py +1671 -0
  297. aria_code/clients/kling_video_client.py +182 -0
  298. aria_code/clients/market_data_client.py +1985 -0
  299. aria_code/clients/openai_image_client.py +242 -0
  300. aria_code/clients/runway_video_client.py +157 -0
  301. aria_code/clients/warehouse_erp_client.py +105 -0
  302. aria_code/cloud_memory.py +190 -0
  303. aria_code/command_safety.py +19 -0
  304. aria_code/computer_use_server.py +276 -0
  305. aria_code/computer_use_tools.py +4 -0
  306. aria_code/dashboard_generator.py +579 -0
  307. aria_code/data_analysis_tools.py +4 -0
  308. aria_code/data_cleaner.py +483 -0
  309. aria_code/data_service.py +513 -0
  310. aria_code/datasources/__init__.py +23 -0
  311. aria_code/datasources/base.py +166 -0
  312. aria_code/datasources/router.py +253 -0
  313. aria_code/datasources/sec_statements.py +217 -0
  314. aria_code/datasources/sources/__init__.py +15 -0
  315. aria_code/datasources/sources/akshare_source.py +269 -0
  316. aria_code/datasources/sources/alpha_vantage_source.py +203 -0
  317. aria_code/datasources/sources/edgar_source.py +219 -0
  318. aria_code/datasources/sources/finnhub_source.py +198 -0
  319. aria_code/datasources/sources/fred_source.py +223 -0
  320. aria_code/datasources/sources/tushare_source.py +143 -0
  321. aria_code/datasources/sources/web_scraper_source.py +278 -0
  322. aria_code/datasources/sources/world_bank_source.py +206 -0
  323. aria_code/datasources/sources/yfinance_source.py +152 -0
  324. aria_code/doctor.py +860 -0
  325. aria_code/domain/__init__.py +0 -0
  326. aria_code/domain/_finance_core/__init__.py +5 -0
  327. aria_code/domain/_finance_core/backtest_engine.py +325 -0
  328. aria_code/domain/_finance_core/performance_stats.py +101 -0
  329. aria_code/domain/backtest_engine.py +75 -0
  330. aria_code/domain/backtest_report.py +488 -0
  331. aria_code/domain/finance_formulas.py +389 -0
  332. aria_code/domain/performance_stats.py +6 -0
  333. aria_code/domain/portfolio_ledger.py +307 -0
  334. aria_code/domain/strategy_vault.py +421 -0
  335. aria_code/evals/__init__.py +37 -0
  336. aria_code/evals/behavior.py +113 -0
  337. aria_code/evals/gap.py +93 -0
  338. aria_code/evals/harness.py +949 -0
  339. aria_code/evals/review_probe.py +132 -0
  340. aria_code/evals/runner.py +425 -0
  341. aria_code/evals/scorecard.py +322 -0
  342. aria_code/evals/summary.py +125 -0
  343. aria_code/external_agent_runner.py +115 -0
  344. aria_code/figma_client.py +4 -0
  345. aria_code/file_analysis_tools.py +4 -0
  346. aria_code/finance_formulas.py +4 -0
  347. aria_code/football_data_client.py +4 -0
  348. aria_code/image_gen_tools.py +4 -0
  349. aria_code/intent_classifier.py +459 -0
  350. aria_code/kling_video_client.py +4 -0
  351. aria_code/licensing.py +151 -0
  352. aria_code/local_finance_tools.py +4 -0
  353. aria_code/local_image_provider.py +4 -0
  354. aria_code/local_llm_provider.py +4 -0
  355. aria_code/macro_tools.py +4 -0
  356. aria_code/markdown_pdf.py +289 -0
  357. aria_code/market_data_client.py +4 -0
  358. aria_code/mcp_client.py +744 -0
  359. aria_code/memory_manager.py +273 -0
  360. aria_code/model_capability.py +512 -0
  361. aria_code/notification_tools.py +4 -0
  362. aria_code/openai_image_client.py +4 -0
  363. aria_code/packages/__init__.py +26 -0
  364. aria_code/packages/adk_bridge/__init__.py +11 -0
  365. aria_code/packages/adk_bridge/code_review_tools.py +49 -0
  366. aria_code/packages/adk_bridge/market_tools.py +125 -0
  367. aria_code/packages/aria_agents/__init__.py +5 -0
  368. aria_code/packages/aria_agents/manifest.py +78 -0
  369. aria_code/packages/aria_core/__init__.py +34 -0
  370. aria_code/packages/aria_core/architecture.py +269 -0
  371. aria_code/packages/aria_core/export.py +147 -0
  372. aria_code/packages/aria_core/manifest.py +65 -0
  373. aria_code/packages/aria_core/paths.py +57 -0
  374. aria_code/packages/aria_core/secure_file.py +68 -0
  375. aria_code/packages/aria_infra/__init__.py +15 -0
  376. aria_code/packages/aria_infra/arthera.py +58 -0
  377. aria_code/packages/aria_infra/doctor.py +246 -0
  378. aria_code/packages/aria_infra/product.py +40 -0
  379. aria_code/packages/aria_mcp/__init__.py +25 -0
  380. aria_code/packages/aria_mcp/bridge.py +232 -0
  381. aria_code/packages/aria_mcp/circuit.py +82 -0
  382. aria_code/packages/aria_mcp/config.py +162 -0
  383. aria_code/packages/aria_mcp/installer.py +95 -0
  384. aria_code/packages/aria_mcp/server.py +1705 -0
  385. aria_code/packages/aria_mcp/tools.py +81 -0
  386. aria_code/packages/aria_sdk/__init__.py +19 -0
  387. aria_code/packages/aria_sdk/client.py +393 -0
  388. aria_code/packages/aria_sdk/providers.py +70 -0
  389. aria_code/packages/aria_sdk/streaming.py +75 -0
  390. aria_code/packages/aria_sdk/types.py +86 -0
  391. aria_code/packages/aria_services/__init__.py +92 -0
  392. aria_code/packages/aria_services/cache.py +60 -0
  393. aria_code/packages/aria_services/context.py +356 -0
  394. aria_code/packages/aria_services/context_checkpoints.py +157 -0
  395. aria_code/packages/aria_services/data.py +11 -0
  396. aria_code/packages/aria_services/provider_health.py +304 -0
  397. aria_code/packages/aria_services/references.py +247 -0
  398. aria_code/packages/aria_services/registry.py +249 -0
  399. aria_code/packages/aria_services/research_protocol.py +137 -0
  400. aria_code/packages/aria_services/research_quality.py +186 -0
  401. aria_code/packages/aria_services/settings.py +160 -0
  402. aria_code/packages/aria_services/usage.py +151 -0
  403. aria_code/packages/aria_skills/__init__.py +46 -0
  404. aria_code/packages/aria_skills/catalog.py +149 -0
  405. aria_code/packages/aria_skills/loader.py +455 -0
  406. aria_code/packages/aria_skills/registry.py +84 -0
  407. aria_code/packages/aria_tools/__init__.py +5 -0
  408. aria_code/packages/aria_tools/financial/__init__.py +5 -0
  409. aria_code/packages/aria_tools/financial/_paths.py +92 -0
  410. aria_code/packages/aria_tools/registry.py +129 -0
  411. aria_code/packages/quant_engine/__init__.py +33 -0
  412. aria_code/packages/quant_engine/_namespace.py +24 -0
  413. aria_code/packages/quant_engine/backtest/__init__.py +10 -0
  414. aria_code/packages/quant_engine/backtest/core.py +53 -0
  415. aria_code/packages/quant_engine/backtest/engine.py +102 -0
  416. aria_code/packages/quant_engine/portfolio/__init__.py +9 -0
  417. aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
  418. aria_code/packages/quant_engine/sports/__init__.py +76 -0
  419. aria_code/packages/quant_engine/sports/calibrator.py +354 -0
  420. aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
  421. aria_code/packages/quant_engine/sports/elo.py +300 -0
  422. aria_code/packages/quant_engine/sports/form.py +188 -0
  423. aria_code/packages/quant_engine/sports/h2h.py +195 -0
  424. aria_code/packages/quant_engine/sports/predictor.py +312 -0
  425. aria_code/packages/quant_engine/sports/tracker.py +665 -0
  426. aria_code/packages/quant_engine/stochastic/__init__.py +31 -0
  427. aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
  428. aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
  429. aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
  430. aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
  431. aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
  432. aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
  433. aria_code/packs/__init__.py +85 -0
  434. aria_code/packs/base.py +168 -0
  435. aria_code/packs/finance/__init__.py +250 -0
  436. aria_code/packs/healthcare/__init__.py +40 -0
  437. aria_code/packs/logistics/__init__.py +171 -0
  438. aria_code/packs/payments/__init__.py +139 -0
  439. aria_code/packs/realty/__init__.py +190 -0
  440. aria_code/packs/registry.py +202 -0
  441. aria_code/packs/rules.py +90 -0
  442. aria_code/plan_utils.py +194 -0
  443. aria_code/plugin_loader.py +328 -0
  444. aria_code/portfolio_ledger.py +4 -0
  445. aria_code/preview_server.py +449 -0
  446. aria_code/privacy/__init__.py +5 -0
  447. aria_code/privacy/feedback.py +123 -0
  448. aria_code/project_review.py +278 -0
  449. aria_code/project_review_api.py +235 -0
  450. aria_code/project_review_server.py +18 -0
  451. aria_code/project_tools.py +4 -0
  452. aria_code/providers/__init__.py +30 -0
  453. aria_code/providers/google_video_provider.py +256 -0
  454. aria_code/providers/llm/__init__.py +19 -0
  455. aria_code/providers/llm/anthropic.py +184 -0
  456. aria_code/providers/llm/arthera_gateway.py +90 -0
  457. aria_code/providers/llm/autoconfig.py +213 -0
  458. aria_code/providers/llm/base.py +139 -0
  459. aria_code/providers/llm/custom.py +158 -0
  460. aria_code/providers/llm/ollama.py +137 -0
  461. aria_code/providers/llm/openai_compat.py +350 -0
  462. aria_code/providers/llm/registry.py +457 -0
  463. aria_code/providers/local_image_provider.py +202 -0
  464. aria_code/providers/local_llm_provider.py +549 -0
  465. aria_code/providers/ollama_models.py +79 -0
  466. aria_code/providers/openai_params.py +32 -0
  467. aria_code/providers/tool_messages.py +100 -0
  468. aria_code/realty_data_tools.py +4 -0
  469. aria_code/report_exporters.py +150 -0
  470. aria_code/report_generator.py +1764 -0
  471. aria_code/review_service.py +497 -0
  472. aria_code/runtime/__init__.py +176 -0
  473. aria_code/runtime/acceptance.py +632 -0
  474. aria_code/runtime/agent_loop.py +1851 -0
  475. aria_code/runtime/agent_profiles.py +75 -0
  476. aria_code/runtime/approval.py +71 -0
  477. aria_code/runtime/baseline.py +219 -0
  478. aria_code/runtime/budget.py +232 -0
  479. aria_code/runtime/checkpoints.py +481 -0
  480. aria_code/runtime/consult.py +65 -0
  481. aria_code/runtime/contract.py +282 -0
  482. aria_code/runtime/delivery.py +432 -0
  483. aria_code/runtime/events.py +113 -0
  484. aria_code/runtime/gateway.py +167 -0
  485. aria_code/runtime/lsp.py +484 -0
  486. aria_code/runtime/native_index.py +153 -0
  487. aria_code/runtime/orchestrator.py +55 -0
  488. aria_code/runtime/processes.py +343 -0
  489. aria_code/runtime/project_graph.py +614 -0
  490. aria_code/runtime/repo_map.py +712 -0
  491. aria_code/runtime/research_bundle.py +105 -0
  492. aria_code/runtime/review.py +269 -0
  493. aria_code/runtime/run_state.py +127 -0
  494. aria_code/runtime/run_store.py +522 -0
  495. aria_code/runtime/scoped_runs.py +113 -0
  496. aria_code/runtime/self_healing.py +422 -0
  497. aria_code/runtime/semantic_diff.py +171 -0
  498. aria_code/runtime/subagent.py +721 -0
  499. aria_code/runtime/symbol_edit.py +117 -0
  500. aria_code/runtime/task_brief.py +46 -0
  501. aria_code/runtime/task_context.py +145 -0
  502. aria_code/runtime/task_ledger.py +108 -0
  503. aria_code/runtime/task_orchestrator.py +90 -0
  504. aria_code/runtime/task_outcome.py +33 -0
  505. aria_code/runtime/task_verification.py +266 -0
  506. aria_code/runtime/task_worktree.py +448 -0
  507. aria_code/runtime/tool_executor.py +329 -0
  508. aria_code/runtime/tool_policy.py +107 -0
  509. aria_code/runtime/transactions.py +216 -0
  510. aria_code/runtime/windows_job.py +115 -0
  511. aria_code/runtime/workflows.py +222 -0
  512. aria_code/runtime/worktrees.py +215 -0
  513. aria_code/runway_video_client.py +4 -0
  514. aria_code/safety/__init__.py +27 -0
  515. aria_code/safety/client_isolation.py +178 -0
  516. aria_code/safety/permissions.py +339 -0
  517. aria_code/safety/risk.py +699 -0
  518. aria_code/safety/sandbox.py +148 -0
  519. aria_code/safety/service.py +102 -0
  520. aria_code/service_endpoints.py +14 -0
  521. aria_code/setup_wizard.py +684 -0
  522. aria_code/spreadsheet_tools.py +4 -0
  523. aria_code/strategy_vault.py +4 -0
  524. aria_code/tools/__init__.py +0 -0
  525. aria_code/tools/artifact_tools.py +252 -0
  526. aria_code/tools/broker_tools.py +92 -0
  527. aria_code/tools/build_quant_engine.py +97 -0
  528. aria_code/tools/code_audit_tools.py +192 -0
  529. aria_code/tools/computer_use_tools.py +509 -0
  530. aria_code/tools/data_analysis_tools.py +831 -0
  531. aria_code/tools/enterprise_finance_tools.py +202 -0
  532. aria_code/tools/extended_tools.py +240 -0
  533. aria_code/tools/file_analysis_tools.py +880 -0
  534. aria_code/tools/image_gen_tools.py +114 -0
  535. aria_code/tools/local_finance_tools.py +3488 -0
  536. aria_code/tools/logistics_carriers.py +11 -0
  537. aria_code/tools/logistics_inventory.py +11 -0
  538. aria_code/tools/logistics_io.py +11 -0
  539. aria_code/tools/logistics_tenancy.py +11 -0
  540. aria_code/tools/logistics_tools.py +11 -0
  541. aria_code/tools/macro_tools.py +412 -0
  542. aria_code/tools/notification_tools.py +249 -0
  543. aria_code/tools/project_tools.py +525 -0
  544. aria_code/tools/realty_data_tools.py +662 -0
  545. aria_code/tools/spreadsheet_tools.py +399 -0
  546. aria_code/tools/stripe_tools.py +115 -0
  547. aria_code/tools/video_tools.py +500 -0
  548. aria_code/training/__init__.py +1 -0
  549. aria_code/training/compare.py +117 -0
  550. aria_code/training/prelude_commands.py +111 -0
  551. aria_code/training/prelude_eval.py +390 -0
  552. aria_code/training/prelude_real.py +183 -0
  553. aria_code/training/prelude_train.py +248 -0
  554. aria_code/training/sft_dataset.py +230 -0
  555. aria_code/training/trajectory_dataset.py +263 -0
  556. aria_code/ui/__init__.py +105 -0
  557. aria_code/ui/banner.py +404 -0
  558. aria_code/ui/completer.py +571 -0
  559. aria_code/ui/console.py +285 -0
  560. aria_code/ui/input_box.py +505 -0
  561. aria_code/ui/mentions.py +206 -0
  562. aria_code/ui/picker.py +248 -0
  563. aria_code/ui/render/__init__.py +11 -0
  564. aria_code/ui/render/actions.py +297 -0
  565. aria_code/ui/render/finance.py +1732 -0
  566. aria_code/ui/render/market.py +253 -0
  567. aria_code/ui/render/output.py +954 -0
  568. aria_code/ui/render/responsive.py +75 -0
  569. aria_code/ui/render/team.py +367 -0
  570. aria_code/ui/robot.py +239 -0
  571. aria_code/ui/startup_dashboard.py +110 -0
  572. aria_code/video_analysis.py +147 -0
  573. aria_code/video_editor.py +518 -0
  574. aria_code/video_workflow/__init__.py +8 -0
  575. aria_code/video_workflow/__main__.py +61 -0
  576. aria_code/video_workflow/engines/__init__.py +18 -0
  577. aria_code/video_workflow/engines/base.py +69 -0
  578. aria_code/video_workflow/engines/custom_model.py +204 -0
  579. aria_code/video_workflow/engines/google_veo.py +94 -0
  580. aria_code/video_workflow/engines/local_engine.py +71 -0
  581. aria_code/video_workflow/engines/registry.py +98 -0
  582. aria_code/video_workflow/google_models.py +278 -0
  583. aria_code/video_workflow/music/__init__.py +5 -0
  584. aria_code/video_workflow/music/foley_service.py +132 -0
  585. aria_code/video_workflow/music/service.py +212 -0
  586. aria_code/video_workflow/pipeline.py +620 -0
  587. aria_code/video_workflow/plan.py +202 -0
  588. aria_code/video_workflow/session.py +297 -0
  589. aria_code/workspace/__init__.py +6 -0
  590. aria_code/workspace/files.py +219 -0
  591. aria_code/workspace/verify.py +167 -0
  592. aria_code/workspace_changes.py +199 -0
  593. aria_code/workspace_service.py +196 -0
  594. aria_code/workspace_tools.py +150 -0
  595. aria_code-0.167.0.dist-info/METADATA +330 -0
  596. aria_code-0.167.0.dist-info/RECORD +601 -0
  597. aria_code-0.167.0.dist-info/WHEEL +5 -0
  598. aria_code-0.167.0.dist-info/entry_points.txt +5 -0
  599. aria_code-0.167.0.dist-info/licenses/LICENSE +201 -0
  600. aria_code-0.167.0.dist-info/licenses/NOTICE +49 -0
  601. aria_code-0.167.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,712 @@
1
+ """Repo map — what is defined where, ranked by what the rest of the repo needs.
2
+
3
+ Why this exists
4
+ ---------------
5
+ Before this module, Aria's only way to find anything in an unfamiliar repository
6
+ was to guess a string and grep for it. That works in a 20-file project and
7
+ falls apart in an enterprise one: the model burns four or five rounds probing
8
+ names that do not exist, and a small local model — the configuration this
9
+ project is actually built around — never recovers, because it has no prior about
10
+ what this codebase calls things.
11
+
12
+ A file tree does not fix that; it says where files are, not what is in them.
13
+ What a model needs on the first round is a *symbol* map: the classes and
14
+ functions this repository defines, which file each lives in, and — critically —
15
+ which of them the rest of the repository actually depends on.
16
+
17
+ Ranking is the whole difference
18
+ -------------------------------
19
+ Every real repo has far more symbols than fit in a context window, so an
20
+ unranked dump is just a differently-shaped grep. This module ranks a file by
21
+ how much the *rest of the codebase* reaches into it: for each symbol a file
22
+ defines, how many other files mention that symbol. A widely-referenced module
23
+ scores high; a leaf script nothing imports scores near zero. That ordering is
24
+ what makes a budgeted map useful — the first 8 KB describe the parts of the
25
+ system a change is most likely to touch.
26
+
27
+ Three corrections keep that number honest, each for an observed way the naive
28
+ count lies:
29
+
30
+ - Names under four characters are ignored. ``id``, ``get``, ``run``, ``fn``
31
+ collide with ordinary vocabulary and would rank whichever file happened to
32
+ define them above everything else.
33
+ - A name defined in more than a handful of files contributes nothing. A
34
+ ``main`` or ``setup`` defined in thirty places tells you nothing about which
35
+ of the thirty matters.
36
+ - One symbol's contribution is capped, so a single popular helper cannot
37
+ outvote a file that is broadly depended on.
38
+
39
+ No new dependencies
40
+ -------------------
41
+ Python is parsed with the stdlib ``ast`` — exact, including nesting. Every
42
+ other language is matched by declaration regex. This is deliberately less
43
+ precise than tree-sitter, and the trade is worth it: an approximate map that
44
+ installs everywhere beats an exact one gated behind a native build, because the
45
+ map's job is to point the model at the right file, and ``read_file`` is what
46
+ establishes the truth once it gets there.
47
+ """
48
+
49
+ from __future__ import annotations
50
+
51
+ import ast
52
+ import os
53
+ import re
54
+ import time
55
+ from dataclasses import dataclass, field
56
+ from pathlib import Path
57
+ from typing import Dict, Iterable, List, Optional, Sequence, Set, Tuple
58
+
59
+ from . import native_index
60
+
61
+ __all__ = [
62
+ "REPO_MAP_SCHEMAS",
63
+ "REPO_MAP_TOOLS",
64
+ "RepoMap",
65
+ "Symbol",
66
+ "tool_find_symbol",
67
+ "tool_repo_map",
68
+ ]
69
+
70
+
71
+ # Directories that are never the user's own code. Skipped by name at any
72
+ # depth: a single unpruned ``.venv`` or ``node_modules`` outweighs the entire
73
+ # repository and would dominate both the scan time and the ranking.
74
+ SKIP_DIRS = frozenset({
75
+ ".git", ".hg", ".svn", "__pycache__", "node_modules", ".venv", "venv",
76
+ "env", ".env", "site-packages", "dist", "build", "target", ".next",
77
+ ".nuxt", ".cache", ".mypy_cache", ".pytest_cache", ".ruff_cache",
78
+ ".tox", ".gradle", ".idea", ".vscode", "vendor", "coverage",
79
+ "htmlcov", ".terraform", "Pods", "DerivedData", ".dart_tool",
80
+ "bower_components", "jspm_packages", ".serverless", "out",
81
+ })
82
+
83
+ # Extension → language label. Membership here is also what decides whether a
84
+ # file is scanned at all.
85
+ LANGUAGES: Dict[str, str] = {
86
+ ".py": "python", ".pyi": "python",
87
+ ".js": "javascript", ".jsx": "javascript", ".mjs": "javascript", ".cjs": "javascript",
88
+ ".ts": "typescript", ".tsx": "typescript",
89
+ ".go": "go",
90
+ ".rs": "rust",
91
+ ".java": "java",
92
+ ".kt": "kotlin", ".kts": "kotlin",
93
+ ".swift": "swift",
94
+ ".rb": "ruby",
95
+ ".php": "php",
96
+ ".cs": "csharp",
97
+ ".c": "c", ".h": "c",
98
+ ".cc": "cpp", ".cpp": "cpp", ".cxx": "cpp", ".hpp": "cpp",
99
+ ".scala": "scala",
100
+ ".sh": "shell", ".bash": "shell",
101
+ ".sql": "sql",
102
+ ".lua": "lua",
103
+ ".dart": "dart",
104
+ ".ex": "elixir", ".exs": "elixir",
105
+ }
106
+
107
+ # Declaration patterns per language. Each yields (kind, name). These match
108
+ # declarations, not uses — anchored at line start (modulo indentation and
109
+ # modifiers) so a call like ``foo(function() {})`` is not read as a definition.
110
+ _DECL_PATTERNS: Dict[str, Sequence[Tuple[str, re.Pattern]]] = {
111
+ "javascript": (
112
+ ("class", re.compile(r"^\s*(?:export\s+)?(?:default\s+)?class\s+([A-Za-z_$][\w$]*)")),
113
+ ("function", re.compile(r"^\s*(?:export\s+)?(?:default\s+)?(?:async\s+)?function\s*\*?\s*([A-Za-z_$][\w$]*)")),
114
+ ("function", re.compile(r"^\s*(?:export\s+)?(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:async\s*)?(?:\([^)]*\)|[A-Za-z_$][\w$]*)\s*=>")),
115
+ ),
116
+ "go": (
117
+ ("func", re.compile(r"^func\s+(?:\([^)]*\)\s*)?([A-Za-z_][\w]*)")),
118
+ ("type", re.compile(r"^type\s+([A-Za-z_][\w]*)")),
119
+ ),
120
+ "rust": (
121
+ ("fn", re.compile(r"^\s*(?:pub(?:\([^)]*\))?\s+)?(?:async\s+)?fn\s+([A-Za-z_][\w]*)")),
122
+ ("struct", re.compile(r"^\s*(?:pub(?:\([^)]*\))?\s+)?struct\s+([A-Za-z_][\w]*)")),
123
+ ("enum", re.compile(r"^\s*(?:pub(?:\([^)]*\))?\s+)?enum\s+([A-Za-z_][\w]*)")),
124
+ ("trait", re.compile(r"^\s*(?:pub(?:\([^)]*\))?\s+)?trait\s+([A-Za-z_][\w]*)")),
125
+ ("impl", re.compile(r"^\s*impl(?:<[^>]*>)?\s+(?:[\w:<>, ]+\s+for\s+)?([A-Za-z_][\w]*)")),
126
+ ),
127
+ "java": (
128
+ ("class", re.compile(r"^\s*(?:public|private|protected|abstract|final|static|\s)*class\s+([A-Za-z_][\w]*)")),
129
+ ("interface", re.compile(r"^\s*(?:public|private|protected|abstract|\s)*interface\s+([A-Za-z_][\w]*)")),
130
+ ("enum", re.compile(r"^\s*(?:public|private|protected|\s)*enum\s+([A-Za-z_][\w]*)")),
131
+ ),
132
+ "ruby": (
133
+ ("class", re.compile(r"^\s*class\s+([A-Za-z_][\w]*)")),
134
+ ("module", re.compile(r"^\s*module\s+([A-Za-z_][\w]*)")),
135
+ ("def", re.compile(r"^\s*def\s+(?:self\.)?([A-Za-z_][\w]*[?!=]?)")),
136
+ ),
137
+ "php": (
138
+ ("class", re.compile(r"^\s*(?:abstract\s+|final\s+)?class\s+([A-Za-z_][\w]*)")),
139
+ ("function", re.compile(r"^\s*(?:public\s+|private\s+|protected\s+|static\s+)*function\s+([A-Za-z_][\w]*)")),
140
+ ),
141
+ "csharp": (
142
+ ("class", re.compile(r"^\s*(?:public|private|protected|internal|abstract|sealed|static|partial|\s)*class\s+([A-Za-z_][\w]*)")),
143
+ ("interface", re.compile(r"^\s*(?:public|private|protected|internal|\s)*interface\s+([A-Za-z_][\w]*)")),
144
+ ("record", re.compile(r"^\s*(?:public|private|protected|internal|\s)*record\s+([A-Za-z_][\w]*)")),
145
+ ),
146
+ "swift": (
147
+ ("class", re.compile(r"^\s*(?:public\s+|private\s+|internal\s+|open\s+|final\s+)*class\s+([A-Za-z_][\w]*)")),
148
+ ("struct", re.compile(r"^\s*(?:public\s+|private\s+|internal\s+)?struct\s+([A-Za-z_][\w]*)")),
149
+ ("protocol", re.compile(r"^\s*(?:public\s+|private\s+|internal\s+)?protocol\s+([A-Za-z_][\w]*)")),
150
+ ("func", re.compile(r"^\s*(?:public\s+|private\s+|internal\s+|static\s+|override\s+|@\w+\s+)*func\s+([A-Za-z_][\w]*)")),
151
+ ),
152
+ "kotlin": (
153
+ ("class", re.compile(r"^\s*(?:public\s+|private\s+|internal\s+|open\s+|data\s+|sealed\s+|abstract\s+)*class\s+([A-Za-z_][\w]*)")),
154
+ ("object", re.compile(r"^\s*(?:public\s+|private\s+|internal\s+)?object\s+([A-Za-z_][\w]*)")),
155
+ ("fun", re.compile(r"^\s*(?:public\s+|private\s+|internal\s+|suspend\s+|override\s+)*fun\s+(?:<[^>]*>\s*)?([A-Za-z_][\w]*)")),
156
+ ),
157
+ "c": (
158
+ ("struct", re.compile(r"^\s*(?:typedef\s+)?struct\s+([A-Za-z_][\w]*)")),
159
+ ("function", re.compile(r"^[A-Za-z_][\w \*]*\s+\*?([A-Za-z_][\w]*)\s*\([^;]*\)\s*\{")),
160
+ ),
161
+ "scala": (
162
+ ("class", re.compile(r"^\s*(?:case\s+)?class\s+([A-Za-z_][\w]*)")),
163
+ ("object", re.compile(r"^\s*(?:case\s+)?object\s+([A-Za-z_][\w]*)")),
164
+ ("trait", re.compile(r"^\s*trait\s+([A-Za-z_][\w]*)")),
165
+ ("def", re.compile(r"^\s*def\s+([A-Za-z_][\w]*)")),
166
+ ),
167
+ "shell": (
168
+ ("function", re.compile(r"^\s*(?:function\s+)?([A-Za-z_][\w]*)\s*\(\s*\)\s*\{")),
169
+ ),
170
+ "sql": (
171
+ ("table", re.compile(r"(?i)^\s*create\s+table\s+(?:if\s+not\s+exists\s+)?[`\"\[]?([A-Za-z_][\w]*)")),
172
+ ("view", re.compile(r"(?i)^\s*create\s+(?:or\s+replace\s+)?view\s+[`\"\[]?([A-Za-z_][\w]*)")),
173
+ ("function", re.compile(r"(?i)^\s*create\s+(?:or\s+replace\s+)?function\s+[`\"\[]?([A-Za-z_][\w]*)")),
174
+ ),
175
+ "lua": (
176
+ ("function", re.compile(r"^\s*(?:local\s+)?function\s+([A-Za-z_][\w.:]*)")),
177
+ ),
178
+ "dart": (
179
+ ("class", re.compile(r"^\s*(?:abstract\s+)?class\s+([A-Za-z_][\w]*)")),
180
+ ),
181
+ "elixir": (
182
+ ("defmodule", re.compile(r"^\s*defmodule\s+([A-Za-z_][\w.]*)")),
183
+ ("def", re.compile(r"^\s*defp?\s+([a-z_][\w]*[?!]?)")),
184
+ ),
185
+ }
186
+ _DECL_PATTERNS["typescript"] = _DECL_PATTERNS["javascript"] + (
187
+ ("interface", re.compile(r"^\s*(?:export\s+)?interface\s+([A-Za-z_$][\w$]*)")),
188
+ ("type", re.compile(r"^\s*(?:export\s+)?type\s+([A-Za-z_$][\w$]*)\s*=")),
189
+ ("enum", re.compile(r"^\s*(?:export\s+)?(?:const\s+)?enum\s+([A-Za-z_$][\w$]*)")),
190
+ )
191
+ _DECL_PATTERNS["cpp"] = _DECL_PATTERNS["c"] + (
192
+ ("class", re.compile(r"^\s*class\s+([A-Za-z_][\w]*)")),
193
+ ("namespace", re.compile(r"^\s*namespace\s+([A-Za-z_][\w]*)")),
194
+ )
195
+
196
+ _IDENTIFIER = re.compile(r"[A-Za-z_][A-Za-z0-9_]*")
197
+
198
+ # Ranking guards — see the module docstring for what each one corrects.
199
+ _MIN_RANKED_NAME = 4
200
+ _MAX_DEFINING_FILES = 5
201
+ _MAX_SYMBOL_CONTRIBUTION = 20
202
+
203
+ # Rendering budget: how many files a map should try to touch, and roughly what
204
+ # one symbol line costs. Together these turn a char budget into a per-file
205
+ # symbol cap, so breadth survives a small budget.
206
+ _TARGET_FILES = 28
207
+ _AVG_SYMBOL_LINE = 46
208
+
209
+
210
+ @dataclass(frozen=True)
211
+ class Symbol:
212
+ """One definition found in one file."""
213
+
214
+ name: str
215
+ kind: str
216
+ line: int
217
+ parent: str = ""
218
+
219
+ @property
220
+ def qualified(self) -> str:
221
+ return f"{self.parent}.{self.name}" if self.parent else self.name
222
+
223
+
224
+ @dataclass
225
+ class FileEntry:
226
+ path: str
227
+ language: str
228
+ symbols: List[Symbol] = field(default_factory=list)
229
+ mtime: float = 0.0
230
+ size: int = 0
231
+ score: float = 0.0
232
+
233
+
234
+ def _python_symbols(source: str) -> List[Symbol]:
235
+ """Exact symbols for Python, including one level of class nesting.
236
+
237
+ Methods are kept with their class as ``parent`` rather than flattened: a
238
+ map that lists ``run`` without saying it is ``AcceptanceGate.run`` sends
239
+ the model to the wrong file about as often as it helps.
240
+ """
241
+ try:
242
+ tree = ast.parse(source)
243
+ except (SyntaxError, ValueError, RecursionError):
244
+ return []
245
+
246
+ out: List[Symbol] = []
247
+
248
+ def _kind(node: ast.AST) -> str:
249
+ if isinstance(node, ast.AsyncFunctionDef):
250
+ return "async def"
251
+ if isinstance(node, ast.FunctionDef):
252
+ return "def"
253
+ return "class"
254
+
255
+ for node in tree.body:
256
+ if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):
257
+ out.append(Symbol(name=node.name, kind=_kind(node), line=node.lineno))
258
+ if isinstance(node, ast.ClassDef):
259
+ for child in node.body:
260
+ if isinstance(child, (ast.FunctionDef, ast.AsyncFunctionDef)):
261
+ out.append(Symbol(
262
+ name=child.name, kind=_kind(child),
263
+ line=child.lineno, parent=node.name,
264
+ ))
265
+ elif isinstance(node, (ast.Assign, ast.AnnAssign)):
266
+ # Module-level constants are part of a module's surface: registries
267
+ # like LOCAL_TOOLS and SKIP_DIRS are exactly what a caller looks up.
268
+ targets = node.targets if isinstance(node, ast.Assign) else [node.target]
269
+ for target in targets:
270
+ if isinstance(target, ast.Name) and target.id.isupper() and len(target.id) > 2:
271
+ out.append(Symbol(name=target.id, kind="const", line=node.lineno))
272
+ return out
273
+
274
+
275
+ def _regex_symbols(source: str, language: str) -> List[Symbol]:
276
+ patterns = _DECL_PATTERNS.get(language)
277
+ if not patterns:
278
+ return []
279
+ out: List[Symbol] = []
280
+ seen: Set[Tuple[str, int]] = set()
281
+ for lineno, line in enumerate(source.splitlines(), 1):
282
+ if len(line) > 400: # minified or generated; never a readable declaration
283
+ continue
284
+ for kind, pattern in patterns:
285
+ match = pattern.match(line)
286
+ if match:
287
+ name = match.group(1)
288
+ key = (name, lineno)
289
+ if key not in seen:
290
+ seen.add(key)
291
+ out.append(Symbol(name=name, kind=kind, line=lineno))
292
+ break
293
+ return out
294
+
295
+
296
+ def extract_symbols(source: str, language: str) -> List[Symbol]:
297
+ """Definitions in *source*. Never raises — an unparseable file has none."""
298
+ try:
299
+ if language == "python":
300
+ return _python_symbols(source)
301
+ return _regex_symbols(source, language)
302
+ except Exception:
303
+ return []
304
+
305
+
306
+ class RepoMap:
307
+ """A scanned, ranked symbol index for one repository root."""
308
+
309
+ def __init__(
310
+ self,
311
+ root: str | Path = ".",
312
+ *,
313
+ max_files: int = 4000,
314
+ max_file_bytes: int = 400_000,
315
+ extra_skip_dirs: Iterable[str] = (),
316
+ ) -> None:
317
+ self.root = Path(root).expanduser().resolve()
318
+ self.max_files = max(1, int(max_files))
319
+ self.max_file_bytes = max(1, int(max_file_bytes))
320
+ self.skip_dirs = SKIP_DIRS | {str(d) for d in extra_skip_dirs}
321
+ self.files: Dict[str, FileEntry] = {}
322
+ self.defs: Dict[str, List[Tuple[str, Symbol]]] = {}
323
+ self.refs: Dict[str, Set[str]] = {}
324
+ self.built_at: float = 0.0
325
+ self.truncated: bool = False
326
+ self.scan_seconds: float = 0.0
327
+
328
+ # ── scanning ──────────────────────────────────────────────────────────
329
+
330
+ def _walk(self) -> List[Path]:
331
+ found: List[Path] = []
332
+ stack = [self.root]
333
+ while stack and len(found) < self.max_files:
334
+ current = stack.pop()
335
+ try:
336
+ entries = list(current.iterdir())
337
+ except (OSError, PermissionError):
338
+ continue
339
+ for entry in entries:
340
+ name = entry.name
341
+ if name.startswith(".") and name not in (".github",):
342
+ if entry.is_dir():
343
+ continue
344
+ try:
345
+ if entry.is_dir():
346
+ if name not in self.skip_dirs:
347
+ stack.append(entry)
348
+ continue
349
+ if entry.suffix.lower() in LANGUAGES:
350
+ found.append(entry)
351
+ if len(found) >= self.max_files:
352
+ self.truncated = True
353
+ break
354
+ except OSError:
355
+ continue
356
+ return found
357
+
358
+ def build(self, *, force: bool = False) -> "RepoMap":
359
+ """Scan the tree. Unchanged files keep their cached symbols.
360
+
361
+ Incremental by mtime and size so a rebuild between turns costs a stat
362
+ per file rather than a reparse — the map is only useful if refreshing
363
+ it is cheaper than the grep round it replaces.
364
+ """
365
+ started = time.time()
366
+ paths = self._walk()
367
+ previous = self.files if not force else {}
368
+ files: Dict[str, FileEntry] = {}
369
+ order: List[str] = [] # walk order, which ranking ties fall back on
370
+ stale: List[Tuple[str, Path, os.stat_result, str]] = []
371
+
372
+ for path in paths:
373
+ try:
374
+ stat = path.stat()
375
+ except OSError:
376
+ continue
377
+ if stat.st_size > self.max_file_bytes:
378
+ continue
379
+ try:
380
+ rel = str(path.relative_to(self.root))
381
+ except ValueError:
382
+ rel = str(path)
383
+
384
+ order.append(rel)
385
+ cached = previous.get(rel)
386
+ if cached is not None and cached.mtime == stat.st_mtime and cached.size == stat.st_size:
387
+ files[rel] = cached
388
+ continue
389
+ stale.append((rel, path, stat, LANGUAGES.get(path.suffix.lower(), "")))
390
+
391
+ # Python definitions come from the native indexer when it can answer
392
+ # (one parallel pass); everything it does not is extracted here.
393
+ native = native_index.python_symbols(
394
+ self.root, [rel for rel, _path, _stat, language in stale if language == "python"])
395
+ parsed = native[0] if native is not None else {}
396
+
397
+ for rel, path, stat, language in stale:
398
+ if rel in parsed:
399
+ symbols = [Symbol(name=n, kind=k, line=line, parent=p) for n, k, line, p in parsed[rel]]
400
+ else:
401
+ try:
402
+ source = path.read_text(encoding="utf-8-sig", errors="replace")
403
+ except (OSError, UnicodeError):
404
+ continue
405
+ symbols = extract_symbols(source, language)
406
+ files[rel] = FileEntry(path=rel, language=language, symbols=symbols,
407
+ mtime=stat.st_mtime, size=stat.st_size)
408
+
409
+ self.files = {rel: files[rel] for rel in order if rel in files}
410
+ self._index()
411
+ self.built_at = time.time()
412
+ self.scan_seconds = self.built_at - started
413
+ return self
414
+
415
+ def _index(self) -> None:
416
+ """Build the definition table, the reference table, and the ranking."""
417
+ defs: Dict[str, List[Tuple[str, Symbol]]] = {}
418
+ for entry in self.files.values():
419
+ for symbol in entry.symbols:
420
+ defs.setdefault(symbol.name, []).append((entry.path, symbol))
421
+ self.defs = defs
422
+
423
+ # References: identifiers a file mentions that some *other* file
424
+ # defines. Re-reading each file here is what a second pass costs; it
425
+ # is bounded by max_file_bytes and only runs on a real rebuild.
426
+ known = set(defs)
427
+ refs: Dict[str, Set[str]] = {}
428
+ for entry in self.files.values():
429
+ path = self.root / entry.path
430
+ try:
431
+ source = path.read_text(encoding="utf-8-sig", errors="replace")
432
+ except (OSError, UnicodeError):
433
+ continue
434
+ own = {symbol.name for symbol in entry.symbols}
435
+ for token in set(_IDENTIFIER.findall(source)):
436
+ if token in known and token not in own:
437
+ refs.setdefault(token, set()).add(entry.path)
438
+ self.refs = refs
439
+
440
+ for entry in self.files.values():
441
+ entry.score = self._score(entry)
442
+
443
+ def _effective_refs(self, name: str) -> int:
444
+ """Reference count, with the two names that always lie zeroed out.
445
+
446
+ A name under four characters (``get``, ``run``, ``id``) collides with
447
+ ordinary vocabulary, and a name defined in more than a handful of files
448
+ (``main``, ``setup``, ``status``) cannot tell you which of them is the
449
+ one that matters. Both would otherwise dominate every ranking.
450
+ """
451
+ if len(name) < _MIN_RANKED_NAME:
452
+ return 0
453
+ if len(self.defs.get(name, ())) > _MAX_DEFINING_FILES:
454
+ return 0
455
+ return len(self.refs.get(name, ()))
456
+
457
+ def _score(self, entry: FileEntry) -> float:
458
+ total = 0.0
459
+ counted: Set[str] = set()
460
+ for symbol in entry.symbols:
461
+ if symbol.name in counted:
462
+ continue
463
+ counted.add(symbol.name)
464
+ total += min(self._effective_refs(symbol.name), _MAX_SYMBOL_CONTRIBUTION)
465
+ return total
466
+
467
+ # ── querying ──────────────────────────────────────────────────────────
468
+
469
+ def ranked(self, *, focus: Sequence[str] = ()) -> List[FileEntry]:
470
+ """Files, most depended-upon first.
471
+
472
+ ``focus`` promotes paths the caller already knows are relevant (the
473
+ files in the current diff, say) above the global ranking, because what
474
+ the rest of the repo needs and what *this task* needs are different
475
+ questions and the caller often knows the second one.
476
+ """
477
+ wanted = tuple(f for f in focus if f)
478
+
479
+ def _is_focused(entry: FileEntry) -> bool:
480
+ return any(token in entry.path for token in wanted)
481
+
482
+ return sorted(
483
+ (e for e in self.files.values() if e.symbols),
484
+ key=lambda e: (0 if _is_focused(e) else 1, -e.score, e.path),
485
+ )
486
+
487
+ def notable(self, entry: FileEntry, limit: int) -> List[Symbol]:
488
+ """The *limit* symbols in this file worth naming, in source order.
489
+
490
+ Two rules, in order. Top-level definitions come before methods: a class
491
+ name is the handle a caller navigates by, and three of its methods say
492
+ less about the file than the class itself does. Within a level, the
493
+ most-referenced name wins.
494
+
495
+ Listing a file's first N definitions instead — the obvious
496
+ implementation — is what makes a map read like noise: the top of a
497
+ large module is usually private constants and local helpers, so the
498
+ budget gets spent on the exact symbols no outside caller will ever
499
+ ask about.
500
+ """
501
+ if len(entry.symbols) <= limit:
502
+ return list(entry.symbols)
503
+ ranked = sorted(
504
+ entry.symbols,
505
+ key=lambda s: (
506
+ bool(s.parent),
507
+ s.name.startswith("_"),
508
+ -self._effective_refs(s.name),
509
+ s.line,
510
+ ),
511
+ )[:limit]
512
+ return sorted(ranked, key=lambda s: s.line)
513
+
514
+ def render(self, *, budget_chars: int = 8000, focus: Sequence[str] = ()) -> str:
515
+ """The map, as compact text, cut to fit *budget_chars*."""
516
+ if not self.files:
517
+ return "(repo map empty — no source files found)"
518
+
519
+ header = (
520
+ f"# Repo map — {self.root.name}\n"
521
+ f"# {len(self.files)} files indexed, "
522
+ f"{sum(len(e.symbols) for e in self.files.values())} symbols, "
523
+ f"ranked by how much the rest of the repo references them.\n"
524
+ f"# Use read_file for the actual code; this map only says where to look.\n"
525
+ )
526
+ if self.truncated:
527
+ header += f"# (truncated at {self.max_files} files)\n"
528
+
529
+ blocks: List[str] = []
530
+ used = len(header)
531
+ shown = 0
532
+ entries = self.ranked(focus=focus)
533
+
534
+ # Spread the budget across files instead of letting the first one eat
535
+ # it. A map that covers thirty files shallowly is navigable; one that
536
+ # covers a single file exhaustively is a worse `read_file`.
537
+ per_file = max(3, min(12, budget_chars // (_TARGET_FILES * _AVG_SYMBOL_LINE)))
538
+
539
+ for entry in entries:
540
+ lines = [f"\n{entry.path}"]
541
+ listed = self.notable(entry, per_file)
542
+ for symbol in listed:
543
+ lines.append(f" {symbol.line:>5} {symbol.kind} {symbol.qualified}")
544
+ if len(entry.symbols) > len(listed):
545
+ lines.append(f" … +{len(entry.symbols) - len(listed)} more")
546
+ block = "\n".join(lines)
547
+ if used + len(block) > budget_chars:
548
+ break
549
+ blocks.append(block)
550
+ used += len(block)
551
+ shown += 1
552
+
553
+ footer = ""
554
+ if shown < len(entries):
555
+ footer = (
556
+ f"\n\n… {len(entries) - shown} lower-ranked files omitted. "
557
+ "Use find_symbol(name) to locate anything not listed here."
558
+ )
559
+ return header + "".join(blocks) + footer
560
+
561
+ def find_symbol(self, name: str, *, limit: int = 20) -> dict:
562
+ """Where *name* is defined and which files mention it.
563
+
564
+ This is the call that replaces a speculative grep: it answers "does
565
+ this repo have such a thing, and where" in one round instead of three.
566
+ """
567
+ query = (name or "").strip()
568
+ if not query:
569
+ return {"symbol": "", "definitions": [], "referenced_by": [], "error": "empty name"}
570
+
571
+ definitions = [
572
+ {"file": path, "line": symbol.line, "kind": symbol.kind, "name": symbol.qualified}
573
+ for path, symbol in self.defs.get(query, ())
574
+ ]
575
+
576
+ if not definitions:
577
+ # An exact miss is the common case for a half-remembered name, so
578
+ # answer with the near misses rather than an empty result.
579
+ lowered = query.lower()
580
+ near = sorted(
581
+ (n for n in self.defs if lowered in n.lower()),
582
+ key=lambda n: (len(n), n),
583
+ )[:limit]
584
+ return {
585
+ "symbol": query,
586
+ "definitions": [],
587
+ "referenced_by": [],
588
+ "did_you_mean": near,
589
+ }
590
+
591
+ return {
592
+ "symbol": query,
593
+ "definitions": definitions[:limit],
594
+ "referenced_by": sorted(self.refs.get(query, ()))[:limit],
595
+ "reference_count": len(self.refs.get(query, ())),
596
+ }
597
+
598
+ def summary(self) -> dict:
599
+ return {
600
+ "root": str(self.root),
601
+ "files": len(self.files),
602
+ "symbols": sum(len(e.symbols) for e in self.files.values()),
603
+ "truncated": self.truncated,
604
+ "scan_seconds": round(self.scan_seconds, 3),
605
+ }
606
+
607
+
608
+ # ── tool surface ──────────────────────────────────────────────────────────
609
+ # One cached map per root: rebuilding is incremental, so a repeated call in the
610
+ # same session costs a stat per file rather than a full reparse.
611
+
612
+ _CACHE: Dict[str, RepoMap] = {}
613
+
614
+
615
+ def get_repo_map(root: str | Path = ".", *, refresh: bool = True) -> RepoMap:
616
+ key = str(Path(root).expanduser().resolve())
617
+ existing = _CACHE.get(key)
618
+ if existing is None:
619
+ existing = RepoMap(key)
620
+ _CACHE[key] = existing
621
+ return existing.build()
622
+ if refresh:
623
+ existing.build()
624
+ return existing
625
+
626
+
627
+ def clear_cache() -> None:
628
+ _CACHE.clear()
629
+
630
+
631
+ def tool_repo_map(params: dict) -> dict:
632
+ """Model-facing: an overview of what this repository defines."""
633
+ try:
634
+ root = params.get("path") or "."
635
+ budget = int(params.get("budget_chars") or 8000)
636
+ focus = params.get("focus") or []
637
+ if isinstance(focus, str):
638
+ focus = [focus]
639
+ repo = get_repo_map(root)
640
+ return {
641
+ "success": True,
642
+ "data": {
643
+ "map": repo.render(budget_chars=max(500, min(budget, 40000)), focus=focus),
644
+ **repo.summary(),
645
+ },
646
+ }
647
+ except Exception as exc:
648
+ return {"success": False, "error": f"repo_map failed: {exc}"}
649
+
650
+
651
+ def tool_find_symbol(params: dict) -> dict:
652
+ """Model-facing: where one named thing is defined, and who uses it."""
653
+ try:
654
+ name = str(params.get("name") or params.get("symbol") or "").strip()
655
+ if not name:
656
+ return {"success": False, "error": "Missing 'name' parameter"}
657
+ repo = get_repo_map(params.get("path") or ".")
658
+ return {"success": True, "data": repo.find_symbol(name)}
659
+ except Exception as exc:
660
+ return {"success": False, "error": f"find_symbol failed: {exc}"}
661
+
662
+
663
+ REPO_MAP_TOOLS = {
664
+ "repo_map": (tool_repo_map,
665
+ "Ranked map of what this repository defines and where"),
666
+ "find_symbol": (tool_find_symbol,
667
+ "Locate a class/function by name and see which files reference it"),
668
+ }
669
+
670
+ REPO_MAP_SCHEMAS = [
671
+ {
672
+ "name": "repo_map",
673
+ "description": (
674
+ "Get a ranked map of the classes, functions and constants this repository "
675
+ "defines, with file paths and line numbers. Files are ordered by how much "
676
+ "the rest of the codebase references them, so the top of the map is where "
677
+ "a change most likely belongs. CALL THIS FIRST when working in an "
678
+ "unfamiliar repository — it replaces several rounds of guessing filenames "
679
+ "and grepping. Then use read_file on the files it points to."
680
+ ),
681
+ "parameters": {
682
+ "type": "object",
683
+ "properties": {
684
+ "path": {"type": "string", "description": "Repository root (default: current directory)"},
685
+ "budget_chars": {"type": "integer", "description": "Max size of the returned map (default 8000)"},
686
+ "focus": {
687
+ "type": "array",
688
+ "items": {"type": "string"},
689
+ "description": "Path fragments to list first, e.g. files you are already editing",
690
+ },
691
+ },
692
+ "required": [],
693
+ },
694
+ },
695
+ {
696
+ "name": "find_symbol",
697
+ "description": (
698
+ "Find where a class, function or constant is defined and which files "
699
+ "reference it. Use this instead of guessing a path or grepping for a name: "
700
+ "it returns exact file:line definitions, and near-miss suggestions when the "
701
+ "name does not exist, so a wrong guess costs one round instead of four."
702
+ ),
703
+ "parameters": {
704
+ "type": "object",
705
+ "properties": {
706
+ "name": {"type": "string", "description": "Symbol name to look up"},
707
+ "path": {"type": "string", "description": "Repository root (default: current directory)"},
708
+ },
709
+ "required": ["name"],
710
+ },
711
+ },
712
+ ]