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,392 @@
1
+ """
2
+ agents/portfolio_agent.py — 组合级分析 Agent
3
+ =============================================
4
+ 跨标的分析:相关性矩阵、波动率、集中度风险、再平衡建议。
5
+ 数据源:yfinance 1年日线(免费,无需 key)
6
+ 触发:/portfolio analyze [symbols…]
7
+ /portfolio rebalance [symbols…]
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import logging
13
+ from datetime import datetime
14
+ from typing import Any, Dict, List, Optional
15
+
16
+ from .base import BaseAgent, AgentResult
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ class PortfolioAgent(BaseAgent):
22
+
23
+ name = "portfolio"
24
+ description = "组合级分析 — 相关性、分散度、整体风险、再平衡建议"
25
+
26
+ _SYSTEM = (
27
+ "You are a portfolio risk analyst. Given price history and statistics for "
28
+ "a portfolio of stocks, your job is to:\n"
29
+ "1. Evaluate overall portfolio risk (Low / Medium / High)\n"
30
+ "2. Identify diversification gaps — highly correlated pairs, sector crowding\n"
31
+ "3. Flag concentration risk if any single position dominates\n"
32
+ "4. Give 2-3 actionable rebalancing suggestions (be specific: which stocks to "
33
+ "trim / add / replace and why)\n"
34
+ "5. End with a one-line verdict: HEALTHY / NEEDS_ATTENTION / HIGH_RISK\n"
35
+ "Be concrete. Avoid boilerplate."
36
+ )
37
+
38
+ # ── BaseAgent compatibility ───────────────────────────────────────────────
39
+
40
+ async def fetch_data(self, symbol: str) -> Dict[str, Any]:
41
+ symbols = [s.strip().upper() for s in symbol.split(",") if s.strip()]
42
+ return await self.fetch_portfolio_data(symbols)
43
+
44
+ async def analyze(self, symbol: str, data: Dict[str, Any]) -> AgentResult:
45
+ symbols = data.get("symbols") or [s.strip().upper() for s in symbol.split(",") if s.strip()]
46
+ return await self.analyze_portfolio(symbols, data)
47
+
48
+ # ── Multi-symbol interface ────────────────────────────────────────────────
49
+
50
+ async def run_portfolio(
51
+ self, symbols: List[str], weights: Optional[Dict[str, float]] = None
52
+ ) -> AgentResult:
53
+ """Primary entry point for multi-symbol analysis.
54
+
55
+ weights: optional {symbol: dollar_cost_basis} from the user's real
56
+ holdings (portfolio_ledger.PortfolioLedger.get_positions()). Without
57
+ it, every position is silently treated as equal-weight — which used
58
+ to be the ONLY mode this agent supported, so a user who actually
59
+ holds 80% NVDA and 20% everything else got a risk verdict computed
60
+ on a fictional 1/n-weighted portfolio instead of their real exposure.
61
+ """
62
+ data = await self.fetch_portfolio_data(symbols, weights=weights)
63
+ return await self.analyze_portfolio(symbols, data)
64
+
65
+ async def fetch_portfolio_data(
66
+ self, symbols: List[str], weights: Optional[Dict[str, float]] = None
67
+ ) -> Dict[str, Any]:
68
+ data: Dict[str, Any] = {"symbols": symbols}
69
+ if len(symbols) < 2:
70
+ return data
71
+
72
+ price_series: Dict[str, Any] = {}
73
+ latest_prices: Dict[str, float] = {}
74
+ sector_map: Dict[str, str] = {}
75
+
76
+ for sym in symbols:
77
+ try:
78
+ import yfinance as yf
79
+ ticker = yf.Ticker(sym)
80
+ hist = ticker.history(period="1y")
81
+ if not hist.empty and len(hist) > 20:
82
+ price_series[sym] = hist["Close"]
83
+ latest_prices[sym] = float(hist["Close"].iloc[-1])
84
+ # Try to get sector info
85
+ try:
86
+ info = ticker.info or {}
87
+ sector = info.get("sector") or info.get("industry", "")
88
+ if sector:
89
+ sector_map[sym] = sector
90
+ except Exception:
91
+ pass
92
+ except Exception as e:
93
+ logger.debug("[portfolio] yfinance %s: %s", sym, e)
94
+
95
+ if len(price_series) < 2:
96
+ data["error"] = "insufficient_data"
97
+ return data
98
+
99
+ try:
100
+ import pandas as pd
101
+ import numpy as np
102
+
103
+ df = pd.DataFrame(price_series).dropna()
104
+ returns = df.pct_change().dropna()
105
+
106
+ corr = returns.corr()
107
+ ann_returns = (returns.mean() * 252).round(4)
108
+ ann_vols = (returns.std() * np.sqrt(252)).round(4)
109
+ cov_matrix = returns.cov() * 252
110
+ valid_syms = list(df.columns)
111
+ n = len(valid_syms)
112
+ if weights and any(weights.get(s, 0) > 0 for s in valid_syms):
113
+ raw = np.array([max(weights.get(s, 0.0), 0.0) for s in valid_syms])
114
+ w_vec = raw / raw.sum() if raw.sum() > 0 else np.ones(n) / n
115
+ weight_source = "ledger"
116
+ else:
117
+ w_vec = np.ones(n) / n
118
+ weight_source = "equal"
119
+ port_vol = float(np.sqrt(w_vec @ cov_matrix.values @ w_vec))
120
+ position_weights = {s: round(float(w_vec[i]), 4) for i, s in enumerate(valid_syms)}
121
+
122
+ # High correlation pairs (|r| > 0.70)
123
+ high_corr: List[Dict] = []
124
+ for i in range(len(valid_syms)):
125
+ for j in range(i + 1, len(valid_syms)):
126
+ c = float(corr.iloc[i, j])
127
+ if abs(c) > 0.70:
128
+ high_corr.append({
129
+ "sym1": valid_syms[i],
130
+ "sym2": valid_syms[j],
131
+ "corr": round(c, 3),
132
+ })
133
+
134
+ # Diversification ratio: weighted avg individual vol / portfolio vol.
135
+ # Was np.mean() (unweighted) despite the comment already claiming
136
+ # "weighted" — with real ledger weights now available, actually weight it.
137
+ avg_vol = float(sum(w_vec[i] * float(ann_vols.get(s, 0)) for i, s in enumerate(valid_syms)))
138
+ div_ratio = round(avg_vol / port_vol, 2) if port_vol > 0 else 1.0
139
+
140
+ # 52-week return per symbol
141
+ returns_1y: Dict[str, float] = {}
142
+ for sym in valid_syms:
143
+ first = float(df[sym].iloc[0])
144
+ last = float(df[sym].iloc[-1])
145
+ if first > 0:
146
+ returns_1y[sym] = round((last - first) / first, 4)
147
+
148
+ # Best/worst performer
149
+ sorted_ret = sorted(returns_1y.items(), key=lambda x: x[1], reverse=True)
150
+
151
+ data.update({
152
+ "valid_symbols": valid_syms,
153
+ "latest_prices": latest_prices,
154
+ "ann_returns": {s: float(v) for s, v in ann_returns.items()},
155
+ "ann_vols": {s: float(v) for s, v in ann_vols.items()},
156
+ "port_vol_ann": round(port_vol, 4),
157
+ "div_ratio": div_ratio,
158
+ "corr_matrix": corr.round(3).to_dict(),
159
+ "high_corr": high_corr,
160
+ "returns_1y": returns_1y,
161
+ "best_performer": sorted_ret[0] if sorted_ret else None,
162
+ "worst_performer": sorted_ret[-1] if sorted_ret else None,
163
+ "sector_map": sector_map,
164
+ "position_weights": position_weights,
165
+ "weight_source": weight_source,
166
+ })
167
+
168
+ except ImportError:
169
+ data["error"] = "pandas/numpy not available"
170
+ except Exception as e:
171
+ logger.warning("[portfolio] stats calculation: %s", e)
172
+ data["error"] = str(e)
173
+
174
+ return data
175
+
176
+ async def analyze_portfolio(
177
+ self, symbols: List[str], data: Dict[str, Any]
178
+ ) -> AgentResult:
179
+ zh = self.lang != "en"
180
+ if len(symbols) < 2:
181
+ return AgentResult(
182
+ agent=self.name, symbol=",".join(symbols),
183
+ analysis=("组合分析需要至少 2 个标的。" if zh
184
+ else "A portfolio analysis needs at least 2 symbols."),
185
+ confidence=0.0, signal="HOLD",
186
+ key_points=["标的数量不足" if zh else "Not enough symbols"],
187
+ )
188
+
189
+ if data.get("error") == "insufficient_data":
190
+ return AgentResult(
191
+ agent=self.name, symbol=",".join(symbols),
192
+ analysis=("无法获取足够的历史价格数据进行组合分析。" if zh
193
+ else "Not enough price history could be fetched to analyse the portfolio."),
194
+ confidence=0.3, signal="HOLD",
195
+ key_points=["历史数据不足(需要 >20 个交易日)" if zh
196
+ else "Not enough history (needs more than 20 trading days)"],
197
+ )
198
+
199
+ valid_syms = data.get("valid_symbols", symbols)
200
+ port_block = _format_portfolio_stats(data)
201
+ weight_desc = ("your actual position sizes" if data.get("weight_source") == "ledger"
202
+ else "equal weight — no real position sizes available")
203
+
204
+ prompt = (
205
+ f"Portfolio: {', '.join(valid_syms)} ({len(valid_syms)} positions, weighted by {weight_desc})\n\n"
206
+ f"{port_block}\n\n"
207
+ "Analyze this portfolio:\n"
208
+ "1. Overall risk level (Low / Medium / High)\n"
209
+ "2. Diversification quality — any dangerous correlations or sector crowding?\n"
210
+ "3. Top 2-3 concerns (be specific about which symbols)\n"
211
+ "4. Concrete rebalancing suggestions\n"
212
+ "5. End with: HEALTHY / NEEDS_ATTENTION / HIGH_RISK"
213
+ )
214
+
215
+ analysis = await self._call_llm(self._SYSTEM, prompt, max_tokens=650)
216
+ if not analysis:
217
+ analysis = _template_analysis(valid_syms, data, self.lang)
218
+
219
+ verdict = _extract_verdict(analysis)
220
+ signal = _verdict_to_signal(verdict)
221
+ confidence = _estimate_confidence(data)
222
+ key_points = _build_key_points(data, verdict, self.lang)
223
+
224
+ return AgentResult(
225
+ agent=self.name,
226
+ symbol=",".join(valid_syms),
227
+ analysis=analysis,
228
+ confidence=confidence,
229
+ signal=signal,
230
+ key_points=key_points,
231
+ data_used={
232
+ # The verdict itself: the signal maps NEEDS_ATTENTION to SELL,
233
+ # and a banner built from the signal said HIGH_RISK.
234
+ "verdict": verdict,
235
+ "n": len(valid_syms),
236
+ "port_vol_ann": data.get("port_vol_ann"),
237
+ "div_ratio": data.get("div_ratio"),
238
+ "high_corr_count": len(data.get("high_corr", [])),
239
+ },
240
+ )
241
+
242
+
243
+ # ── Helpers ───────────────────────────────────────────────────────────────────
244
+
245
+ def _format_portfolio_stats(d: Dict) -> str:
246
+ lines = []
247
+
248
+ # Returns & volatility table
249
+ vols = d.get("ann_vols", {})
250
+ rets = d.get("ann_returns", {})
251
+ rets_1y = d.get("returns_1y", {})
252
+ pweights = d.get("position_weights", {})
253
+ if vols:
254
+ lines.append("Symbol │ Weight │ Ann.Vol │ Ann.Ret │ 1Y Return")
255
+ lines.append("─" * 52)
256
+ for sym in d.get("valid_symbols", list(vols)):
257
+ v = vols.get(sym, 0)
258
+ r = rets.get(sym, 0)
259
+ y = rets_1y.get(sym, 0)
260
+ w = pweights.get(sym, 0)
261
+ lines.append(
262
+ f"{sym:<6} │ {w*100:>5.1f}% │ {v*100:>6.1f}% │ {r*100:>6.1f}% │ {y*100:>+7.1f}%"
263
+ )
264
+
265
+ port_vol = d.get("port_vol_ann", 0)
266
+ div_r = d.get("div_ratio", 1)
267
+ if port_vol:
268
+ lines.append(f"\nPortfolio Ann.Vol: {port_vol*100:.1f}%")
269
+ lines.append(f"Diversification Ratio: {div_r:.2f}x "
270
+ f"({'good' if div_r >= 1.3 else 'poor'})")
271
+
272
+ high_corr = d.get("high_corr", [])
273
+ if high_corr:
274
+ lines.append("\nHigh-Correlation Pairs (|r|>0.70):")
275
+ for p in high_corr[:5]:
276
+ lines.append(f" {p['sym1']} ↔ {p['sym2']}: {p['corr']:+.2f}")
277
+
278
+ sectors = d.get("sector_map", {})
279
+ if sectors:
280
+ from collections import Counter
281
+ sector_counts = Counter(sectors.values())
282
+ dominant = [(s, c) for s, c in sector_counts.items() if c >= 2]
283
+ if dominant:
284
+ lines.append("\nSector Concentration:")
285
+ for sec, cnt in dominant:
286
+ lines.append(f" {sec}: {cnt} positions")
287
+
288
+ best = d.get("best_performer")
289
+ worst = d.get("worst_performer")
290
+ if best and worst:
291
+ lines.append(f"\nBest 1Y: {best[0]} ({best[1]*100:+.1f}%)")
292
+ lines.append(f"Worst 1Y: {worst[0]} ({worst[1]*100:+.1f}%)")
293
+
294
+ return "\n".join(lines)
295
+
296
+
297
+ def _extract_verdict(analysis: str) -> str:
298
+ text = analysis.upper()
299
+ if "HIGH_RISK" in text or "HIGH RISK" in text:
300
+ return "HIGH_RISK"
301
+ if "NEEDS_ATTENTION" in text or "NEEDS ATTENTION" in text:
302
+ return "NEEDS_ATTENTION"
303
+ if "HEALTHY" in text:
304
+ return "HEALTHY"
305
+ return "NEEDS_ATTENTION"
306
+
307
+
308
+ def _verdict_to_signal(verdict: str) -> str:
309
+ return {"HEALTHY": "HOLD", "NEEDS_ATTENTION": "SELL", "HIGH_RISK": "SELL"}.get(verdict, "HOLD")
310
+
311
+
312
+ def _estimate_confidence(d: Dict) -> float:
313
+ base = 0.60
314
+ n = len(d.get("valid_symbols", []))
315
+ if n >= 5:
316
+ base += 0.05
317
+ if d.get("div_ratio", 1) < 1.1:
318
+ base += 0.05
319
+ return min(round(base, 2), 0.75)
320
+
321
+
322
+ def _build_key_points(d: Dict, verdict: str, lang: str = "zh") -> List[str]:
323
+ zh = lang != "en"
324
+ pts = []
325
+ n = len(d.get("valid_symbols", []))
326
+ if d.get("weight_source") == "ledger":
327
+ pts.append(f"{n} 个标的,按真实持仓成本加权" if zh
328
+ else f"{n} symbols, weighted by the cost of your real positions")
329
+ else:
330
+ pts.append(f"{n} 个标的,等权配置(无真实持仓数据,非实际风险暴露)" if zh
331
+ else f"{n} symbols, equal weight (no real positions recorded, so not your actual exposure)")
332
+
333
+ port_vol = d.get("port_vol_ann", 0)
334
+ if port_vol:
335
+ if zh:
336
+ risk_lv = "高风险" if port_vol > 0.30 else ("中等" if port_vol > 0.18 else "低风险")
337
+ pts.append(f"组合年化波动 {port_vol*100:.1f}%({risk_lv})")
338
+ else:
339
+ risk_lv = "high" if port_vol > 0.30 else ("medium" if port_vol > 0.18 else "low")
340
+ pts.append(f"Annualised portfolio volatility {port_vol*100:.1f}% ({risk_lv})")
341
+
342
+ div_r = d.get("div_ratio", 1)
343
+ if div_r < 1.1:
344
+ pts.append(f"分散度不足(ratio {div_r:.2f}x,标的相关性高)" if zh
345
+ else f"Poorly diversified (ratio {div_r:.2f}x, the symbols move together)")
346
+ else:
347
+ pts.append(f"分散度合理(ratio {div_r:.2f}x)" if zh
348
+ else f"Reasonably diversified (ratio {div_r:.2f}x)")
349
+
350
+ high_corr = d.get("high_corr", [])
351
+ if high_corr:
352
+ top = high_corr[0]
353
+ pts.append(f"{'最高相关对' if zh else 'Most correlated pair'}: "
354
+ f"{top['sym1']}↔{top['sym2']} ({top['corr']:+.2f})")
355
+
356
+ pts.append(f"{'整体评级' if zh else 'Overall'}: {verdict}")
357
+ return pts[:6]
358
+
359
+
360
+ def _template_analysis(symbols: List[str], d: Dict, lang: str = "zh") -> str:
361
+ high_corr = d.get("high_corr", [])
362
+ port_vol = d.get("port_vol_ann", 0)
363
+ div_r = d.get("div_ratio", 1)
364
+
365
+ verdict = "NEEDS_ATTENTION"
366
+ if not high_corr and port_vol < 0.20 and div_r >= 1.2:
367
+ verdict = "HEALTHY"
368
+ elif len(high_corr) >= 3 or port_vol > 0.30:
369
+ verdict = "HIGH_RISK"
370
+
371
+ if lang == "en":
372
+ lines = [f"{','.join(symbols)} portfolio report (template)"]
373
+ lines.append(f"Annualised volatility: {port_vol*100:.1f}%")
374
+ lines.append(f"Diversification ratio: {div_r:.2f}x")
375
+ if high_corr:
376
+ lines.append(f"{len(high_corr)} highly correlated pairs, the highest "
377
+ f"{high_corr[0]['sym1']}↔{high_corr[0]['sym2']} {high_corr[0]['corr']:+.2f}")
378
+ else:
379
+ lines.append("No highly correlated pairs.")
380
+ lines.append(f"\n{verdict}")
381
+ return "\n".join(lines)
382
+
383
+ lines = [f"{','.join(symbols)} 组合分析报告(模板)"]
384
+ lines.append(f"年化波动率: {port_vol*100:.1f}%")
385
+ lines.append(f"分散度系数: {div_r:.2f}x")
386
+ if high_corr:
387
+ lines.append(f"高相关对 {len(high_corr)} 组,最高: "
388
+ f"{high_corr[0]['sym1']}↔{high_corr[0]['sym2']} {high_corr[0]['corr']:+.2f}")
389
+ else:
390
+ lines.append("无显著高相关对,分散良好。")
391
+ lines.append(f"\n{verdict}")
392
+ return "\n".join(lines)
@@ -0,0 +1,62 @@
1
+ """
2
+ agents/realty — 经营权共创平台 AI Agent 模块
3
+ =============================================
4
+ 9 个领域专属 Agent,继承 BaseAgent,用于:
5
+ - 资产诊断与处置建议
6
+ - 业态匹配与经营方推荐
7
+ - 合同条款结构化生成
8
+ - 分账规则配置建议
9
+ - 流水核验与异常检测
10
+ - 能耗异常分析
11
+ - 合同履约风控
12
+ - 运营优化建议
13
+ - 退出清算方案生成
14
+
15
+ 用法:
16
+ from agents.realty import AssetDiagnosisAgent, RevenueShareAgent
17
+ from agents.realty import REALTY_TEAM # 默认 team 名称列表
18
+ """
19
+
20
+ from .asset_diagnosis import AssetDiagnosisAgent
21
+ from .business_match import BusinessMatchAgent
22
+ from .contract_rules import ContractRulesAgent
23
+ from .revenue_share import RevenueShareAgent
24
+ from .cashflow_verify import CashFlowVerifyAgent
25
+ from .energy_anomaly import EnergyAnomalyAgent
26
+ from .fulfillment_risk import FulfillmentRiskAgent
27
+ from .ops_optimize import OpsOptimizeAgent
28
+ from .exit_settlement import ExitSettlementAgent
29
+
30
+ # 默认完整 team
31
+ REALTY_TEAM = [
32
+ "asset_diagnosis",
33
+ "business_match",
34
+ "contract_rules",
35
+ "revenue_share",
36
+ "cashflow_verify",
37
+ "energy_anomaly",
38
+ "fulfillment_risk",
39
+ "ops_optimize",
40
+ "exit_settlement",
41
+ ]
42
+
43
+ # 风控专项 team(快速预警)
44
+ RISK_TEAM = [
45
+ "cashflow_verify",
46
+ "energy_anomaly",
47
+ "fulfillment_risk",
48
+ ]
49
+
50
+ __all__ = [
51
+ "AssetDiagnosisAgent",
52
+ "BusinessMatchAgent",
53
+ "ContractRulesAgent",
54
+ "RevenueShareAgent",
55
+ "CashFlowVerifyAgent",
56
+ "EnergyAnomalyAgent",
57
+ "FulfillmentRiskAgent",
58
+ "OpsOptimizeAgent",
59
+ "ExitSettlementAgent",
60
+ "REALTY_TEAM",
61
+ "RISK_TEAM",
62
+ ]
@@ -0,0 +1,152 @@
1
+ """
2
+ agents/realty/asset_diagnosis.py — 资产诊断 Agent
3
+ ==================================================
4
+ 判断资产适合出租、出售还是经营权共创。
5
+
6
+ 输入数据(data dict keys):
7
+ asset_info — 资产基础信息 dict(面积、位置、产权状态、空置时间等)
8
+ market_context — 周边业态、租金行情(可选)
9
+ renovation_cost — 估算改造成本(可选)
10
+
11
+ 输出:
12
+ analysis — 详细分析文本
13
+ signal — GOOD=推荐共创 / WATCH=需观察 / CONCERN=建议出租或出售
14
+ (地产健康度尺度,见 agents/signal_scheme.py::REALTY_SCHEME,
15
+ 不是股票 BUY/SELL 那套交易动作词汇)
16
+ key_points — 3-5 条关键结论
17
+ """
18
+ from __future__ import annotations
19
+
20
+ from typing import Any, Dict
21
+ from ..base import BaseAgent, AgentResult
22
+
23
+
24
+ class AssetDiagnosisAgent(BaseAgent):
25
+ name = "asset_diagnosis"
26
+ description = "资产诊断:判断处置方式(出租/出售/共创)并给出保底与分润结构建议"
27
+
28
+ _SYSTEM = (
29
+ "你是一名专业的不动产资产运营顾问,擅长评估商业空间的经营潜力。\n"
30
+ "你的任务是根据资产条件、空置状况、市场行情,判断该资产最适合哪种处置方式:\n"
31
+ " A) 传统出租(固定租金)\n"
32
+ " B) 经营权共创(保底+流水分润)\n"
33
+ " C) 出售(一次性变现)\n\n"
34
+ "输出格式要求:\n"
35
+ "1. 推荐方式及理由(2-3句话)\n"
36
+ "2. 如推荐共创,给出:保底收益建议(元/月)、分润比例建议(%)、适合业态Top3\n"
37
+ "3. 主要风险提示(1-2条)\n"
38
+ "4. 综合评分:[适合共创] / [建议观察] / [不建议共创]"
39
+ )
40
+
41
+ async def analyze(self, symbol: str, data: Dict[str, Any]) -> AgentResult:
42
+ asset = data.get("asset_info", {})
43
+ market = data.get("market_context", {})
44
+ reno = data.get("renovation_cost", 0)
45
+
46
+ # 构建资产摘要
47
+ area = asset.get("area", 0)
48
+ location = asset.get("location", "未知位置")
49
+ vacancy_days= asset.get("vacancy_days", 0)
50
+ expected_rent = asset.get("expected_rent", 0)
51
+ floor_height = asset.get("floor_height", 0)
52
+ business_types = asset.get("allowed_business", [])
53
+ prohibited = asset.get("prohibited_business", [])
54
+ property_state= asset.get("property_state", "正常")
55
+
56
+ user_prompt = (
57
+ f"资产信息:\n"
58
+ f" 位置: {location}\n"
59
+ f" 面积: {area} m² 层高: {floor_height}m\n"
60
+ f" 产权状态: {property_state} 空置天数: {vacancy_days}天\n"
61
+ f" 评估租金: {expected_rent}元/月 改造成本估算: {reno}元\n"
62
+ f" 适合业态: {', '.join(business_types) or '未指定'}\n"
63
+ f" 禁止业态: {', '.join(prohibited) or '无'}\n"
64
+ f" 市场背景: {market.get('summary', '暂无周边数据')}\n\n"
65
+ "请根据以上信息完成资产诊断。"
66
+ )
67
+
68
+ analysis = await self._call_llm(self._SYSTEM, user_prompt, max_tokens=600)
69
+ if not analysis:
70
+ analysis = _template_diagnosis(asset, reno)
71
+
72
+ signal = _score_to_signal(asset, reno)
73
+ confidence = _calc_confidence(asset)
74
+ key_points = _extract_key_points(asset, reno, market)
75
+
76
+ return AgentResult(
77
+ agent = self.name,
78
+ symbol = symbol,
79
+ analysis = analysis,
80
+ confidence = confidence,
81
+ signal = signal,
82
+ key_points = key_points,
83
+ data_used = {"asset_info": asset, "renovation_cost": reno},
84
+ )
85
+
86
+
87
+ # ── 内部辅助函数 ──────────────────────────────────────────────────────────────
88
+
89
+ def _score_to_signal(asset: Dict, reno: float) -> str:
90
+ """根据资产条件估算共创适合度"""
91
+ area = asset.get("area", 0)
92
+ vacancy_days = asset.get("vacancy_days", 0)
93
+ rent = asset.get("expected_rent", 0)
94
+ allowed = asset.get("allowed_business", [])
95
+ state = asset.get("property_state", "正常")
96
+
97
+ score = 0
98
+ if area >= 50: score += 1
99
+ if area >= 200: score += 1
100
+ if vacancy_days >= 90: score += 1 # 空置越久越需要共创
101
+ if rent > 0: score += 1
102
+ if len(allowed) >= 2: score += 1
103
+ if state != "正常": score -= 2
104
+ if reno > rent * 24: score -= 1 # 改造成本超过2年租金则不划算
105
+
106
+ if score >= 4: return "GOOD" # 非常适合共创
107
+ if score >= 2: return "WATCH" # 需进一步评估
108
+ return "CONCERN" # 建议传统出租或出售
109
+
110
+
111
+ def _calc_confidence(asset: Dict) -> float:
112
+ """数据越完整,置信度越高"""
113
+ fields = ["area", "location", "expected_rent", "allowed_business", "property_state"]
114
+ filled = sum(1 for f in fields if asset.get(f))
115
+ return round(0.5 + 0.1 * filled, 2)
116
+
117
+
118
+ def _extract_key_points(asset: Dict, reno: float, market: Dict) -> list:
119
+ points = []
120
+ area = asset.get("area", 0)
121
+ vacancy = asset.get("vacancy_days", 0)
122
+ rent = asset.get("expected_rent", 0)
123
+ allowed = asset.get("allowed_business", [])
124
+
125
+ if area >= 200:
126
+ points.append(f"面积 {area}m² 具备多业态组合潜力")
127
+ if vacancy >= 90:
128
+ points.append(f"已空置 {vacancy} 天,引入经营方具有紧迫性")
129
+ if rent > 0:
130
+ points.append(f"评估租金 {rent:,.0f} 元/月,保底基准参考值")
131
+ if allowed:
132
+ points.append(f"适合业态:{', '.join(allowed[:3])}")
133
+ if reno > 0:
134
+ points.append(f"改造成本约 {reno:,.0f} 元,需纳入分润谈判")
135
+ return points[:5]
136
+
137
+
138
+ def _template_diagnosis(asset: Dict, reno: float) -> str:
139
+ area = asset.get("area", 0)
140
+ vacancy = asset.get("vacancy_days", 0)
141
+ rent = asset.get("expected_rent", 0)
142
+ allowed = asset.get("allowed_business", [])
143
+
144
+ suitability = "建议经营权共创" if area >= 100 and vacancy >= 30 else "建议先评估市场需求"
145
+ return (
146
+ f"资产诊断(模板):\n"
147
+ f" 面积: {area}m² 空置: {vacancy}天 评估租金: {rent:,.0f}元/月\n"
148
+ f" 适合业态: {', '.join(allowed[:3]) or '待评估'}\n"
149
+ f" 改造成本估算: {reno:,.0f}元\n"
150
+ f" 诊断结论: {suitability}\n"
151
+ f" 建议保底: {int(rent * 0.7):,}元/月 建议分润比例: 8-12%"
152
+ )