aria-code 4.1.4__tar.gz → 4.2.0__tar.gz

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 (426) hide show
  1. {aria_code-4.1.4 → aria_code-4.2.0}/PKG-INFO +83 -8
  2. {aria_code-4.1.4 → aria_code-4.2.0}/README.md +75 -6
  3. {aria_code-4.1.4 → aria_code-4.2.0}/agents/__init__.py +2 -0
  4. {aria_code-4.1.4 → aria_code-4.2.0}/agents/base.py +6 -0
  5. {aria_code-4.1.4 → aria_code-4.2.0}/agents/portfolio_agent.py +43 -13
  6. {aria_code-4.1.4 → aria_code-4.2.0}/agents/realty/asset_diagnosis.py +6 -4
  7. {aria_code-4.1.4 → aria_code-4.2.0}/agents/realty/business_match.py +5 -4
  8. {aria_code-4.1.4 → aria_code-4.2.0}/agents/realty/cashflow_verify.py +6 -5
  9. {aria_code-4.1.4 → aria_code-4.2.0}/agents/realty/contract_rules.py +5 -4
  10. {aria_code-4.1.4 → aria_code-4.2.0}/agents/realty/energy_anomaly.py +6 -5
  11. {aria_code-4.1.4 → aria_code-4.2.0}/agents/realty/exit_settlement.py +6 -5
  12. {aria_code-4.1.4 → aria_code-4.2.0}/agents/realty/fulfillment_risk.py +8 -7
  13. {aria_code-4.1.4 → aria_code-4.2.0}/agents/realty/ops_optimize.py +7 -6
  14. {aria_code-4.1.4 → aria_code-4.2.0}/agents/realty/revenue_share.py +7 -6
  15. aria_code-4.2.0/agents/signal_scheme.py +97 -0
  16. {aria_code-4.1.4 → aria_code-4.2.0}/agents/sports/football_agent.py +33 -5
  17. {aria_code-4.1.4 → aria_code-4.2.0}/agents/team.py +146 -52
  18. aria_code-4.2.0/apps/channels/__init__.py +17 -0
  19. aria_code-4.2.0/apps/channels/intake.py +92 -0
  20. aria_code-4.2.0/apps/channels/registry.py +95 -0
  21. aria_code-4.2.0/apps/channels/tradingview.py +94 -0
  22. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/bootstrap.py +4 -0
  23. aria_code-4.2.0/apps/cli/commands/auth_cmds.py +135 -0
  24. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/backtest_cmds.py +565 -0
  25. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/broker_cmds.py +19 -2
  26. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/catalog.py +1 -1
  27. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/diagnostic_ops_cmds.py +63 -10
  28. aria_code-4.2.0/apps/cli/commands/file_cmds.py +267 -0
  29. aria_code-4.2.0/apps/cli/commands/fx_commodity_cmds.py +87 -0
  30. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/market.py +29 -4
  31. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/model_cmds.py +256 -23
  32. aria_code-4.2.0/apps/cli/commands/pdf_export_cmds.py +97 -0
  33. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/portfolio_cmds.py +202 -19
  34. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/report.py +60 -0
  35. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/session_cmds.py +28 -0
  36. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/session_ux_cmds.py +40 -0
  37. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/team.py +70 -2
  38. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/workflow_cmds.py +109 -0
  39. aria_code-4.2.0/apps/cli/config_store.py +66 -0
  40. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/deterministic.py +8 -2
  41. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/i18n.py +4 -0
  42. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/intent_router.py +32 -5
  43. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/market_universe.py +98 -3
  44. aria_code-4.2.0/apps/cli/pdf_report.py +977 -0
  45. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/preflight.py +33 -28
  46. aria_code-4.2.0/apps/cli/prompt_assembly.py +59 -0
  47. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/prompts/system_prompts.py +12 -3
  48. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/providers/base.py +195 -4
  49. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/providers/chat_routing.py +26 -16
  50. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/providers/llm/ollama_stream.py +317 -51
  51. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/providers/runtime_bridge.py +46 -14
  52. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/runtime_consumer.py +156 -19
  53. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/session_export.py +6 -0
  54. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/tools/market_tools.py +54 -12
  55. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/tools/system_tools.py +19 -4
  56. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/tools/write_tools.py +79 -0
  57. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/tradingview_bridge.py +100 -5
  58. aria_code-4.2.0/apps/cli/turn_planning.py +62 -0
  59. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/utils/market_detect.py +8 -0
  60. {aria_code-4.1.4 → aria_code-4.2.0}/aria_cli.py +1408 -1328
  61. {aria_code-4.1.4 → aria_code-4.2.0}/aria_code.egg-info/PKG-INFO +83 -8
  62. {aria_code-4.1.4 → aria_code-4.2.0}/aria_code.egg-info/SOURCES.txt +69 -0
  63. {aria_code-4.1.4 → aria_code-4.2.0}/aria_code.egg-info/requires.txt +9 -0
  64. {aria_code-4.1.4 → aria_code-4.2.0}/aria_code.egg-info/top_level.txt +2 -0
  65. {aria_code-4.1.4 → aria_code-4.2.0}/aria_daemon.py +67 -2
  66. {aria_code-4.1.4 → aria_code-4.2.0}/artifacts.py +66 -0
  67. aria_code-4.2.0/backtest_engine.py +354 -0
  68. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/__init__.py +6 -0
  69. aria_code-4.2.0/brokers/automation.py +193 -0
  70. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/base.py +24 -0
  71. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/paper_broker.py +7 -0
  72. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/registry.py +32 -1
  73. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/trading.py +18 -0
  74. {aria_code-4.1.4 → aria_code-4.2.0}/doctor.py +79 -0
  75. {aria_code-4.1.4 → aria_code-4.2.0}/file_analysis_tools.py +160 -9
  76. aria_code-4.2.0/licensing.py +150 -0
  77. {aria_code-4.1.4 → aria_code-4.2.0}/local_finance_tools.py +113 -0
  78. {aria_code-4.1.4 → aria_code-4.2.0}/local_llm_provider.py +40 -3
  79. {aria_code-4.1.4 → aria_code-4.2.0}/market_data_client.py +87 -16
  80. {aria_code-4.1.4 → aria_code-4.2.0}/mcp_client.py +126 -23
  81. {aria_code-4.1.4 → aria_code-4.2.0}/model_capability.py +4 -4
  82. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_core/architecture.py +18 -16
  83. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_core/export.py +23 -0
  84. aria_code-4.2.0/packages/aria_mcp/circuit.py +82 -0
  85. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_mcp/config.py +19 -5
  86. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_mcp/tools.py +24 -4
  87. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_sdk/streaming.py +9 -3
  88. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_services/__init__.py +33 -0
  89. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_services/context.py +111 -13
  90. aria_code-4.2.0/packages/aria_services/context_checkpoints.py +156 -0
  91. aria_code-4.2.0/packages/aria_services/references.py +247 -0
  92. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_services/registry.py +38 -2
  93. aria_code-4.2.0/packages/aria_services/research_protocol.py +57 -0
  94. aria_code-4.2.0/packages/aria_services/research_quality.py +186 -0
  95. aria_code-4.2.0/packages/aria_services/settings.py +146 -0
  96. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_services/usage.py +15 -2
  97. aria_code-4.2.0/packages/aria_skills/__init__.py +46 -0
  98. aria_code-4.2.0/packages/aria_skills/catalog.py +148 -0
  99. aria_code-4.2.0/packages/aria_skills/loader.py +429 -0
  100. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_skills/registry.py +26 -1
  101. aria_code-4.2.0/packages/quant_engine/__init__.py +24 -0
  102. {aria_code-4.1.4 → aria_code-4.2.0}/portfolio_ledger.py +44 -0
  103. {aria_code-4.1.4 → aria_code-4.2.0}/providers/llm/openai_compat.py +12 -1
  104. {aria_code-4.1.4 → aria_code-4.2.0}/providers/llm/registry.py +18 -14
  105. {aria_code-4.1.4 → aria_code-4.2.0}/pyproject.toml +19 -2
  106. {aria_code-4.1.4 → aria_code-4.2.0}/report_generator.py +201 -4
  107. {aria_code-4.1.4 → aria_code-4.2.0}/runtime/__init__.py +40 -0
  108. {aria_code-4.1.4 → aria_code-4.2.0}/runtime/agent_loop.py +230 -14
  109. {aria_code-4.1.4 → aria_code-4.2.0}/runtime/approval.py +6 -0
  110. aria_code-4.2.0/runtime/checkpoints.py +432 -0
  111. {aria_code-4.1.4 → aria_code-4.2.0}/runtime/events.py +13 -2
  112. {aria_code-4.1.4 → aria_code-4.2.0}/runtime/gateway.py +16 -1
  113. aria_code-4.2.0/runtime/run_state.py +127 -0
  114. aria_code-4.2.0/runtime/run_store.py +449 -0
  115. {aria_code-4.1.4 → aria_code-4.2.0}/runtime/subagent.py +176 -5
  116. aria_code-4.2.0/runtime/tool_executor.py +198 -0
  117. aria_code-4.2.0/runtime/worktrees.py +215 -0
  118. {aria_code-4.1.4 → aria_code-4.2.0}/safety/__init__.py +2 -0
  119. aria_code-4.2.0/safety/service.py +86 -0
  120. aria_code-4.2.0/tests/test_agent_team_fallback.py +105 -0
  121. aria_code-4.2.0/tests/test_analyze_file_tool.py +93 -0
  122. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_architecture_report.py +3 -2
  123. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_aria_cli_core.py +68 -0
  124. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_aria_sdk.py +69 -0
  125. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_artifacts_and_reports.py +26 -0
  126. aria_code-4.2.0/tests/test_backtest_cmds.py +184 -0
  127. aria_code-4.2.0/tests/test_backtest_engine.py +146 -0
  128. aria_code-4.2.0/tests/test_broker_automation.py +133 -0
  129. aria_code-4.2.0/tests/test_broker_safety.py +96 -0
  130. aria_code-4.2.0/tests/test_channel_intake.py +73 -0
  131. aria_code-4.2.0/tests/test_channels.py +102 -0
  132. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_chat_routing.py +13 -4
  133. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_cli_app_split.py +71 -2
  134. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_cli_runtime_consumer.py +86 -2
  135. aria_code-4.2.0/tests/test_configured_provider.py +102 -0
  136. aria_code-4.2.0/tests/test_context_checkpoints.py +130 -0
  137. aria_code-4.2.0/tests/test_context_references.py +177 -0
  138. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_context_service.py +41 -4
  139. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_doctor.py +75 -1
  140. aria_code-4.2.0/tests/test_finance_renderers.py +116 -0
  141. aria_code-4.2.0/tests/test_football_agent.py +103 -0
  142. aria_code-4.2.0/tests/test_licensing.py +89 -0
  143. aria_code-4.2.0/tests/test_markdown_pdf.py +60 -0
  144. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_market_data_client.py +50 -0
  145. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_market_history_tool.py +51 -0
  146. aria_code-4.2.0/tests/test_market_symbol_extraction.py +72 -0
  147. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_market_universe.py +36 -0
  148. aria_code-4.2.0/tests/test_mcp_circuit.py +170 -0
  149. aria_code-4.2.0/tests/test_mcp_client.py +64 -0
  150. aria_code-4.2.0/tests/test_model_selection_state.py +51 -0
  151. aria_code-4.2.0/tests/test_ollama_stream_tools.py +137 -0
  152. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_output_rendering.py +33 -0
  153. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_packages_facade.py +32 -0
  154. aria_code-4.2.0/tests/test_pdf_report.py +270 -0
  155. aria_code-4.2.0/tests/test_pick_best_installed_model.py +63 -0
  156. aria_code-4.2.0/tests/test_portfolio_ledger.py +89 -0
  157. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_preflight.py +30 -2
  158. aria_code-4.2.0/tests/test_prompt_assembly.py +70 -0
  159. aria_code-4.2.0/tests/test_report_generator.py +65 -0
  160. aria_code-4.2.0/tests/test_research_protocol.py +26 -0
  161. aria_code-4.2.0/tests/test_research_quality.py +96 -0
  162. aria_code-4.2.0/tests/test_responsive_rendering.py +90 -0
  163. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_runtime_agent_loop.py +195 -1
  164. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_runtime_approval.py +31 -0
  165. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_runtime_bridge.py +56 -1
  166. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_runtime_bridge_fallback.py +2 -2
  167. aria_code-4.2.0/tests/test_runtime_checkpoints.py +175 -0
  168. aria_code-4.2.0/tests/test_runtime_run_store.py +146 -0
  169. aria_code-4.2.0/tests/test_runtime_tool_executor.py +163 -0
  170. aria_code-4.2.0/tests/test_runtime_worktrees.py +151 -0
  171. aria_code-4.2.0/tests/test_safety_service.py +100 -0
  172. aria_code-4.2.0/tests/test_settings_service.py +108 -0
  173. aria_code-4.2.0/tests/test_skill_agent_binding.py +103 -0
  174. aria_code-4.2.0/tests/test_skill_catalog.py +187 -0
  175. aria_code-4.2.0/tests/test_skill_loader.py +208 -0
  176. aria_code-4.2.0/tests/test_spreadsheet_tools.py +92 -0
  177. aria_code-4.2.0/tests/test_startup_dashboard.py +122 -0
  178. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_subagent.py +44 -0
  179. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_tradingview_bridge.py +44 -0
  180. aria_code-4.2.0/tests/test_turn_planning.py +58 -0
  181. aria_code-4.2.0/tests/test_ui_completer_references.py +79 -0
  182. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_ui_console_theme.py +8 -1
  183. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_ui_input_box.py +115 -1
  184. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_ui_robot_banner.py +7 -6
  185. {aria_code-4.1.4 → aria_code-4.2.0}/ui/__init__.py +7 -2
  186. {aria_code-4.1.4 → aria_code-4.2.0}/ui/banner.py +229 -67
  187. {aria_code-4.1.4 → aria_code-4.2.0}/ui/completer.py +132 -22
  188. {aria_code-4.1.4 → aria_code-4.2.0}/ui/console.py +11 -1
  189. {aria_code-4.1.4 → aria_code-4.2.0}/ui/input_box.py +145 -33
  190. {aria_code-4.1.4 → aria_code-4.2.0}/ui/picker.py +9 -5
  191. {aria_code-4.1.4 → aria_code-4.2.0}/ui/render/finance.py +239 -21
  192. {aria_code-4.1.4 → aria_code-4.2.0}/ui/render/output.py +80 -2
  193. aria_code-4.2.0/ui/render/responsive.py +75 -0
  194. {aria_code-4.1.4 → aria_code-4.2.0}/ui/render/team.py +10 -2
  195. aria_code-4.2.0/ui/startup_dashboard.py +109 -0
  196. aria_code-4.1.4/apps/cli/config_store.py +0 -61
  197. aria_code-4.1.4/packages/aria_skills/__init__.py +0 -5
  198. aria_code-4.1.4/packages/quant_engine/__init__.py +0 -6
  199. aria_code-4.1.4/runtime/tool_executor.py +0 -104
  200. aria_code-4.1.4/tests/test_backtest_cmds.py +0 -96
  201. aria_code-4.1.4/tests/test_runtime_tool_executor.py +0 -63
  202. {aria_code-4.1.4 → aria_code-4.2.0}/LICENSE +0 -0
  203. {aria_code-4.1.4 → aria_code-4.2.0}/agents/deep/__init__.py +0 -0
  204. {aria_code-4.1.4 → aria_code-4.2.0}/agents/deep/calibration_loop.py +0 -0
  205. {aria_code-4.1.4 → aria_code-4.2.0}/agents/deep/critic.py +0 -0
  206. {aria_code-4.1.4 → aria_code-4.2.0}/agents/deep/deepen.py +0 -0
  207. {aria_code-4.1.4 → aria_code-4.2.0}/agents/deep/models.py +0 -0
  208. {aria_code-4.1.4 → aria_code-4.2.0}/agents/deep/pipeline.py +0 -0
  209. {aria_code-4.1.4 → aria_code-4.2.0}/agents/deep/quant_fusion.py +0 -0
  210. {aria_code-4.1.4 → aria_code-4.2.0}/agents/deep/themes.py +0 -0
  211. {aria_code-4.1.4 → aria_code-4.2.0}/agents/deep/tiers.py +0 -0
  212. {aria_code-4.1.4 → aria_code-4.2.0}/agents/financial/__init__.py +0 -0
  213. {aria_code-4.1.4 → aria_code-4.2.0}/agents/financial/catalyst.py +0 -0
  214. {aria_code-4.1.4 → aria_code-4.2.0}/agents/financial/debate.py +0 -0
  215. {aria_code-4.1.4 → aria_code-4.2.0}/agents/financial/earnings.py +0 -0
  216. {aria_code-4.1.4 → aria_code-4.2.0}/agents/financial/fundamental.py +0 -0
  217. {aria_code-4.1.4 → aria_code-4.2.0}/agents/financial/macro.py +0 -0
  218. {aria_code-4.1.4 → aria_code-4.2.0}/agents/financial/news.py +0 -0
  219. {aria_code-4.1.4 → aria_code-4.2.0}/agents/financial/risk.py +0 -0
  220. {aria_code-4.1.4 → aria_code-4.2.0}/agents/financial/sector.py +0 -0
  221. {aria_code-4.1.4 → aria_code-4.2.0}/agents/financial/synthesis.py +0 -0
  222. {aria_code-4.1.4 → aria_code-4.2.0}/agents/financial/technical.py +0 -0
  223. {aria_code-4.1.4 → aria_code-4.2.0}/agents/realty/__init__.py +0 -0
  224. {aria_code-4.1.4 → aria_code-4.2.0}/agents/registry.py +0 -0
  225. {aria_code-4.1.4 → aria_code-4.2.0}/agents/sports/__init__.py +0 -0
  226. {aria_code-4.1.4 → aria_code-4.2.0}/aliyun_data_client.py +0 -0
  227. {aria_code-4.1.4 → aria_code-4.2.0}/apps/README.md +0 -0
  228. {aria_code-4.1.4 → aria_code-4.2.0}/apps/__init__.py +0 -0
  229. {aria_code-4.1.4 → aria_code-4.2.0}/apps/channels/README.md +0 -0
  230. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/README.md +0 -0
  231. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/__init__.py +0 -0
  232. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/codegen_paths.py +0 -0
  233. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/__init__.py +0 -0
  234. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/analysis_cmds.py +0 -0
  235. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/business_workflow_cmds.py +0 -0
  236. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/data_cmds.py +0 -0
  237. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/diagnostic_cmds.py +0 -0
  238. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/finance_render.py +0 -0
  239. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/market_cmds.py +0 -0
  240. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/market_context.py +0 -0
  241. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/market_render.py +0 -0
  242. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/ops_cmds.py +0 -0
  243. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/scaffold_templates.py +0 -0
  244. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/team_render.py +0 -0
  245. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/ui_cmds.py +0 -0
  246. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/commands/workspace_cmds.py +0 -0
  247. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/config_paths.py +0 -0
  248. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/direct.py +0 -0
  249. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/github_app_auth.py +0 -0
  250. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/handlers/__init__.py +0 -0
  251. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/handlers/broker_handlers.py +0 -0
  252. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/handlers/chart_handlers.py +0 -0
  253. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/handlers/market_handlers.py +0 -0
  254. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/handlers/realty_handlers.py +0 -0
  255. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/handlers/strategy_advice.py +0 -0
  256. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/hooks.py +0 -0
  257. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/intent.py +0 -0
  258. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/lifecycle_hooks.py +0 -0
  259. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/main.py +0 -0
  260. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/market_metadata.py +0 -0
  261. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/message_processing.py +0 -0
  262. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/plan_mode.py +0 -0
  263. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/plotly_html.py +0 -0
  264. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/prediction_feedback.py +0 -0
  265. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/project_aria.py +0 -0
  266. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/prompts/__init__.py +0 -0
  267. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/prompts/coding.py +0 -0
  268. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/prompts/ui.py +0 -0
  269. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/providers/__init__.py +0 -0
  270. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/providers/llm/__init__.py +0 -0
  271. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/providers/llm/sse_stream.py +0 -0
  272. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/session_jsonl.py +0 -0
  273. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/session_store.py +0 -0
  274. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/todo_tracker.py +0 -0
  275. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/tools/__init__.py +0 -0
  276. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/tools/context.py +0 -0
  277. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/tools/file_tools.py +0 -0
  278. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/tools/notebook_tools.py +0 -0
  279. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/update_check.py +0 -0
  280. {aria_code-4.1.4 → aria_code-4.2.0}/apps/cli/utils/__init__.py +0 -0
  281. {aria_code-4.1.4 → aria_code-4.2.0}/apps/daemon/README.md +0 -0
  282. {aria_code-4.1.4 → aria_code-4.2.0}/apps/vscode/README.md +0 -0
  283. {aria_code-4.1.4 → aria_code-4.2.0}/apps/vscode/package.json +0 -0
  284. {aria_code-4.1.4 → aria_code-4.2.0}/aria_code.egg-info/dependency_links.txt +0 -0
  285. {aria_code-4.1.4 → aria_code-4.2.0}/aria_code.egg-info/entry_points.txt +0 -0
  286. {aria_code-4.1.4 → aria_code-4.2.0}/aria_feishu_bot.py +0 -0
  287. {aria_code-4.1.4 → aria_code-4.2.0}/aria_relay_client.py +0 -0
  288. {aria_code-4.1.4 → aria_code-4.2.0}/aria_relay_server.py +0 -0
  289. {aria_code-4.1.4 → aria_code-4.2.0}/aria_telegram_bot.py +0 -0
  290. {aria_code-4.1.4 → aria_code-4.2.0}/ariarc.py +0 -0
  291. {aria_code-4.1.4 → aria_code-4.2.0}/backtest_report.py +0 -0
  292. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/capabilities.py +0 -0
  293. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/cn/__init__.py +0 -0
  294. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/cn/easytrader_broker.py +0 -0
  295. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/cn/futu_broker.py +0 -0
  296. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/cn/longbridge_broker.py +0 -0
  297. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/cn/tiger_broker.py +0 -0
  298. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/cn/xtquant_broker.py +0 -0
  299. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/config.py +0 -0
  300. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/intl/__init__.py +0 -0
  301. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/intl/alpaca_broker.py +0 -0
  302. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/intl/ibkr_broker.py +0 -0
  303. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/intl/webull_broker.py +0 -0
  304. {aria_code-4.1.4 → aria_code-4.2.0}/brokers/planning.py +0 -0
  305. {aria_code-4.1.4 → aria_code-4.2.0}/change_store.py +0 -0
  306. {aria_code-4.1.4 → aria_code-4.2.0}/command_safety.py +0 -0
  307. {aria_code-4.1.4 → aria_code-4.2.0}/computer_use_tools.py +0 -0
  308. {aria_code-4.1.4 → aria_code-4.2.0}/dashboard_generator.py +0 -0
  309. {aria_code-4.1.4 → aria_code-4.2.0}/data_analysis_tools.py +0 -0
  310. {aria_code-4.1.4 → aria_code-4.2.0}/data_cleaner.py +0 -0
  311. {aria_code-4.1.4 → aria_code-4.2.0}/data_service.py +0 -0
  312. {aria_code-4.1.4 → aria_code-4.2.0}/datasources/__init__.py +0 -0
  313. {aria_code-4.1.4 → aria_code-4.2.0}/datasources/base.py +0 -0
  314. {aria_code-4.1.4 → aria_code-4.2.0}/datasources/router.py +0 -0
  315. {aria_code-4.1.4 → aria_code-4.2.0}/datasources/sources/__init__.py +0 -0
  316. {aria_code-4.1.4 → aria_code-4.2.0}/datasources/sources/akshare_source.py +0 -0
  317. {aria_code-4.1.4 → aria_code-4.2.0}/datasources/sources/alpha_vantage_source.py +0 -0
  318. {aria_code-4.1.4 → aria_code-4.2.0}/datasources/sources/edgar_source.py +0 -0
  319. {aria_code-4.1.4 → aria_code-4.2.0}/datasources/sources/finnhub_source.py +0 -0
  320. {aria_code-4.1.4 → aria_code-4.2.0}/datasources/sources/fred_source.py +0 -0
  321. {aria_code-4.1.4 → aria_code-4.2.0}/datasources/sources/tushare_source.py +0 -0
  322. {aria_code-4.1.4 → aria_code-4.2.0}/datasources/sources/web_scraper_source.py +0 -0
  323. {aria_code-4.1.4 → aria_code-4.2.0}/datasources/sources/world_bank_source.py +0 -0
  324. {aria_code-4.1.4 → aria_code-4.2.0}/datasources/sources/yfinance_source.py +0 -0
  325. {aria_code-4.1.4 → aria_code-4.2.0}/demo_player.py +0 -0
  326. {aria_code-4.1.4 → aria_code-4.2.0}/finance_formulas.py +0 -0
  327. {aria_code-4.1.4 → aria_code-4.2.0}/football_data_client.py +0 -0
  328. {aria_code-4.1.4 → aria_code-4.2.0}/intent_classifier.py +0 -0
  329. {aria_code-4.1.4 → aria_code-4.2.0}/macro_tools.py +0 -0
  330. {aria_code-4.1.4 → aria_code-4.2.0}/memory_manager.py +0 -0
  331. {aria_code-4.1.4 → aria_code-4.2.0}/notification_tools.py +0 -0
  332. {aria_code-4.1.4 → aria_code-4.2.0}/packages/__init__.py +0 -0
  333. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_agents/__init__.py +0 -0
  334. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_agents/manifest.py +0 -0
  335. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_core/__init__.py +0 -0
  336. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_core/manifest.py +0 -0
  337. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_infra/__init__.py +0 -0
  338. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_infra/arthera.py +0 -0
  339. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_infra/doctor.py +0 -0
  340. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_infra/product.py +0 -0
  341. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_mcp/__init__.py +0 -0
  342. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_mcp/bridge.py +0 -0
  343. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_sdk/__init__.py +0 -0
  344. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_sdk/client.py +0 -0
  345. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_sdk/providers.py +0 -0
  346. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_sdk/types.py +0 -0
  347. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_services/data.py +0 -0
  348. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_services/provider_health.py +0 -0
  349. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_tools/__init__.py +0 -0
  350. {aria_code-4.1.4 → aria_code-4.2.0}/packages/aria_tools/registry.py +0 -0
  351. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/sports/__init__.py +0 -0
  352. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/sports/calibrator.py +0 -0
  353. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/sports/dixon_coles.py +0 -0
  354. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/sports/elo.py +0 -0
  355. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/sports/form.py +0 -0
  356. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/sports/h2h.py +0 -0
  357. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/sports/ml_model.py +0 -0
  358. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/sports/predictor.py +0 -0
  359. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/sports/tracker.py +0 -0
  360. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/stochastic/__init__.py +0 -0
  361. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/stochastic/gbm_enhanced.py +0 -0
  362. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/stochastic/ito_calculus.py +0 -0
  363. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/stochastic/kelly_criterion.py +0 -0
  364. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/stochastic/monte_carlo_advanced.py +0 -0
  365. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/stochastic/options_pricing.py +0 -0
  366. {aria_code-4.1.4 → aria_code-4.2.0}/packages/quant_engine/stochastic/stochastic_processes.py +0 -0
  367. {aria_code-4.1.4 → aria_code-4.2.0}/plan_utils.py +0 -0
  368. {aria_code-4.1.4 → aria_code-4.2.0}/plugin_loader.py +0 -0
  369. {aria_code-4.1.4 → aria_code-4.2.0}/privacy/__init__.py +0 -0
  370. {aria_code-4.1.4 → aria_code-4.2.0}/privacy/feedback.py +0 -0
  371. {aria_code-4.1.4 → aria_code-4.2.0}/project_tools.py +0 -0
  372. {aria_code-4.1.4 → aria_code-4.2.0}/providers/__init__.py +0 -0
  373. {aria_code-4.1.4 → aria_code-4.2.0}/providers/llm/__init__.py +0 -0
  374. {aria_code-4.1.4 → aria_code-4.2.0}/providers/llm/anthropic.py +0 -0
  375. {aria_code-4.1.4 → aria_code-4.2.0}/providers/llm/base.py +0 -0
  376. {aria_code-4.1.4 → aria_code-4.2.0}/providers/llm/ollama.py +0 -0
  377. {aria_code-4.1.4 → aria_code-4.2.0}/realty_data_tools.py +0 -0
  378. {aria_code-4.1.4 → aria_code-4.2.0}/runtime/lsp.py +0 -0
  379. {aria_code-4.1.4 → aria_code-4.2.0}/runtime/tool_policy.py +0 -0
  380. {aria_code-4.1.4 → aria_code-4.2.0}/safety/permissions.py +0 -0
  381. {aria_code-4.1.4 → aria_code-4.2.0}/setup.cfg +0 -0
  382. {aria_code-4.1.4 → aria_code-4.2.0}/setup_wizard.py +0 -0
  383. {aria_code-4.1.4 → aria_code-4.2.0}/strategy_vault.py +0 -0
  384. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_backtest_report.py +0 -0
  385. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_broker_planning.py +0 -0
  386. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_business_workflow_cmds.py +0 -0
  387. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_chart_handlers.py +0 -0
  388. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_cli_bootstrap.py +0 -0
  389. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_cli_config_store.py +0 -0
  390. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_cli_lifecycle_hooks.py +0 -0
  391. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_codegen_output.py +0 -0
  392. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_command_safety.py +0 -0
  393. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_completions_builder.py +0 -0
  394. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_config_paths.py +0 -0
  395. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_dashboard_generator.py +0 -0
  396. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_data_service.py +0 -0
  397. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_deep_analysis.py +0 -0
  398. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_football_prediction_output.py +0 -0
  399. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_image_inputs.py +0 -0
  400. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_intent_router.py +0 -0
  401. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_lsp.py +0 -0
  402. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_new_modules.py +0 -0
  403. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_plan_mode.py +0 -0
  404. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_plotly_html_output.py +0 -0
  405. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_privacy_feedback.py +0 -0
  406. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_project_aria.py +0 -0
  407. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_provider_integration.py +0 -0
  408. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_provider_registry.py +0 -0
  409. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_runtime_gateway.py +0 -0
  410. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_safety_permissions.py +0 -0
  411. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_session_search.py +0 -0
  412. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_streaming_pipeline.py +0 -0
  413. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_system_prompts.py +0 -0
  414. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_system_tools_output.py +0 -0
  415. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_team_synthesis.py +0 -0
  416. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_tool_policy.py +0 -0
  417. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_trading_service.py +0 -0
  418. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_workspace_files.py +0 -0
  419. {aria_code-4.1.4 → aria_code-4.2.0}/tests/test_workspace_verify.py +0 -0
  420. {aria_code-4.1.4 → aria_code-4.2.0}/ui/image_render.py +0 -0
  421. {aria_code-4.1.4 → aria_code-4.2.0}/ui/render/__init__.py +0 -0
  422. {aria_code-4.1.4 → aria_code-4.2.0}/ui/render/market.py +0 -0
  423. {aria_code-4.1.4 → aria_code-4.2.0}/ui/robot.py +0 -0
  424. {aria_code-4.1.4 → aria_code-4.2.0}/workspace/__init__.py +0 -0
  425. {aria_code-4.1.4 → aria_code-4.2.0}/workspace/files.py +0 -0
  426. {aria_code-4.1.4 → aria_code-4.2.0}/workspace/verify.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aria-code
3
- Version: 4.1.4
3
+ Version: 4.2.0
4
4
  Summary: AI-powered financial terminal — local LLM + multi-source market data
5
5
  License: BUSL-1.1
6
6
  Project-URL: Homepage, https://github.com/artherahq/aria-code
@@ -18,7 +18,7 @@ Classifier: Programming Language :: Python :: 3.12
18
18
  Classifier: Programming Language :: Python :: 3.13
19
19
  Classifier: Topic :: Office/Business :: Financial
20
20
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
- Requires-Python: >=3.10
21
+ Requires-Python: <3.14,>=3.10
22
22
  Description-Content-Type: text/markdown
23
23
  License-File: LICENSE
24
24
  Requires-Dist: aiohttp>=3.9.0
@@ -31,11 +31,14 @@ Requires-Dist: PyJWT>=2.8.0
31
31
  Requires-Dist: aiofiles>=23.2.0
32
32
  Requires-Dist: websockets>=12.0
33
33
  Requires-Dist: apscheduler>=3.10.0
34
+ Requires-Dist: ddgs>=9.0
34
35
  Requires-Dist: numpy>=1.26.0
35
36
  Requires-Dist: pandas>=2.2.0
36
37
  Requires-Dist: scipy>=1.13.0
37
38
  Requires-Dist: pandas_ta>=0.4.67b0; python_version >= "3.12"
38
39
  Requires-Dist: yfinance>=0.2.55
40
+ Requires-Dist: pyobjc-framework-WebKit>=10.0; sys_platform == "darwin"
41
+ Requires-Dist: markdown>=3.6
39
42
  Provides-Extra: cn
40
43
  Requires-Dist: akshare>=1.14.68; extra == "cn"
41
44
  Provides-Extra: crypto
@@ -51,6 +54,8 @@ Requires-Dist: python-docx>=1.1.2; extra == "files"
51
54
  Requires-Dist: openpyxl>=3.1.5; extra == "files"
52
55
  Requires-Dist: beautifulsoup4>=4.12.3; extra == "files"
53
56
  Requires-Dist: Pillow>=10.4.0; extra == "files"
57
+ Provides-Extra: video
58
+ Requires-Dist: opencv-python>=4.8.0; extra == "video"
54
59
  Provides-Extra: ibkr
55
60
  Requires-Dist: ib_insync>=0.9.86; extra == "ibkr"
56
61
  Provides-Extra: futu
@@ -114,6 +119,7 @@ Requires-Dist: ddgs>=9.0; extra == "all"
114
119
  Requires-Dist: playwright>=1.44.0; extra == "all"
115
120
  Requires-Dist: mss>=9.0.1; extra == "all"
116
121
  Requires-Dist: pyautogui>=0.9.54; extra == "all"
122
+ Requires-Dist: opencv-python>=4.8.0; extra == "all"
117
123
  Requires-Dist: understat>=0.1.0; extra == "all"
118
124
  Requires-Dist: ib_insync>=0.9.86; extra == "all"
119
125
  Requires-Dist: futu-api>=9.1.5108; extra == "all"
@@ -139,6 +145,8 @@ Dynamic: license-file
139
145
 
140
146
  <p align="center">
141
147
  <a href="https://www.npmjs.com/package/@artheras/aria-code"><img src="https://img.shields.io/npm/v/@artheras/aria-code?style=for-the-badge&logo=npm&color=cb3837&label=npm" alt="npm"/></a>
148
+ <a href="https://pypi.org/project/aria-code/"><img src="https://img.shields.io/pypi/v/aria-code?style=for-the-badge&logo=pypi&logoColor=white&label=PyPI&color=3775A9" alt="PyPI"/></a>
149
+ <a href="https://github.com/artherahq/aria-code/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/artherahq/aria-code/ci.yml?branch=main&style=for-the-badge&logo=githubactions&logoColor=white&label=CI" alt="CI"/></a>
142
150
  <img src="https://img.shields.io/badge/Python-3.10+-3776AB?style=for-the-badge&logo=python&logoColor=white" alt="python"/>
143
151
  <img src="https://img.shields.io/badge/Ollama-Local_LLM-black?style=for-the-badge&logo=llama&logoColor=white" alt="ollama"/>
144
152
  <img src="https://img.shields.io/badge/Providers-19+_Cloud-f59e0b?style=for-the-badge" alt="providers"/>
@@ -176,7 +184,7 @@ Aria Code is a **terminal-first AI financial agent** — think of it as Claude C
176
184
  ```
177
185
  $ aria-code
178
186
 
179
- ▣ Aria Code v4.0 local-first agent
187
+ ▣ Aria Code v4.1 local-first agent
180
188
  model qwen2.5-coder:7b local
181
189
  workspace ~/my-portfolio
182
190
  mode workspace-write · network on · local-only
@@ -214,6 +222,8 @@ $ aria-code
214
222
  | **MCP tools** | 5 new quantitative MCP tools in the tool registry |
215
223
  | **83 commands** | Consolidated from ~150 — removed all LLM-replaceable commands; natural language handles the rest |
216
224
  | **LLM routing fix** | Model now knows it can call real-time data tools instead of saying "I don't have live data" |
225
+ | **Unified agent loop** | CLI, SDK and self-host backend now run the *same* tested runtime (`runtime.run_turn`) — consistent provider routing, cloud→local fallback and tool execution on every surface |
226
+ | **One-command install** | `pip install aria-code` (PyPI) or `npm install -g @artheras/aria-code` — verified clean on Python 3.10 / 3.11 / 3.12 |
217
227
 
218
228
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
219
229
 
@@ -223,7 +233,7 @@ See [CHANGELOG.md](CHANGELOG.md) for the full history.
223
233
  |---------|-------------|
224
234
  | ⌨️ **Keyboard shortcuts** | `Shift+Tab` cycle modes · `Alt+T` thinking · `Alt+P` model picker · `Ctrl+O` transcript · `Ctrl+T` tasks |
225
235
  | `!` **Shell mode** | Type `! git status` to run shell commands, output auto-added to AI context |
226
- | `@` **File autocomplete** | Type `@src/` to get instant file path completion anywhere in input |
236
+ | `@` **Typed context references** | Attach files, folders, assets, portfolios, strategies, datasets, runs, or reports without executing an action |
227
237
  | `/btw` **Side questions** | Ask quick questions without polluting conversation history |
228
238
  | 🌍 **Auto language** | UI and responses auto-detect Chinese/English from OS locale on first run |
229
239
  | 🤖 **19+ cloud providers** | Google Gemini · xAI Grok · Mistral · Cohere · Perplexity · Baidu ERNIE · ByteDance · MiniMax · StepFun · 01.AI + all originals |
@@ -295,7 +305,7 @@ mindmap
295
305
  | 🔍 **Quant research** | `/backtest` `/signal` `/kelly` `/factor` `/portfolio` `/screen` `/corr` `/ptbt` |
296
306
  | 🤖 **19+ cloud providers** | All major international + Chinese LLM APIs supported |
297
307
  | 🔌 **MCP protocol** | Connect any [Model Context Protocol](https://modelcontextprotocol.io) server |
298
- | ⌨️ **Rich keyboard UX** | Vim mode · `!` shell · `@` files · `Shift+Tab` modes · transcript viewer |
308
+ | ⌨️ **Rich keyboard UX** | Vim mode · `!` shell · typed `@` context · `Shift+Tab` modes · transcript viewer |
299
309
  | 💬 **Feishu / Telegram** | Ask Aria from any chat app, anytime |
300
310
  | 📱 **iOS push alerts** | Real-time price alerts via APNs |
301
311
  | 🌍 **Auto bilingual** | OS language auto-detected on first run; output follows user's input language |
@@ -474,9 +484,26 @@ Aria Code has a full keyboard shortcut system powered by `prompt_toolkit`:
474
484
  |--------|------|---------|
475
485
  | `/` | Slash command with fuzzy autocomplete | `/backtest momentum SPY` |
476
486
  | `!` | Shell mode — runs command, adds output to context | `! git diff HEAD~1` |
477
- | `@` | File path autocomplete | `@src/components/` |
487
+ | `@` | Read-only typed context reference | `@file:src/app.py` · `@asset:AAPL` |
478
488
  | `"""` | Multi-line input mode (end with `"""`) | For pasting code blocks |
479
489
 
490
+ `/` and `@` are intentionally different: `/` selects an action; `@` selects
491
+ context for that action or for a natural-language request. They can be combined:
492
+
493
+ ```text
494
+ /risk @portfolio:core
495
+ /backtest @strategy:momentum-v2 @asset:AAPL --period 3y
496
+ Review @folder:apps/cli against @report:last-audit
497
+ ```
498
+
499
+ Available reference types: `@file:`, `@folder:`, `@asset:`, `@portfolio:`,
500
+ `@strategy:`, `@dataset:`, `@run:`, and `@report:`. A plain `@path` remains a
501
+ file reference for compatibility; unknown references fail locally instead of
502
+ being guessed by the model. References contain pointers only: Aria reads them
503
+ on demand through audited tools such as `read_file`, `list_files`,
504
+ `analyze_file`, and `get_market_data`; source content is never silently
505
+ expanded into the prompt.
506
+
480
507
  ### Bottom Toolbar (always visible)
481
508
 
482
509
  ```
@@ -761,6 +788,54 @@ Analyze NVDA momentum → Full AI analysis
761
788
 
762
789
  ---
763
790
 
791
+ ## 📡 TradingView Alerts
792
+
793
+ Pipe TradingView alerts into Aria: the daemon receives the webhook, verifies
794
+ it, and runs a tool-less AI analysis through the shared runtime gateway, then
795
+ pushes the result to your notify channels (Telegram / Feishu).
796
+
797
+ ### Setup
798
+
799
+ ```env
800
+ ARIA_WEBHOOK_SECRET=your-strong-passphrase # REQUIRED for non-local use
801
+ ARIA_WEBHOOK_HOST=127.0.0.1 # bind address (default local-only)
802
+ ARIA_WEBHOOK_PORT=8765
803
+ ARIA_DAEMON_MODEL=qwen2.5:7b # model for alert analysis
804
+ ```
805
+
806
+ ```bash
807
+ python3 aria_daemon.py start
808
+ # endpoint: POST http://127.0.0.1:8765/api/v1/webhook/tradingview
809
+ ```
810
+
811
+ ### TradingView alert message (Webhook URL → your public endpoint)
812
+
813
+ ```json
814
+ {
815
+ "symbol": "{{ticker}}",
816
+ "action": "{{strategy.order.action}}",
817
+ "price": "{{close}}",
818
+ "message": "MA cross on {{interval}}",
819
+ "passphrase": "your-strong-passphrase"
820
+ }
821
+ ```
822
+
823
+ ### Security model
824
+
825
+ - **Passphrase (fail-closed):** with `ARIA_WEBHOOK_SECRET` set, alerts without
826
+ a matching `passphrase` are rejected (constant-time compare). TradingView
827
+ cannot send custom headers, so the body passphrase is the documented way.
828
+ - **Open-mode guard:** with *no* secret and *no* `WEBHOOK_TOKEN` configured,
829
+ only loopback clients may submit — a non-local request gets `403` with a
830
+ fix-it message instead of silently accepting injected buy/sell alerts.
831
+ - **HMAC option:** a fronting relay that can sign requests may send
832
+ `sha256=<hex>` of the raw body; HMAC verification never runs in open mode.
833
+ - **Analysis, not trading:** the alert turn runs with an empty tool set and a
834
+ prompt that forbids order placement. Order *previews* (when a broker is
835
+ configured) still require explicit confirmation via the preview flow.
836
+
837
+ ---
838
+
764
839
  ## 🏗️ Architecture
765
840
 
766
841
  ```
@@ -791,7 +866,7 @@ Analyze NVDA momentum → Full AI analysis
791
866
 
792
867
  ```
793
868
  aria-code/
794
- ├── aria_cli.py # Main CLI + REPL (keyboard shortcuts, ! shell, @files)
869
+ ├── aria_cli.py # Main CLI + REPL (keyboard shortcuts, ! shell, @ context)
795
870
  ├── aria_daemon.py # Background daemon + scheduler
796
871
  ├── market_data_client.py # Unified market data (Finnhub primary for US)
797
872
  ├── setup_wizard.py # Bilingual setup wizard (19 providers)
@@ -807,7 +882,7 @@ aria-code/
807
882
  │
808
883
  ├── ui/
809
884
  │ ├── banner.py # Bilingual banner (i18n aware)
810
- │ └── completer.py # Fuzzy autocomplete: / commands · @ files · ! history
885
+ │ └── completer.py # Fuzzy autocomplete: / commands · @ context · ! history
811
886
  │
812
887
  ├── providers/llm/ # LLM adapters (19+ cloud endpoints)
813
888
  ├── agents/financial/ # Fundamental / Technical / Macro / Risk / Synthesis
@@ -12,6 +12,8 @@
12
12
 
13
13
  <p align="center">
14
14
  <a href="https://www.npmjs.com/package/@artheras/aria-code"><img src="https://img.shields.io/npm/v/@artheras/aria-code?style=for-the-badge&logo=npm&color=cb3837&label=npm" alt="npm"/></a>
15
+ <a href="https://pypi.org/project/aria-code/"><img src="https://img.shields.io/pypi/v/aria-code?style=for-the-badge&logo=pypi&logoColor=white&label=PyPI&color=3775A9" alt="PyPI"/></a>
16
+ <a href="https://github.com/artherahq/aria-code/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/artherahq/aria-code/ci.yml?branch=main&style=for-the-badge&logo=githubactions&logoColor=white&label=CI" alt="CI"/></a>
15
17
  <img src="https://img.shields.io/badge/Python-3.10+-3776AB?style=for-the-badge&logo=python&logoColor=white" alt="python"/>
16
18
  <img src="https://img.shields.io/badge/Ollama-Local_LLM-black?style=for-the-badge&logo=llama&logoColor=white" alt="ollama"/>
17
19
  <img src="https://img.shields.io/badge/Providers-19+_Cloud-f59e0b?style=for-the-badge" alt="providers"/>
@@ -49,7 +51,7 @@ Aria Code is a **terminal-first AI financial agent** — think of it as Claude C
49
51
  ```
50
52
  $ aria-code
51
53
 
52
- ▣ Aria Code v4.0 local-first agent
54
+ ▣ Aria Code v4.1 local-first agent
53
55
  model qwen2.5-coder:7b local
54
56
  workspace ~/my-portfolio
55
57
  mode workspace-write · network on · local-only
@@ -87,6 +89,8 @@ $ aria-code
87
89
  | **MCP tools** | 5 new quantitative MCP tools in the tool registry |
88
90
  | **83 commands** | Consolidated from ~150 — removed all LLM-replaceable commands; natural language handles the rest |
89
91
  | **LLM routing fix** | Model now knows it can call real-time data tools instead of saying "I don't have live data" |
92
+ | **Unified agent loop** | CLI, SDK and self-host backend now run the *same* tested runtime (`runtime.run_turn`) — consistent provider routing, cloud→local fallback and tool execution on every surface |
93
+ | **One-command install** | `pip install aria-code` (PyPI) or `npm install -g @artheras/aria-code` — verified clean on Python 3.10 / 3.11 / 3.12 |
90
94
 
91
95
  See [CHANGELOG.md](CHANGELOG.md) for the full history.
92
96
 
@@ -96,7 +100,7 @@ See [CHANGELOG.md](CHANGELOG.md) for the full history.
96
100
  |---------|-------------|
97
101
  | ⌨️ **Keyboard shortcuts** | `Shift+Tab` cycle modes · `Alt+T` thinking · `Alt+P` model picker · `Ctrl+O` transcript · `Ctrl+T` tasks |
98
102
  | `!` **Shell mode** | Type `! git status` to run shell commands, output auto-added to AI context |
99
- | `@` **File autocomplete** | Type `@src/` to get instant file path completion anywhere in input |
103
+ | `@` **Typed context references** | Attach files, folders, assets, portfolios, strategies, datasets, runs, or reports without executing an action |
100
104
  | `/btw` **Side questions** | Ask quick questions without polluting conversation history |
101
105
  | 🌍 **Auto language** | UI and responses auto-detect Chinese/English from OS locale on first run |
102
106
  | 🤖 **19+ cloud providers** | Google Gemini · xAI Grok · Mistral · Cohere · Perplexity · Baidu ERNIE · ByteDance · MiniMax · StepFun · 01.AI + all originals |
@@ -168,7 +172,7 @@ mindmap
168
172
  | 🔍 **Quant research** | `/backtest` `/signal` `/kelly` `/factor` `/portfolio` `/screen` `/corr` `/ptbt` |
169
173
  | 🤖 **19+ cloud providers** | All major international + Chinese LLM APIs supported |
170
174
  | 🔌 **MCP protocol** | Connect any [Model Context Protocol](https://modelcontextprotocol.io) server |
171
- | ⌨️ **Rich keyboard UX** | Vim mode · `!` shell · `@` files · `Shift+Tab` modes · transcript viewer |
175
+ | ⌨️ **Rich keyboard UX** | Vim mode · `!` shell · typed `@` context · `Shift+Tab` modes · transcript viewer |
172
176
  | 💬 **Feishu / Telegram** | Ask Aria from any chat app, anytime |
173
177
  | 📱 **iOS push alerts** | Real-time price alerts via APNs |
174
178
  | 🌍 **Auto bilingual** | OS language auto-detected on first run; output follows user's input language |
@@ -347,9 +351,26 @@ Aria Code has a full keyboard shortcut system powered by `prompt_toolkit`:
347
351
  |--------|------|---------|
348
352
  | `/` | Slash command with fuzzy autocomplete | `/backtest momentum SPY` |
349
353
  | `!` | Shell mode — runs command, adds output to context | `! git diff HEAD~1` |
350
- | `@` | File path autocomplete | `@src/components/` |
354
+ | `@` | Read-only typed context reference | `@file:src/app.py` · `@asset:AAPL` |
351
355
  | `"""` | Multi-line input mode (end with `"""`) | For pasting code blocks |
352
356
 
357
+ `/` and `@` are intentionally different: `/` selects an action; `@` selects
358
+ context for that action or for a natural-language request. They can be combined:
359
+
360
+ ```text
361
+ /risk @portfolio:core
362
+ /backtest @strategy:momentum-v2 @asset:AAPL --period 3y
363
+ Review @folder:apps/cli against @report:last-audit
364
+ ```
365
+
366
+ Available reference types: `@file:`, `@folder:`, `@asset:`, `@portfolio:`,
367
+ `@strategy:`, `@dataset:`, `@run:`, and `@report:`. A plain `@path` remains a
368
+ file reference for compatibility; unknown references fail locally instead of
369
+ being guessed by the model. References contain pointers only: Aria reads them
370
+ on demand through audited tools such as `read_file`, `list_files`,
371
+ `analyze_file`, and `get_market_data`; source content is never silently
372
+ expanded into the prompt.
373
+
353
374
  ### Bottom Toolbar (always visible)
354
375
 
355
376
  ```
@@ -634,6 +655,54 @@ Analyze NVDA momentum → Full AI analysis
634
655
 
635
656
  ---
636
657
 
658
+ ## 📡 TradingView Alerts
659
+
660
+ Pipe TradingView alerts into Aria: the daemon receives the webhook, verifies
661
+ it, and runs a tool-less AI analysis through the shared runtime gateway, then
662
+ pushes the result to your notify channels (Telegram / Feishu).
663
+
664
+ ### Setup
665
+
666
+ ```env
667
+ ARIA_WEBHOOK_SECRET=your-strong-passphrase # REQUIRED for non-local use
668
+ ARIA_WEBHOOK_HOST=127.0.0.1 # bind address (default local-only)
669
+ ARIA_WEBHOOK_PORT=8765
670
+ ARIA_DAEMON_MODEL=qwen2.5:7b # model for alert analysis
671
+ ```
672
+
673
+ ```bash
674
+ python3 aria_daemon.py start
675
+ # endpoint: POST http://127.0.0.1:8765/api/v1/webhook/tradingview
676
+ ```
677
+
678
+ ### TradingView alert message (Webhook URL → your public endpoint)
679
+
680
+ ```json
681
+ {
682
+ "symbol": "{{ticker}}",
683
+ "action": "{{strategy.order.action}}",
684
+ "price": "{{close}}",
685
+ "message": "MA cross on {{interval}}",
686
+ "passphrase": "your-strong-passphrase"
687
+ }
688
+ ```
689
+
690
+ ### Security model
691
+
692
+ - **Passphrase (fail-closed):** with `ARIA_WEBHOOK_SECRET` set, alerts without
693
+ a matching `passphrase` are rejected (constant-time compare). TradingView
694
+ cannot send custom headers, so the body passphrase is the documented way.
695
+ - **Open-mode guard:** with *no* secret and *no* `WEBHOOK_TOKEN` configured,
696
+ only loopback clients may submit — a non-local request gets `403` with a
697
+ fix-it message instead of silently accepting injected buy/sell alerts.
698
+ - **HMAC option:** a fronting relay that can sign requests may send
699
+ `sha256=<hex>` of the raw body; HMAC verification never runs in open mode.
700
+ - **Analysis, not trading:** the alert turn runs with an empty tool set and a
701
+ prompt that forbids order placement. Order *previews* (when a broker is
702
+ configured) still require explicit confirmation via the preview flow.
703
+
704
+ ---
705
+
637
706
  ## 🏗️ Architecture
638
707
 
639
708
  ```
@@ -664,7 +733,7 @@ Analyze NVDA momentum → Full AI analysis
664
733
 
665
734
  ```
666
735
  aria-code/
667
- ├── aria_cli.py # Main CLI + REPL (keyboard shortcuts, ! shell, @files)
736
+ ├── aria_cli.py # Main CLI + REPL (keyboard shortcuts, ! shell, @ context)
668
737
  ├── aria_daemon.py # Background daemon + scheduler
669
738
  ├── market_data_client.py # Unified market data (Finnhub primary for US)
670
739
  ├── setup_wizard.py # Bilingual setup wizard (19 providers)
@@ -680,7 +749,7 @@ aria-code/
680
749
  │
681
750
  ├── ui/
682
751
  │ ├── banner.py # Bilingual banner (i18n aware)
683
- │ └── completer.py # Fuzzy autocomplete: / commands · @ files · ! history
752
+ │ └── completer.py # Fuzzy autocomplete: / commands · @ context · ! history
684
753
  │
685
754
  ├── providers/llm/ # LLM adapters (19+ cloud endpoints)
686
755
  ├── agents/financial/ # Fundamental / Technical / Macro / Risk / Synthesis
@@ -24,9 +24,11 @@ agents/ — Aria Code 可组合多智能体系统
24
24
  from .base import BaseAgent, AgentResult
25
25
  from .registry import AgentRegistry, get_registry
26
26
  from .team import AgentTeam, run_team
27
+ from .signal_scheme import SignalScheme, FINANCIAL_SCHEME, REALTY_SCHEME
27
28
 
28
29
  __all__ = [
29
30
  "BaseAgent", "AgentResult",
30
31
  "AgentRegistry", "get_registry",
31
32
  "AgentTeam", "run_team",
33
+ "SignalScheme", "FINANCIAL_SCHEME", "REALTY_SCHEME",
32
34
  ]
@@ -26,6 +26,9 @@ class AgentResult:
26
26
  key_points: List[str] = field(default_factory=list) # 关键结论(用于 synthesis)
27
27
  data_used: Dict[str, Any] = field(default_factory=dict) # 使用的原始数据
28
28
  error: Optional[str] = None # 失败时的错误信息
29
+ degraded: bool = False # True when a deterministic fallback was used
30
+ provenance: List[str] = field(default_factory=list)
31
+ limitations: List[str] = field(default_factory=list)
29
32
 
30
33
  @property
31
34
  def success(self) -> bool:
@@ -40,6 +43,9 @@ class AgentResult:
40
43
  "signal": self.signal,
41
44
  "key_points": self.key_points,
42
45
  "error": self.error,
46
+ "degraded": self.degraded,
47
+ "provenance": list(self.provenance),
48
+ "limitations": list(self.limitations),
43
49
  }
44
50
 
45
51
 
@@ -47,12 +47,24 @@ class PortfolioAgent(BaseAgent):
47
47
 
48
48
  # ── Multi-symbol interface ────────────────────────────────────────────────
49
49
 
50
- async def run_portfolio(self, symbols: List[str]) -> AgentResult:
51
- """Primary entry point for multi-symbol analysis."""
52
- data = await self.fetch_portfolio_data(symbols)
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)
53
63
  return await self.analyze_portfolio(symbols, data)
54
64
 
55
- async def fetch_portfolio_data(self, symbols: List[str]) -> Dict[str, Any]:
65
+ async def fetch_portfolio_data(
66
+ self, symbols: List[str], weights: Optional[Dict[str, float]] = None
67
+ ) -> Dict[str, Any]:
56
68
  data: Dict[str, Any] = {"symbols": symbols}
57
69
  if len(symbols) < 2:
58
70
  return data
@@ -97,8 +109,15 @@ class PortfolioAgent(BaseAgent):
97
109
  cov_matrix = returns.cov() * 252
98
110
  valid_syms = list(df.columns)
99
111
  n = len(valid_syms)
100
- weights = np.ones(n) / n
101
- port_vol = float(np.sqrt(weights @ cov_matrix.values @ weights))
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)}
102
121
 
103
122
  # High correlation pairs (|r| > 0.70)
104
123
  high_corr: List[Dict] = []
@@ -112,8 +131,10 @@ class PortfolioAgent(BaseAgent):
112
131
  "corr": round(c, 3),
113
132
  })
114
133
 
115
- # Diversification ratio: weighted avg individual vol / portfolio vol
116
- avg_vol = float(np.mean([float(ann_vols.get(s, 0)) for s in valid_syms]))
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)))
117
138
  div_ratio = round(avg_vol / port_vol, 2) if port_vol > 0 else 1.0
118
139
 
119
140
  # 52-week return per symbol
@@ -140,6 +161,8 @@ class PortfolioAgent(BaseAgent):
140
161
  "best_performer": sorted_ret[0] if sorted_ret else None,
141
162
  "worst_performer": sorted_ret[-1] if sorted_ret else None,
142
163
  "sector_map": sector_map,
164
+ "position_weights": position_weights,
165
+ "weight_source": weight_source,
143
166
  })
144
167
 
145
168
  except ImportError:
@@ -171,9 +194,11 @@ class PortfolioAgent(BaseAgent):
171
194
 
172
195
  valid_syms = data.get("valid_symbols", symbols)
173
196
  port_block = _format_portfolio_stats(data)
197
+ weight_desc = ("your actual position sizes" if data.get("weight_source") == "ledger"
198
+ else "equal weight — no real position sizes available")
174
199
 
175
200
  prompt = (
176
- f"Portfolio: {', '.join(valid_syms)} ({len(valid_syms)} positions, equal weight)\n\n"
201
+ f"Portfolio: {', '.join(valid_syms)} ({len(valid_syms)} positions, weighted by {weight_desc})\n\n"
177
202
  f"{port_block}\n\n"
178
203
  "Analyze this portfolio:\n"
179
204
  "1. Overall risk level (Low / Medium / High)\n"
@@ -217,15 +242,17 @@ def _format_portfolio_stats(d: Dict) -> str:
217
242
  vols = d.get("ann_vols", {})
218
243
  rets = d.get("ann_returns", {})
219
244
  rets_1y = d.get("returns_1y", {})
245
+ pweights = d.get("position_weights", {})
220
246
  if vols:
221
- lines.append("Symbol │ Ann.Vol │ Ann.Ret │ 1Y Return")
222
- lines.append("─" * 42)
247
+ lines.append("Symbol │ Weight │ Ann.Vol │ Ann.Ret │ 1Y Return")
248
+ lines.append("─" * 52)
223
249
  for sym in d.get("valid_symbols", list(vols)):
224
250
  v = vols.get(sym, 0)
225
251
  r = rets.get(sym, 0)
226
252
  y = rets_1y.get(sym, 0)
253
+ w = pweights.get(sym, 0)
227
254
  lines.append(
228
- f"{sym:<6} │ {v*100:>6.1f}% │ {r*100:>6.1f}% │ {y*100:>+7.1f}%"
255
+ f"{sym:<6} │ {w*100:>5.1f}% │ {v*100:>6.1f}% │ {r*100:>6.1f}% │ {y*100:>+7.1f}%"
229
256
  )
230
257
 
231
258
  port_vol = d.get("port_vol_ann", 0)
@@ -288,7 +315,10 @@ def _estimate_confidence(d: Dict) -> float:
288
315
  def _build_key_points(d: Dict, verdict: str) -> List[str]:
289
316
  pts = []
290
317
  n = len(d.get("valid_symbols", []))
291
- pts.append(f"{n} 个标的,等权配置")
318
+ if d.get("weight_source") == "ledger":
319
+ pts.append(f"{n} 个标的,按真实持仓成本加权")
320
+ else:
321
+ pts.append(f"{n} 个标的,等权配置(无真实持仓数据,非实际风险暴露)")
292
322
 
293
323
  port_vol = d.get("port_vol_ann", 0)
294
324
  if port_vol:
@@ -10,7 +10,9 @@ agents/realty/asset_diagnosis.py — 资产诊断 Agent
10
10
 
11
11
  输出:
12
12
  analysis — 详细分析文本
13
- signal — BUY=推荐共创 / HOLD=需观察 / SELL=建议出租或出售
13
+ signal — GOOD=推荐共创 / WATCH=需观察 / CONCERN=建议出租或出售
14
+ (地产健康度尺度,见 agents/signal_scheme.py::REALTY_SCHEME,
15
+ 不是股票 BUY/SELL 那套交易动作词汇)
14
16
  key_points — 3-5 条关键结论
15
17
  """
16
18
  from __future__ import annotations
@@ -101,9 +103,9 @@ def _score_to_signal(asset: Dict, reno: float) -> str:
101
103
  if state != "正常": score -= 2
102
104
  if reno > rent * 24: score -= 1 # 改造成本超过2年租金则不划算
103
105
 
104
- if score >= 4: return "BUY" # 非常适合共创
105
- if score >= 2: return "HOLD" # 需进一步评估
106
- return "SELL" # 建议传统出租或出售
106
+ if score >= 4: return "GOOD" # 非常适合共创
107
+ if score >= 2: return "WATCH" # 需进一步评估
108
+ return "CONCERN" # 建议传统出租或出售
107
109
 
108
110
 
109
111
  def _calc_confidence(asset: Dict) -> float:
@@ -10,7 +10,8 @@ agents/realty/business_match.py — 业态匹配 Agent
10
10
 
11
11
  输出:
12
12
  analysis — 业态匹配建议
13
- signal — BUY=高度匹配 / HOLD=一般匹配 / SELL=低匹配
13
+ signal — GOOD=高度匹配 / WATCH=一般匹配 / CONCERN=低匹配
14
+ (地产健康度尺度,见 signal_scheme.py)
14
15
  key_points — 推荐业态 Top3 + 理由
15
16
  """
16
17
  from __future__ import annotations
@@ -115,9 +116,9 @@ def _match_signal(asset: Dict, market: Dict) -> str:
115
116
  if market_score >= 7: score += 1
116
117
  elif 0 < market_score <= 3: score -= 1
117
118
 
118
- if score >= 4: return "BUY"
119
- if score >= 2: return "HOLD"
120
- return "SELL"
119
+ if score >= 4: return "GOOD"
120
+ if score >= 2: return "WATCH"
121
+ return "CONCERN"
121
122
 
122
123
 
123
124
  def _match_confidence(asset: Dict, market: Dict) -> float:
@@ -14,7 +14,8 @@ agents/realty/cashflow_verify.py — 流水核验 Agent
14
14
 
15
15
  输出:
16
16
  analysis — 核验报告
17
- signal — BUY=流水真实 / HOLD=轻度异常需复核 / SELL=疑似造假/私账
17
+ signal — GOOD=流水真实 / WATCH=轻度异常需复核 / CONCERN=疑似造假/私账
18
+ / SEVERE=多项异常+差距极大(地产健康度尺度,见 signal_scheme.py)
18
19
  key_points — 异常项目清单
19
20
  """
20
21
  from __future__ import annotations
@@ -174,10 +175,10 @@ def _cross_verify(
174
175
  def _verify_signal(check: Dict) -> str:
175
176
  n = check.get("anomaly_count", 0)
176
177
  gap = abs(check.get("gap_pct", 0))
177
- if n == 0 and gap < 15: return "BUY"
178
- if n <= 1 and gap < 30: return "HOLD"
179
- if n <= 2 and gap < 50: return "SELL"
180
- return "STRONG_SELL"
178
+ if n == 0 and gap < 15: return "GOOD"
179
+ if n <= 1 and gap < 30: return "WATCH"
180
+ if n <= 2 and gap < 50: return "CONCERN"
181
+ return "SEVERE"
181
182
 
182
183
 
183
184
  def _verify_confidence(check: Dict) -> float:
@@ -10,7 +10,8 @@ agents/realty/contract_rules.py — 合同规则 Agent
10
10
 
11
11
  输出:
12
12
  analysis — 合同条款草案文本
13
- signal — BUY=条款清晰可执行 / HOLD=需补充条款 / SELL=有重大风险条款
13
+ signal — GOOD=条款清晰可执行 / WATCH=需补充条款 / CONCERN=有重大风险条款
14
+ (地产健康度尺度,见 signal_scheme.py)
14
15
  key_points — 关键条款摘要(保底金额/分润比例/结算周期/违约条款)
15
16
  """
16
17
  from __future__ import annotations
@@ -139,9 +140,9 @@ def _contract_signal(nego: Dict) -> str:
139
140
  if not nego.get("settlement_cycle"): issues += 1
140
141
  if not nego.get("contract_years"): issues += 1
141
142
 
142
- if issues == 0: return "BUY"
143
- if issues <= 2: return "HOLD"
144
- return "SELL"
143
+ if issues == 0: return "GOOD"
144
+ if issues <= 2: return "WATCH"
145
+ return "CONCERN"
145
146
 
146
147
 
147
148
  def _contract_confidence(nego: Dict) -> float:
@@ -13,7 +13,8 @@ agents/realty/energy_anomaly.py — 能耗异常 Agent
13
13
 
14
14
  输出:
15
15
  analysis — 能耗分析报告
16
- signal — BUY=正常 / HOLD=轻度异常 / SELL=严重异常/疑似空置
16
+ signal — GOOD=正常 / WATCH=轻度异常 / CONCERN=中度异常 / SEVERE=严重异常/疑似空置
17
+ (地产健康度尺度,见 signal_scheme.py)
17
18
  key_points — 异常指标清单
18
19
  """
19
20
  from __future__ import annotations
@@ -154,10 +155,10 @@ def _analyze_energy(
154
155
 
155
156
  def _energy_signal(check: Dict) -> str:
156
157
  n = check.get("anomaly_count", 0)
157
- if n == 0: return "BUY"
158
- if n == 1: return "HOLD"
159
- if n == 2: return "SELL"
160
- return "STRONG_SELL"
158
+ if n == 0: return "GOOD"
159
+ if n == 1: return "WATCH"
160
+ if n == 2: return "CONCERN"
161
+ return "SEVERE"
161
162
 
162
163
 
163
164
  def _energy_confidence(check: Dict) -> float:
@@ -11,7 +11,8 @@ agents/realty/exit_settlement.py — 退出清算 Agent
11
11
 
12
12
  输出:
13
13
  analysis — 清算方案草案
14
- signal — BUY=清算顺利无纠纷 / HOLD=有待确认项 / SELL=存在较大争议
14
+ signal — GOOD=清算顺利无纠纷 / WATCH=有待确认项 / CONCERN=存在较大争议
15
+ (地产健康度尺度,见 signal_scheme.py)
15
16
  key_points — 各方清算金额摘要
16
17
  data_used — 包含 settlement_result(结构化清算数据)
17
18
  """
@@ -145,12 +146,12 @@ def _calculate_settlement(
145
146
 
146
147
  def _settlement_signal(s: Dict, reason: str) -> str:
147
148
  if s["net_settlement"] > 0 and not s["is_breach"]:
148
- return "HOLD" # 经营方有欠款但无违约,需催收
149
+ return "WATCH" # 经营方有欠款但无违约,需催收
149
150
  if s["is_breach"] and s["net_settlement"] > 0:
150
- return "SELL" # 违约且有欠款
151
+ return "CONCERN" # 违约且有欠款
151
152
  if s["operator_owes"] == 0 and s["platform_owes"] == 0:
152
- return "BUY" # 干净退出
153
- return "HOLD"
153
+ return "GOOD" # 干净退出
154
+ return "WATCH"
154
155
 
155
156
 
156
157
  def _settlement_confidence(fin: Dict) -> float: