aria-code 0.66.0__tar.gz → 0.67.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 (715) hide show
  1. {aria_code-0.66.0 → aria_code-0.67.0}/PKG-INFO +4 -1
  2. {aria_code-0.66.0 → aria_code-0.67.0}/pyproject.toml +7 -1
  3. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/_version.py +1 -1
  4. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/channels/README.md +11 -0
  5. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/aria_daemon.py +5 -3
  6. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/aria_feishu_bot.py +54 -49
  7. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/aria_relay_server.py +145 -1
  8. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/clients/aria_relay_client.py +44 -0
  9. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code.egg-info/PKG-INFO +4 -1
  10. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code.egg-info/SOURCES.txt +1 -0
  11. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code.egg-info/requires.txt +3 -0
  12. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_project_review_api.py +3 -3
  13. aria_code-0.67.0/tests/test_relay_sends_for_clients.py +270 -0
  14. {aria_code-0.66.0 → aria_code-0.67.0}/LICENSE +0 -0
  15. {aria_code-0.66.0 → aria_code-0.67.0}/NOTICE +0 -0
  16. {aria_code-0.66.0 → aria_code-0.67.0}/README.md +0 -0
  17. {aria_code-0.66.0 → aria_code-0.67.0}/setup.cfg +0 -0
  18. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/__init__.py +0 -0
  19. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/adk_apps/__init__.py +0 -0
  20. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/adk_apps/aria_code_review/__init__.py +0 -0
  21. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/adk_apps/aria_code_review/agent.py +0 -0
  22. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/adk_apps/aria_research/__init__.py +0 -0
  23. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/adk_apps/aria_research/agent.py +0 -0
  24. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/__init__.py +0 -0
  25. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/base.py +0 -0
  26. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/code_review.py +0 -0
  27. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/deep/__init__.py +0 -0
  28. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/deep/calibration_loop.py +0 -0
  29. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/deep/critic.py +0 -0
  30. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/deep/deepen.py +0 -0
  31. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/deep/models.py +0 -0
  32. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/deep/pipeline.py +0 -0
  33. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/deep/quant_fusion.py +0 -0
  34. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/deep/themes.py +0 -0
  35. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/deep/tiers.py +0 -0
  36. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/engineering/__init__.py +0 -0
  37. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/engineering/coder.py +0 -0
  38. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/engineering/tester.py +0 -0
  39. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/financial/__init__.py +0 -0
  40. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/financial/cashflow_burn.py +0 -0
  41. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/financial/catalyst.py +0 -0
  42. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/financial/corporate_finance.py +0 -0
  43. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/financial/debate.py +0 -0
  44. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/financial/earnings.py +0 -0
  45. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/financial/fundamental.py +0 -0
  46. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/financial/macro.py +0 -0
  47. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/financial/news.py +0 -0
  48. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/financial/risk.py +0 -0
  49. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/financial/sector.py +0 -0
  50. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/financial/strategist.py +0 -0
  51. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/financial/stripe_revenue.py +0 -0
  52. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/financial/synthesis.py +0 -0
  53. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/financial/technical.py +0 -0
  54. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/orchestrator.py +0 -0
  55. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/portfolio_agent.py +0 -0
  56. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/realty/__init__.py +0 -0
  57. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/realty/asset_diagnosis.py +0 -0
  58. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/realty/business_match.py +0 -0
  59. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/realty/cashflow_verify.py +0 -0
  60. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/realty/contract_rules.py +0 -0
  61. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/realty/energy_anomaly.py +0 -0
  62. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/realty/exit_settlement.py +0 -0
  63. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/realty/fulfillment_risk.py +0 -0
  64. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/realty/ops_optimize.py +0 -0
  65. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/realty/revenue_share.py +0 -0
  66. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/registry.py +0 -0
  67. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/signal_scheme.py +0 -0
  68. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/sports/__init__.py +0 -0
  69. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/sports/football_agent.py +0 -0
  70. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/supervisor.py +0 -0
  71. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/team.py +0 -0
  72. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/warehouse/__init__.py +0 -0
  73. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/warehouse/contracts.py +0 -0
  74. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/warehouse/dashboard.py +0 -0
  75. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/warehouse/fulfillment_leadtime.py +0 -0
  76. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/warehouse/inbound_exceptions.py +0 -0
  77. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/warehouse/inventory_health.py +0 -0
  78. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/warehouse/local_run.py +0 -0
  79. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/warehouse/local_snapshot.py +0 -0
  80. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/warehouse/logistics_cost.py +0 -0
  81. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/warehouse/logistics_sync.py +0 -0
  82. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/agents/warehouse/workflow.py +0 -0
  83. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/aliyun_data_client.py +0 -0
  84. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/README.md +0 -0
  85. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/__init__.py +0 -0
  86. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/channels/__init__.py +0 -0
  87. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/channels/approvals.py +0 -0
  88. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/channels/conversation.py +0 -0
  89. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/channels/digest.py +0 -0
  90. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/channels/intake.py +0 -0
  91. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/channels/registry.py +0 -0
  92. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/channels/tradingview.py +0 -0
  93. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/README.md +0 -0
  94. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/__init__.py +0 -0
  95. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/_optional.py +0 -0
  96. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/bootstrap.py +0 -0
  97. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/broker_render.py +0 -0
  98. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/codegen_paths.py +0 -0
  99. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/__init__.py +0 -0
  100. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/_business_render.py +0 -0
  101. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/_ui.py +0 -0
  102. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/analysis_cmds.py +0 -0
  103. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/ashare_prediction_cmds.py +0 -0
  104. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/auth_cmds.py +0 -0
  105. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/backtest_cmds.py +0 -0
  106. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/broker_cmds.py +0 -0
  107. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/business_workflow_cmds.py +0 -0
  108. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/canvas_cmds.py +0 -0
  109. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/catalog.py +0 -0
  110. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/core_cmds.py +0 -0
  111. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/data_cmds.py +0 -0
  112. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/diagnostic_cmds.py +0 -0
  113. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/diagnostic_ops_cmds.py +0 -0
  114. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/file_cmds.py +0 -0
  115. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/finance_service_cmds.py +0 -0
  116. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/fx_commodity_cmds.py +0 -0
  117. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/market.py +0 -0
  118. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/market_cmds.py +0 -0
  119. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/market_context.py +0 -0
  120. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/market_render.py +0 -0
  121. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/model_cmds.py +0 -0
  122. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/ops_cmds.py +0 -0
  123. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/orchestrator_cmds.py +0 -0
  124. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/pdf_export_cmds.py +0 -0
  125. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/portfolio_cmds.py +0 -0
  126. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/report.py +0 -0
  127. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/scaffold_templates.py +0 -0
  128. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/session_cmds.py +0 -0
  129. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/session_ux_cmds.py +0 -0
  130. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/team.py +0 -0
  131. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/team_render.py +0 -0
  132. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/ui_cmds.py +0 -0
  133. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/warehouse_cmds.py +0 -0
  134. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/workflow_cmds.py +0 -0
  135. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/commands/workspace_cmds.py +0 -0
  136. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/config_paths.py +0 -0
  137. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/config_store.py +0 -0
  138. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/constants.py +0 -0
  139. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/context.py +0 -0
  140. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/deterministic.py +0 -0
  141. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/direct.py +0 -0
  142. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/finance_service_catalog.py +0 -0
  143. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/football_reports.py +0 -0
  144. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/github_app_auth.py +0 -0
  145. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/google_login.py +0 -0
  146. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/handlers/__init__.py +0 -0
  147. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/handlers/broker_handlers.py +0 -0
  148. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/handlers/chart_handlers.py +0 -0
  149. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/handlers/market_handlers.py +0 -0
  150. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/handlers/realty_handlers.py +0 -0
  151. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/handlers/sports_handlers.py +0 -0
  152. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/handlers/strategy_advice.py +0 -0
  153. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/helpers.py +0 -0
  154. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/hooks.py +0 -0
  155. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/i18n.py +0 -0
  156. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/intent.py +0 -0
  157. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/intent_router.py +0 -0
  158. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/intent_signals.py +0 -0
  159. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/lifecycle_hooks.py +0 -0
  160. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/local_tool_schemas.py +0 -0
  161. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/main.py +0 -0
  162. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/market_metadata.py +0 -0
  163. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/market_universe.py +0 -0
  164. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/message_processing.py +0 -0
  165. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/model_catalog.py +0 -0
  166. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/pdf_report.py +0 -0
  167. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/plan_mode.py +0 -0
  168. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/plotly_html.py +0 -0
  169. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/prediction_feedback.py +0 -0
  170. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/preflight.py +0 -0
  171. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/project_aria.py +0 -0
  172. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/prompt_assembly.py +0 -0
  173. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/prompts/__init__.py +0 -0
  174. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/prompts/coding.py +0 -0
  175. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/prompts/select.py +0 -0
  176. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/prompts/system_prompts.py +0 -0
  177. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/prompts/ui.py +0 -0
  178. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/provider_endpoints.py +0 -0
  179. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/provider_keys.py +0 -0
  180. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/providers/__init__.py +0 -0
  181. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/providers/base.py +0 -0
  182. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/providers/chat_routing.py +0 -0
  183. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/providers/collaboration.py +0 -0
  184. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/providers/llm/__init__.py +0 -0
  185. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/providers/llm/offline_responses.py +0 -0
  186. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/providers/llm/ollama_stream.py +0 -0
  187. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/providers/llm/response_cache.py +0 -0
  188. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/providers/llm/sse_stream.py +0 -0
  189. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/providers/runtime_bridge.py +0 -0
  190. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/providers/vertexai_stream.py +0 -0
  191. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/runtime_consumer.py +0 -0
  192. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/sandbox.py +0 -0
  193. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/session_export.py +0 -0
  194. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/session_jsonl.py +0 -0
  195. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/session_store.py +0 -0
  196. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/skills_catalog.py +0 -0
  197. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/todo_tracker.py +0 -0
  198. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/tool_executor.py +0 -0
  199. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/tool_registry.py +0 -0
  200. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/tool_scope.py +0 -0
  201. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/tools/__init__.py +0 -0
  202. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/tools/context.py +0 -0
  203. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/tools/file_tools.py +0 -0
  204. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/tools/market_tools.py +0 -0
  205. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/tools/notebook_tools.py +0 -0
  206. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/tools/system_tools.py +0 -0
  207. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/tools/write_tools.py +0 -0
  208. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/tradingview_bridge.py +0 -0
  209. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/turn_planning.py +0 -0
  210. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/update_check.py +0 -0
  211. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/utils/__init__.py +0 -0
  212. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/cli/utils/market_detect.py +0 -0
  213. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/daemon/README.md +0 -0
  214. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/vscode/README.md +0 -0
  215. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/apps/vscode/package.json +0 -0
  216. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/aria_cli.py +0 -0
  217. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/aria_mcp_server.py +0 -0
  218. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/aria_relay_client.py +0 -0
  219. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/aria_telegram_bot.py +0 -0
  220. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ariarc.py +0 -0
  221. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/artifacts.py +0 -0
  222. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/backtest_engine.py +0 -0
  223. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/backtest_report.py +0 -0
  224. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/__init__.py +0 -0
  225. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/automation.py +0 -0
  226. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/base.py +0 -0
  227. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/capabilities.py +0 -0
  228. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/cn/__init__.py +0 -0
  229. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/cn/easytrader_broker.py +0 -0
  230. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/cn/futu_broker.py +0 -0
  231. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/cn/longbridge_broker.py +0 -0
  232. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/cn/tiger_broker.py +0 -0
  233. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/cn/xtquant_broker.py +0 -0
  234. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/config.py +0 -0
  235. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/intl/__init__.py +0 -0
  236. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/intl/alpaca_broker.py +0 -0
  237. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/intl/ibkr_broker.py +0 -0
  238. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/intl/trading212_broker.py +0 -0
  239. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/intl/webull_broker.py +0 -0
  240. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/paper_broker.py +0 -0
  241. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/planning.py +0 -0
  242. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/registry.py +0 -0
  243. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/brokers/trading.py +0 -0
  244. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/canva_client.py +0 -0
  245. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/change_store.py +0 -0
  246. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/clients/__init__.py +0 -0
  247. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/clients/aliyun_data_client.py +0 -0
  248. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/clients/canva_client.py +0 -0
  249. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/clients/figma_client.py +0 -0
  250. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/clients/football_data_client.py +0 -0
  251. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/clients/kling_video_client.py +0 -0
  252. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/clients/market_data_client.py +0 -0
  253. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/clients/openai_image_client.py +0 -0
  254. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/clients/runway_video_client.py +0 -0
  255. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/clients/warehouse_erp_client.py +0 -0
  256. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/cloud_memory.py +0 -0
  257. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/command_safety.py +0 -0
  258. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/computer_use_tools.py +0 -0
  259. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/dashboard_generator.py +0 -0
  260. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/data_analysis_tools.py +0 -0
  261. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/data_cleaner.py +0 -0
  262. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/data_service.py +0 -0
  263. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/datasources/__init__.py +0 -0
  264. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/datasources/base.py +0 -0
  265. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/datasources/router.py +0 -0
  266. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/datasources/sources/__init__.py +0 -0
  267. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/datasources/sources/akshare_source.py +0 -0
  268. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/datasources/sources/alpha_vantage_source.py +0 -0
  269. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/datasources/sources/edgar_source.py +0 -0
  270. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/datasources/sources/finnhub_source.py +0 -0
  271. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/datasources/sources/fred_source.py +0 -0
  272. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/datasources/sources/tushare_source.py +0 -0
  273. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/datasources/sources/web_scraper_source.py +0 -0
  274. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/datasources/sources/world_bank_source.py +0 -0
  275. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/datasources/sources/yfinance_source.py +0 -0
  276. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/demo_player.py +0 -0
  277. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/doctor.py +0 -0
  278. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/domain/__init__.py +0 -0
  279. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/domain/backtest_engine.py +0 -0
  280. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/domain/backtest_report.py +0 -0
  281. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/domain/finance_formulas.py +0 -0
  282. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/domain/portfolio_ledger.py +0 -0
  283. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/domain/strategy_vault.py +0 -0
  284. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/evals/__init__.py +0 -0
  285. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/evals/harness.py +0 -0
  286. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/evals/runner.py +0 -0
  287. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/external_agent_runner.py +0 -0
  288. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/figma_client.py +0 -0
  289. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/file_analysis_tools.py +0 -0
  290. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/finance_formulas.py +0 -0
  291. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/football_data_client.py +0 -0
  292. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/image_gen_tools.py +0 -0
  293. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/intent_classifier.py +0 -0
  294. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/kling_video_client.py +0 -0
  295. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/licensing.py +0 -0
  296. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/local_finance_tools.py +0 -0
  297. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/local_image_provider.py +0 -0
  298. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/local_llm_provider.py +0 -0
  299. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/macro_tools.py +0 -0
  300. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/markdown_pdf.py +0 -0
  301. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/market_data_client.py +0 -0
  302. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/mcp_client.py +0 -0
  303. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/memory_manager.py +0 -0
  304. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/model_capability.py +0 -0
  305. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/notification_tools.py +0 -0
  306. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/openai_image_client.py +0 -0
  307. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/__init__.py +0 -0
  308. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/adk_bridge/__init__.py +0 -0
  309. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/adk_bridge/code_review_tools.py +0 -0
  310. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/adk_bridge/market_tools.py +0 -0
  311. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_agents/__init__.py +0 -0
  312. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_agents/manifest.py +0 -0
  313. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_core/__init__.py +0 -0
  314. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_core/architecture.py +0 -0
  315. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_core/export.py +0 -0
  316. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_core/manifest.py +0 -0
  317. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_core/paths.py +0 -0
  318. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_core/secure_file.py +0 -0
  319. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_infra/__init__.py +0 -0
  320. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_infra/arthera.py +0 -0
  321. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_infra/doctor.py +0 -0
  322. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_infra/product.py +0 -0
  323. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_mcp/__init__.py +0 -0
  324. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_mcp/bridge.py +0 -0
  325. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_mcp/circuit.py +0 -0
  326. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_mcp/config.py +0 -0
  327. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_mcp/installer.py +0 -0
  328. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_mcp/server.py +0 -0
  329. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_mcp/tools.py +0 -0
  330. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_sdk/__init__.py +0 -0
  331. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_sdk/client.py +0 -0
  332. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_sdk/providers.py +0 -0
  333. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_sdk/streaming.py +0 -0
  334. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_sdk/types.py +0 -0
  335. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_services/__init__.py +0 -0
  336. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_services/cache.py +0 -0
  337. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_services/context.py +0 -0
  338. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_services/context_checkpoints.py +0 -0
  339. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_services/data.py +0 -0
  340. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_services/provider_health.py +0 -0
  341. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_services/references.py +0 -0
  342. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_services/registry.py +0 -0
  343. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_services/research_protocol.py +0 -0
  344. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_services/research_quality.py +0 -0
  345. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_services/settings.py +0 -0
  346. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_services/usage.py +0 -0
  347. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_skills/__init__.py +0 -0
  348. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_skills/catalog.py +0 -0
  349. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_skills/loader.py +0 -0
  350. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_skills/registry.py +0 -0
  351. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_tools/__init__.py +0 -0
  352. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_tools/financial/__init__.py +0 -0
  353. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_tools/financial/_paths.py +0 -0
  354. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_tools/financial/compliance.py +0 -0
  355. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_tools/financial/factors.py +0 -0
  356. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_tools/financial/risk_tools.py +0 -0
  357. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_tools/financial/strategy.py +0 -0
  358. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/aria_tools/registry.py +0 -0
  359. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/__init__.py +0 -0
  360. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/_namespace.py +0 -0
  361. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/backtest/__init__.py +0 -0
  362. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/backtest/core.py +0 -0
  363. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/backtest/engine.py +0 -0
  364. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/portfolio/__init__.py +0 -0
  365. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/portfolio/optimizer.py +0 -0
  366. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/sports/__init__.py +0 -0
  367. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/sports/calibrator.py +0 -0
  368. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/sports/dixon_coles.py +0 -0
  369. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/sports/elo.py +0 -0
  370. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/sports/form.py +0 -0
  371. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/sports/h2h.py +0 -0
  372. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/sports/ml_model.py +0 -0
  373. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/sports/predictor.py +0 -0
  374. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/sports/tracker.py +0 -0
  375. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/stochastic/__init__.py +0 -0
  376. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +0 -0
  377. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/stochastic/ito_calculus.py +0 -0
  378. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/stochastic/kelly_criterion.py +0 -0
  379. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +0 -0
  380. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/stochastic/options_pricing.py +0 -0
  381. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packages/quant_engine/stochastic/stochastic_processes.py +0 -0
  382. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packs/__init__.py +0 -0
  383. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packs/base.py +0 -0
  384. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packs/finance/__init__.py +0 -0
  385. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packs/logistics/__init__.py +0 -0
  386. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packs/payments/__init__.py +0 -0
  387. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packs/realty/__init__.py +0 -0
  388. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packs/registry.py +0 -0
  389. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/packs/rules.py +0 -0
  390. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/plan_utils.py +0 -0
  391. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/plugin_loader.py +0 -0
  392. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/portfolio_ledger.py +0 -0
  393. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/preview_server.py +0 -0
  394. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/privacy/__init__.py +0 -0
  395. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/privacy/feedback.py +0 -0
  396. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/project_review.py +0 -0
  397. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/project_review_api.py +0 -0
  398. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/project_review_server.py +0 -0
  399. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/project_tools.py +0 -0
  400. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/providers/__init__.py +0 -0
  401. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/providers/llm/__init__.py +0 -0
  402. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/providers/llm/anthropic.py +0 -0
  403. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/providers/llm/autoconfig.py +0 -0
  404. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/providers/llm/base.py +0 -0
  405. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/providers/llm/custom.py +0 -0
  406. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/providers/llm/ollama.py +0 -0
  407. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/providers/llm/openai_compat.py +0 -0
  408. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/providers/llm/registry.py +0 -0
  409. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/providers/local_image_provider.py +0 -0
  410. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/providers/local_llm_provider.py +0 -0
  411. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/realty_data_tools.py +0 -0
  412. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/report_exporters.py +0 -0
  413. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/report_generator.py +0 -0
  414. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/__init__.py +0 -0
  415. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/acceptance.py +0 -0
  416. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/agent_loop.py +0 -0
  417. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/approval.py +0 -0
  418. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/budget.py +0 -0
  419. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/checkpoints.py +0 -0
  420. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/crash_report.py +0 -0
  421. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/events.py +0 -0
  422. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/gateway.py +0 -0
  423. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/lsp.py +0 -0
  424. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/orchestrator.py +0 -0
  425. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/repo_map.py +0 -0
  426. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/run_state.py +0 -0
  427. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/run_store.py +0 -0
  428. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/self_healing.py +0 -0
  429. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/subagent.py +0 -0
  430. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/task_ledger.py +0 -0
  431. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/task_orchestrator.py +0 -0
  432. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/tool_executor.py +0 -0
  433. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/tool_policy.py +0 -0
  434. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runtime/worktrees.py +0 -0
  435. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/runway_video_client.py +0 -0
  436. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/safety/__init__.py +0 -0
  437. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/safety/permissions.py +0 -0
  438. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/safety/service.py +0 -0
  439. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/setup_wizard.py +0 -0
  440. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/spreadsheet_tools.py +0 -0
  441. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/strategy_vault.py +0 -0
  442. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/__init__.py +0 -0
  443. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/artifact_tools.py +0 -0
  444. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/broker_tools.py +0 -0
  445. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/build_quant_engine.py +0 -0
  446. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/code_audit_tools.py +0 -0
  447. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/computer_use_tools.py +0 -0
  448. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/data_analysis_tools.py +0 -0
  449. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/enterprise_finance_tools.py +0 -0
  450. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/extended_tools.py +0 -0
  451. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/file_analysis_tools.py +0 -0
  452. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/image_gen_tools.py +0 -0
  453. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/local_finance_tools.py +0 -0
  454. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/logistics_carriers.py +0 -0
  455. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/logistics_inventory.py +0 -0
  456. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/logistics_io.py +0 -0
  457. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/logistics_tenancy.py +0 -0
  458. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/logistics_tools.py +0 -0
  459. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/macro_tools.py +0 -0
  460. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/notification_tools.py +0 -0
  461. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/project_tools.py +0 -0
  462. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/realty_data_tools.py +0 -0
  463. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/spreadsheet_tools.py +0 -0
  464. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/tools/stripe_tools.py +0 -0
  465. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ui/__init__.py +0 -0
  466. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ui/banner.py +0 -0
  467. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ui/completer.py +0 -0
  468. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ui/console.py +0 -0
  469. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ui/image_render.py +0 -0
  470. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ui/input_box.py +0 -0
  471. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ui/picker.py +0 -0
  472. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ui/render/__init__.py +0 -0
  473. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ui/render/finance.py +0 -0
  474. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ui/render/market.py +0 -0
  475. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ui/render/output.py +0 -0
  476. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ui/render/responsive.py +0 -0
  477. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ui/render/team.py +0 -0
  478. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ui/robot.py +0 -0
  479. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/ui/startup_dashboard.py +0 -0
  480. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/utils/vscode_uri.py +0 -0
  481. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/video_analysis.py +0 -0
  482. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/video_editor.py +0 -0
  483. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/workspace/__init__.py +0 -0
  484. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/workspace/files.py +0 -0
  485. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/workspace/verify.py +0 -0
  486. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/workspace_changes.py +0 -0
  487. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/workspace_context.py +0 -0
  488. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/workspace_service.py +0 -0
  489. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code/workspace_tools.py +0 -0
  490. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code.egg-info/dependency_links.txt +0 -0
  491. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code.egg-info/entry_points.txt +0 -0
  492. {aria_code-0.66.0 → aria_code-0.67.0}/src/aria_code.egg-info/top_level.txt +0 -0
  493. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_adk_market_tools.py +0 -0
  494. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_agent_team_fallback.py +0 -0
  495. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_analyze_file_tool.py +0 -0
  496. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_architecture_ledger_is_true.py +0 -0
  497. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_architecture_report.py +0 -0
  498. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_aria_cli_core.py +0 -0
  499. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_aria_mcp_server.py +0 -0
  500. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_aria_sdk.py +0 -0
  501. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_artifact_publishing.py +0 -0
  502. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_artifacts_and_reports.py +0 -0
  503. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_ashare_prediction_cmds.py +0 -0
  504. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_backtest_cmds.py +0 -0
  505. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_backtest_engine.py +0 -0
  506. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_backtest_report.py +0 -0
  507. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_binary_bundles_runtime_imports.py +0 -0
  508. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_broken_akshare_is_optional.py +0 -0
  509. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_broker_automation.py +0 -0
  510. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_broker_chat_confirm_gate.py +0 -0
  511. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_broker_planning.py +0 -0
  512. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_broker_safety.py +0 -0
  513. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_broker_tools.py +0 -0
  514. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_budget.py +0 -0
  515. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_business_workflow_cmds.py +0 -0
  516. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_canva_client.py +0 -0
  517. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_canvas_cmds.py +0 -0
  518. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_card_approvals.py +0 -0
  519. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_channel_intake.py +0 -0
  520. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_channels.py +0 -0
  521. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_chart_handlers.py +0 -0
  522. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_chat_bots_fail_closed.py +0 -0
  523. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_chat_routing.py +0 -0
  524. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_ci_security_workflow.py +0 -0
  525. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_cli_app_split.py +0 -0
  526. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_cli_bootstrap.py +0 -0
  527. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_cli_config_store.py +0 -0
  528. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_cli_lifecycle_hooks.py +0 -0
  529. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_cli_runtime_consumer.py +0 -0
  530. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_cli_tool_executor_module.py +0 -0
  531. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_cloud_memory.py +0 -0
  532. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_code_audit_tools.py +0 -0
  533. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_code_review_agent.py +0 -0
  534. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_codegen_output.py +0 -0
  535. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_coder_tester_self_healing.py +0 -0
  536. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_coder_tool_safety.py +0 -0
  537. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_collaboration.py +0 -0
  538. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_command_loggers.py +0 -0
  539. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_command_safety.py +0 -0
  540. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_completions_builder.py +0 -0
  541. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_config_paths.py +0 -0
  542. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_configured_provider.py +0 -0
  543. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_container_entrypoint.py +0 -0
  544. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_container_entrypoints.py +0 -0
  545. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_context_checkpoints.py +0 -0
  546. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_context_references.py +0 -0
  547. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_context_service.py +0 -0
  548. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_conversation_core.py +0 -0
  549. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_crash_report.py +0 -0
  550. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_credential_file_permissions.py +0 -0
  551. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_custom_providers.py +0 -0
  552. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_daemon_gateway_config.py +0 -0
  553. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_dashboard_generator.py +0 -0
  554. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_data_service.py +0 -0
  555. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_data_service_imports.py +0 -0
  556. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_datasource_routing.py +0 -0
  557. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_deep_analysis.py +0 -0
  558. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_degrades_without_quant_engine.py +0 -0
  559. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_dispatcher_pins_match_the_release.py +0 -0
  560. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_doctor.py +0 -0
  561. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_doctor_describes_the_current_install.py +0 -0
  562. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_doctor_npm_scope.py +0 -0
  563. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_engine_boundary.py +0 -0
  564. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_enterprise_tool_honesty.py +0 -0
  565. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_env_switch_docs.py +0 -0
  566. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_evals_harness.py +0 -0
  567. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_extended_tools.py +0 -0
  568. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_feishu_swarm_config.py +0 -0
  569. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_finance_renderers.py +0 -0
  570. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_finance_service_catalog.py +0 -0
  571. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_first_run_works.py +0 -0
  572. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_football_agent.py +0 -0
  573. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_football_prediction_output.py +0 -0
  574. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_google_cloud_routing.py +0 -0
  575. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_google_login.py +0 -0
  576. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_google_search_provider.py +0 -0
  577. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_headless_is_agentic.py +0 -0
  578. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_image_gen_tools.py +0 -0
  579. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_image_inputs.py +0 -0
  580. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_import_graph_budget.py +0 -0
  581. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_intent_router.py +0 -0
  582. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_intent_signals.py +0 -0
  583. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_kling_video_client.py +0 -0
  584. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_lazy_rebind.py +0 -0
  585. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_legacy_module_imports.py +0 -0
  586. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_license_consistency.py +0 -0
  587. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_licensing.py +0 -0
  588. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_local_image_provider.py +0 -0
  589. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_logistics_3pl.py +0 -0
  590. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_logistics_and_finance_agents.py +0 -0
  591. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_lsp.py +0 -0
  592. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_markdown_pdf.py +0 -0
  593. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_market_data_client.py +0 -0
  594. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_market_history_inheritance.py +0 -0
  595. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_market_history_tool.py +0 -0
  596. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_market_symbol_extraction.py +0 -0
  597. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_market_universe.py +0 -0
  598. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_mcp_circuit.py +0 -0
  599. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_mcp_client.py +0 -0
  600. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_model_capability_registry.py +0 -0
  601. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_model_choice_is_the_users.py +0 -0
  602. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_model_selection_state.py +0 -0
  603. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_native_binary_entrypoints.py +0 -0
  604. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_native_installer.py +0 -0
  605. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_new_modules.py +0 -0
  606. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_no_hardcoded_developer_paths.py +0 -0
  607. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_no_uncommitted_imports.py +0 -0
  608. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_ollama_stream_imports.py +0 -0
  609. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_ollama_stream_tools.py +0 -0
  610. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_openai_image_client.py +0 -0
  611. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_operations_suite.py +0 -0
  612. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_output_rendering.py +0 -0
  613. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_packages_facade.py +0 -0
  614. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_packaging_constraints.py +0 -0
  615. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_packaging_manifest.py +0 -0
  616. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_packs_domains.py +0 -0
  617. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_pdf_report.py +0 -0
  618. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_pick_best_installed_model.py +0 -0
  619. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_plan_mode.py +0 -0
  620. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_platform_package_assembly.py +0 -0
  621. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_platform_packages.py +0 -0
  622. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_plotly_html_output.py +0 -0
  623. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_portfolio_ledger.py +0 -0
  624. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_post_turn_context_decision.py +0 -0
  625. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_preflight.py +0 -0
  626. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_preview_server.py +0 -0
  627. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_privacy_feedback.py +0 -0
  628. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_project_aria.py +0 -0
  629. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_project_review.py +0 -0
  630. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_prompt_assembly.py +0 -0
  631. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_prompt_selection.py +0 -0
  632. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_provider_autoconfig.py +0 -0
  633. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_provider_error_messages.py +0 -0
  634. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_provider_integration.py +0 -0
  635. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_provider_registry.py +0 -0
  636. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_public_service_status.py +0 -0
  637. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_quant_engine_namespace.py +0 -0
  638. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_rebind_contract.py +0 -0
  639. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_rebind_namespace_contract.py +0 -0
  640. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_relay_event_verification.py +0 -0
  641. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_release_chain.py +0 -0
  642. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_release_commit_identity.py +0 -0
  643. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_release_push_is_atomic.py +0 -0
  644. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_release_reaches_the_registries.py +0 -0
  645. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_release_verification_waits.py +0 -0
  646. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_release_workflow_permissions.py +0 -0
  647. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_report_charts.py +0 -0
  648. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_report_generator.py +0 -0
  649. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_research_protocol.py +0 -0
  650. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_research_quality.py +0 -0
  651. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_responsive_rendering.py +0 -0
  652. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_root_module_budget.py +0 -0
  653. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_rsi_without_pandas_ta.py +0 -0
  654. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_runtime_acceptance.py +0 -0
  655. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_runtime_agent_loop.py +0 -0
  656. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_runtime_approval.py +0 -0
  657. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_runtime_bridge.py +0 -0
  658. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_runtime_bridge_fallback.py +0 -0
  659. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_runtime_checkpoints.py +0 -0
  660. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_runtime_gateway.py +0 -0
  661. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_runtime_repo_map.py +0 -0
  662. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_runtime_run_store.py +0 -0
  663. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_runtime_tool_executor.py +0 -0
  664. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_runtime_worktrees.py +0 -0
  665. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_runway_video_client.py +0 -0
  666. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_safety_permissions.py +0 -0
  667. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_safety_service.py +0 -0
  668. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_safety_service_adoption.py +0 -0
  669. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_service_diagnostics_security.py +0 -0
  670. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_session_search.py +0 -0
  671. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_settings_service.py +0 -0
  672. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_shipper_digest.py +0 -0
  673. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_single_import_root.py +0 -0
  674. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_skill_agent_binding.py +0 -0
  675. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_skill_catalog.py +0 -0
  676. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_skill_loader.py +0 -0
  677. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_spreadsheet_tools.py +0 -0
  678. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_sse_stream_contract.py +0 -0
  679. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_startup_dashboard.py +0 -0
  680. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_streaming_pipeline.py +0 -0
  681. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_stripe_agent.py +0 -0
  682. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_subagent.py +0 -0
  683. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_supervisor_routing.py +0 -0
  684. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_system_prompts.py +0 -0
  685. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_system_tools_output.py +0 -0
  686. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_task_orchestrator.py +0 -0
  687. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_team_synthesis.py +0 -0
  688. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_tls_trust_store.py +0 -0
  689. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_tool_policy.py +0 -0
  690. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_tool_scope.py +0 -0
  691. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_trading_service.py +0 -0
  692. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_tradingview_bridge.py +0 -0
  693. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_turn_planning.py +0 -0
  694. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_ui_completer_references.py +0 -0
  695. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_ui_console_theme.py +0 -0
  696. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_ui_input_box.py +0 -0
  697. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_ui_robot_banner.py +0 -0
  698. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_verification_hint.py +0 -0
  699. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_verification_policy.py +0 -0
  700. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_version_consistency.py +0 -0
  701. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_version_counter.py +0 -0
  702. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_video_analysis.py +0 -0
  703. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_video_editor.py +0 -0
  704. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_vscode_mcp.py +0 -0
  705. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_warehouse_agents.py +0 -0
  706. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_warehouse_cli_registration.py +0 -0
  707. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_warehouse_erp_client.py +0 -0
  708. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_warehouse_workflow.py +0 -0
  709. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_wheel_is_installable.py +0 -0
  710. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_workspace_changes.py +0 -0
  711. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_workspace_context.py +0 -0
  712. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_workspace_files.py +0 -0
  713. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_workspace_scope.py +0 -0
  714. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_workspace_service.py +0 -0
  715. {aria_code-0.66.0 → aria_code-0.67.0}/tests/test_workspace_verify.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aria-code
3
- Version: 0.66.0
3
+ Version: 0.67.0
4
4
  Summary: AI coding and research workspace with optional finance and connected-domain tools
5
5
  License: Apache-2.0
6
6
  Project-URL: Homepage, https://github.com/artheras/aria-code
@@ -108,6 +108,9 @@ Requires-Dist: pytest-asyncio>=0.23.7; extra == "dev"
108
108
  Requires-Dist: pytest-timeout>=2.3.0; extra == "dev"
109
109
  Requires-Dist: ruff>=0.4.0; extra == "dev"
110
110
  Requires-Dist: mypy>=1.10.0; extra == "dev"
111
+ Requires-Dist: fastapi>=0.110.0; extra == "dev"
112
+ Requires-Dist: uvicorn>=0.29.0; extra == "dev"
113
+ Requires-Dist: python-multipart>=0.0.9; extra == "dev"
111
114
  Provides-Extra: full
112
115
  Requires-Dist: google-genai>=1.0.0; extra == "full"
113
116
  Requires-Dist: akshare>=1.14.68; extra == "full"
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "aria-code"
7
- version = "0.66.0"
7
+ version = "0.67.0"
8
8
  description = "AI coding and research workspace with optional finance and connected-domain tools"
9
9
  readme = "README.md"
10
10
  license = { text = "Apache-2.0" }
@@ -156,6 +156,12 @@ dev = [
156
156
  "pytest-timeout>=2.3.0",
157
157
  "ruff>=0.4.0",
158
158
  "mypy>=1.10.0",
159
+ # The relay server's and the project-review service's tests. Without
160
+ # these, importorskip skipped them all in CI — the relay's account-hijack
161
+ # regressions included — and nobody noticed.
162
+ "fastapi>=0.110.0",
163
+ "uvicorn>=0.29.0",
164
+ "python-multipart>=0.0.9",
159
165
  ]
160
166
 
161
167
  # ── Full feature set (what the bootstrap installers install by default) ────────
@@ -17,4 +17,4 @@ from __future__ import annotations
17
17
 
18
18
  __all__ = ["__version__"]
19
19
 
20
- __version__ = "0.66.0"
20
+ __version__ = "0.67.0"
@@ -84,3 +84,14 @@ A channel renders the request with two buttons and calls
84
84
  `purchase_order_draft`, writes a CSV to `ARIA_APPROVAL_OUTBOX/<shipper>/` for
85
85
  the 3PL's purchasing system: Aria has no integration that places orders, and
86
86
  does not pretend to.
87
+
88
+ ## Relay mode
89
+
90
+ In relay mode the user's machine has no Feishu app credentials — the app
91
+ secret stays on the relay — so `aria_feishu_bot._send_message` hands every
92
+ message back over the relay WebSocket and the relay sends it. The relay
93
+ accepts a send only where the client has standing: a reply to a message it
94
+ forwarded to that client (within an hour), or a post to a chat that client's
95
+ bound user has spoken to the bot in; text or cards, rate-limited. A press on a
96
+ card is routed to the client that posted the card, which holds the approval.
97
+ Attachments still need the app's credentials and are declined with a message.
@@ -1089,9 +1089,11 @@ async def _run_shipper_digests() -> None:
1089
1089
  from apps.channels.digest import run_digests
1090
1090
 
1091
1091
  senders = {}
1092
- if os.environ.get("FEISHU_APP_ID") and os.environ.get("FEISHU_APP_SECRET"):
1093
- from aria_feishu_bot import send_digest_card
1094
- senders["feishu"] = send_digest_card
1092
+ import aria_feishu_bot
1093
+ # With the app's credentials (self-hosted), or through the relay client
1094
+ # this daemon runs in relay mode — the bot knows which it has.
1095
+ if aria_feishu_bot.can_send():
1096
+ senders["feishu"] = aria_feishu_bot.send_digest_card
1095
1097
  report = await run_digests(ConversationStore(), senders)
1096
1098
  for line in report:
1097
1099
  logger.info("shipper digest %s: %s", line["conversation"], line["status"])
@@ -157,6 +157,48 @@ async def _get_access_token() -> Optional[str]:
157
157
 
158
158
  # ── Send message helpers ───────────────────────────────────────────────────────
159
159
 
160
+ # Set by the relay client while it is connected. In relay mode this machine has
161
+ # no Feishu app credentials — by design, the app secret stays on the relay — so
162
+ # every message goes back over the WebSocket and the relay sends it. Before
163
+ # 2026-10-03 nothing did this, and relay mode silently dropped every answer.
164
+ _RELAY_SEND = None
165
+
166
+
167
+ def set_relay_sender(sender) -> None:
168
+ """Route sends through the relay: sender(request) -> Feishu-style result dict."""
169
+ global _RELAY_SEND
170
+ _RELAY_SEND = sender
171
+
172
+
173
+ def can_send() -> bool:
174
+ """Whether this process can deliver a message at all."""
175
+ has_app = bool(os.environ.get("FEISHU_APP_ID") and os.environ.get("FEISHU_APP_SECRET"))
176
+ return has_app or _RELAY_SEND is not None
177
+
178
+
179
+ async def _send_message(op: str, target: str, msg_type: str, content: str,
180
+ receive_id_type: str = "chat_id") -> Optional[dict]:
181
+ """The one place a message leaves: directly with app credentials, else via the relay.
182
+
183
+ op "reply" answers message `target`; op "send" posts to chat `target`.
184
+ """
185
+ token = await _get_access_token()
186
+ if token:
187
+ if op == "reply":
188
+ return await _feishu_post(f"{_FEISHU_API}/im/v1/messages/{target}/reply", token,
189
+ {"msg_type": msg_type, "content": content})
190
+ return await _feishu_post(f"{_FEISHU_API}/im/v1/messages?receive_id_type={receive_id_type}",
191
+ token, {"receive_id": target, "msg_type": msg_type, "content": content})
192
+ if _RELAY_SEND is not None:
193
+ try:
194
+ return await _RELAY_SEND({"op": op, "target": target, "msg_type": msg_type,
195
+ "content": content, "receive_id_type": receive_id_type})
196
+ except Exception as exc:
197
+ logger.warning("relay send failed: %s", exc)
198
+ return None
199
+ logger.error("cannot send: no Feishu app credentials and no relay connection")
200
+ return None
201
+
160
202
  async def _feishu_post(url: str, token: str, payload: dict) -> Optional[dict]:
161
203
  """POST to Feishu API; log the response code on error."""
162
204
  try:
@@ -187,16 +229,8 @@ async def reply_text(message_id: str, text: str) -> None:
187
229
  if not message_id:
188
230
  logger.error("reply_text: empty message_id — cannot reply")
189
231
  return
190
- token = await _get_access_token()
191
- if not token:
192
- logger.error("reply_text: no access token")
193
- return
194
232
  logger.info("reply_text → message_id=%s len=%d", message_id, len(text))
195
- await _feishu_post(
196
- f"{_FEISHU_API}/im/v1/messages/{message_id}/reply",
197
- token,
198
- {"msg_type": "text", "content": json.dumps({"text": text[:3000]})},
199
- )
233
+ await _send_message("reply", message_id, "text", json.dumps({"text": text[:3000]}))
200
234
 
201
235
 
202
236
  async def reply_card(message_id: str, title: str, body: str,
@@ -205,10 +239,6 @@ async def reply_card(message_id: str, title: str, body: str,
205
239
  if not message_id:
206
240
  logger.error("reply_card: empty message_id — cannot reply")
207
241
  return
208
- token = await _get_access_token()
209
- if not token:
210
- await reply_text(message_id, f"【{title}】\n{body}")
211
- return
212
242
  elements = _build_card_elements(body, footer)
213
243
  card = {
214
244
  "config": {"wide_screen_mode": True},
@@ -216,11 +246,7 @@ async def reply_card(message_id: str, title: str, body: str,
216
246
  "elements": elements,
217
247
  }
218
248
  logger.info("reply_card → message_id=%s title=%s", message_id, title[:40])
219
- result = await _feishu_post(
220
- f"{_FEISHU_API}/im/v1/messages/{message_id}/reply",
221
- token,
222
- {"msg_type": "interactive", "content": json.dumps(card)},
223
- )
249
+ result = await _send_message("reply", message_id, "interactive", json.dumps(card))
224
250
  # If card failed, fall back to plain text
225
251
  if result and result.get("code") != 0:
226
252
  logger.info("reply_card: card failed (code %s), falling back to text", result.get("code"))
@@ -280,20 +306,13 @@ def _build_card_elements(body: str, footer: str = "") -> list:
280
306
  async def _reply_card_raw(message_id: str, title: str, body: str,
281
307
  color: str = "blue", footer: str = "") -> Optional[dict]:
282
308
  """Reply with a card; return raw API response dict."""
283
- token = await _get_access_token()
284
- if not token:
285
- return None
286
309
  elements = _build_card_elements(body, footer)
287
310
  card = {
288
311
  "config": {"wide_screen_mode": True},
289
312
  "header": {"title": {"tag": "plain_text", "content": title}, "template": color},
290
313
  "elements": elements,
291
314
  }
292
- return await _feishu_post(
293
- f"{_FEISHU_API}/im/v1/messages/{message_id}/reply",
294
- token,
295
- {"msg_type": "interactive", "content": json.dumps(card)},
296
- )
315
+ return await _send_message("reply", message_id, "interactive", json.dumps(card))
297
316
 
298
317
 
299
318
  async def send_card_to_chat(chat_id: str, title: str, body: str,
@@ -305,31 +324,13 @@ async def send_card_to_chat(chat_id: str, title: str, body: str,
305
324
  was never read, so every proactive send failed without a trace. Nothing
306
325
  scheduled depended on it until the shipper digest.
307
326
  """
308
- token = await _get_access_token()
309
- if not token:
310
- return False
311
327
  elements = _build_card_elements(body)
312
328
  card = {
313
329
  "config": {"wide_screen_mode": True},
314
330
  "header": {"title": {"tag": "plain_text", "content": title}, "template": color},
315
331
  "elements": elements,
316
332
  }
317
- try:
318
- import httpx
319
- async with httpx.AsyncClient(timeout=15) as client:
320
- resp = await client.post(
321
- f"{_FEISHU_API}/im/v1/messages?receive_id_type={receive_id_type}",
322
- headers={"Authorization": f"Bearer {token}"},
323
- json={
324
- "receive_id": chat_id,
325
- "msg_type": "interactive",
326
- "content": json.dumps(card),
327
- },
328
- )
329
- result = resp.json()
330
- except Exception as exc:
331
- logger.warning("send_card_to_chat failed: %s", exc)
332
- return False
333
+ result = await _send_message("send", chat_id, "interactive", json.dumps(card), receive_id_type) or {}
333
334
  if result.get("code") != 0:
334
335
  logger.warning("send_card_to_chat rejected: code=%s msg=%s", result.get("code"), result.get("msg"))
335
336
  return False
@@ -1179,10 +1180,7 @@ async def _request_reorder(inbound: InboundMessage, message_id: str) -> None:
1179
1180
  summary=f"**建议订货**\n{summary}\n\n数量未计入起订量和箱规,请审批人核对。",
1180
1181
  requested_by=f"feishu:{inbound.sender_id}",
1181
1182
  )
1182
- token = await _get_access_token()
1183
- if token:
1184
- await _feishu_post(f"{_FEISHU_API}/im/v1/messages/{message_id}/reply", token,
1185
- {"msg_type": "interactive", "content": json.dumps(_approval_card(approval))})
1183
+ await _send_message("reply", message_id, "interactive", json.dumps(_approval_card(approval)))
1186
1184
 
1187
1185
 
1188
1186
  async def _handle_card_action(event: Dict[str, Any], *, authorized_by_binding: bool = False) -> Dict[str, Any]:
@@ -1294,6 +1292,13 @@ async def dispatch_event(raw: Dict[str, Any], *, authorized_by_binding: bool = F
1294
1292
  if msg.get("chat_type") != "p2p" and msg_type not in ("text", "post"):
1295
1293
  return {"code": 0}
1296
1294
 
1295
+ # Attachments are downloaded with the app's credentials, which relay mode
1296
+ # does not have on this machine; say so instead of failing silently.
1297
+ if msg_type in ("audio", "image", "file") and not (
1298
+ os.environ.get("FEISHU_APP_ID") and os.environ.get("FEISHU_APP_SECRET")):
1299
+ await reply_text(msg_id, "中继模式下暂不支持图片、语音和文件,请直接发送文字。")
1300
+ return {"code": 0}
1301
+
1297
1302
  # ── Text message ──────────────────────────────────────────────────────────
1298
1303
  if msg_type == "text":
1299
1304
  text = _strip_mentions(content.get("text", ""))
@@ -95,6 +95,25 @@ def _db() -> sqlite3.Connection:
95
95
  created_at REAL NOT NULL
96
96
  )
97
97
  """)
98
+ # Chats a client's bound user has spoken to the bot in: the only chats the
99
+ # client may later send to unprompted (the daily digest).
100
+ conn.execute("""
101
+ CREATE TABLE IF NOT EXISTS client_chats (
102
+ client_id TEXT NOT NULL,
103
+ chat_id TEXT NOT NULL,
104
+ last_seen REAL NOT NULL,
105
+ PRIMARY KEY (client_id, chat_id)
106
+ )
107
+ """)
108
+ # Cards the relay posted for a client: a press on one is routed back to
109
+ # that client, which holds the approval it belongs to.
110
+ conn.execute("""
111
+ CREATE TABLE IF NOT EXISTS card_origins (
112
+ message_id TEXT PRIMARY KEY,
113
+ client_id TEXT NOT NULL,
114
+ created_at REAL NOT NULL
115
+ )
116
+ """)
98
117
  conn.commit()
99
118
  return conn
100
119
 
@@ -149,6 +168,103 @@ _connections: dict[str, WebSocket] = {} # client_id → WebSocket
149
168
  _pending_responses: dict[str, asyncio.Future] = {} # request_id → Future
150
169
 
151
170
 
171
+ # ── Sending on a client's behalf ─────────────────────────────────────────────
172
+ #
173
+ # Until 2026-10-03 a client could not answer at all. The relay forwarded each
174
+ # event and replied to Feishu only when the client was offline; the client's
175
+ # bot then tried to reply itself, with app credentials that relay mode
176
+ # deliberately never gives it — so every answer was dropped without a trace.
177
+ #
178
+ # Now the client hands its message back over the WebSocket and the relay sends
179
+ # it. That turns the relay's bot identity into something any connected client
180
+ # can use, so a send is accepted only where the client has standing:
181
+ # reply — to a message the relay forwarded to this client, within an hour;
182
+ # send — to a chat this client's bound user has spoken to the bot in;
183
+ # at most _SEND_LIMIT messages per client per minute;
184
+ # msg_type text or interactive, content at most 30 KB.
185
+
186
+ _FORWARD_TTL = 3600
187
+ _SEND_LIMIT = 60
188
+ _forwarded: dict[str, tuple[str, float]] = {} # message_id → (client_id, expires)
189
+ _send_times: dict[str, list[float]] = {} # client_id → recent send timestamps
190
+
191
+
192
+ def _remember_forward(client_id: str, message_id: str, chat_id: str) -> None:
193
+ now = time.time()
194
+ for mid in [m for m, (_, exp) in _forwarded.items() if exp < now]:
195
+ _forwarded.pop(mid, None)
196
+ if message_id:
197
+ _forwarded[message_id] = (client_id, now + _FORWARD_TTL)
198
+ if chat_id:
199
+ get_db().execute(
200
+ "INSERT OR REPLACE INTO client_chats VALUES (?, ?, ?)", (client_id, chat_id, now))
201
+ get_db().commit()
202
+
203
+
204
+ def _may_send(client_id: str, request: dict) -> str:
205
+ """"" when the request is allowed, otherwise why not."""
206
+ op, target = request.get("op"), str(request.get("target") or "")
207
+ if request.get("msg_type") not in ("text", "interactive"):
208
+ return "msg_type must be text or interactive"
209
+ if len(str(request.get("content") or "")) > 30_000:
210
+ return "content too large"
211
+ if op == "reply":
212
+ owner = _forwarded.get(target)
213
+ if not owner or owner[0] != client_id or owner[1] < time.time():
214
+ return "not a message forwarded to this client"
215
+ elif op == "send":
216
+ if request.get("receive_id_type", "chat_id") != "chat_id":
217
+ return "send is only to chats"
218
+ row = get_db().execute(
219
+ "SELECT 1 FROM client_chats WHERE client_id = ? AND chat_id = ?", (client_id, target)
220
+ ).fetchone()
221
+ if not row:
222
+ return "this client has no conversation in that chat"
223
+ else:
224
+ return "op must be reply or send"
225
+ now = time.time()
226
+ recent = [t for t in _send_times.get(client_id, []) if t > now - 60]
227
+ if len(recent) >= _SEND_LIMIT:
228
+ return "rate limit"
229
+ recent.append(now)
230
+ _send_times[client_id] = recent
231
+ return ""
232
+
233
+
234
+ async def _send_for_client(client_id: str, request: dict) -> dict:
235
+ refused = _may_send(client_id, request)
236
+ if refused:
237
+ logger.warning("refused send for %s: %s", client_id, refused)
238
+ return {"code": -1, "msg": f"relay refused: {refused}"}
239
+ token = await _get_tenant_token()
240
+ body = {"msg_type": request["msg_type"], "content": request["content"]}
241
+ if request["op"] == "reply":
242
+ url = f"{_FEISHU_API}/im/v1/messages/{request['target']}/reply"
243
+ else:
244
+ url = f"{_FEISHU_API}/im/v1/messages?receive_id_type=chat_id"
245
+ body["receive_id"] = request["target"]
246
+ try:
247
+ async with httpx.AsyncClient() as client:
248
+ resp = await client.post(url, headers={"Authorization": f"Bearer {token}"}, json=body, timeout=15)
249
+ result = resp.json()
250
+ except Exception as exc:
251
+ logger.warning("send for %s failed: %s", client_id, exc)
252
+ return {"code": -1, "msg": "relay could not reach Feishu"}
253
+ sent_id = ((result.get("data") or {}).get("message_id") or "")
254
+ if result.get("code") == 0 and request["msg_type"] == "interactive" and sent_id:
255
+ get_db().execute("INSERT OR REPLACE INTO card_origins VALUES (?, ?, ?)",
256
+ (sent_id, client_id, time.time()))
257
+ get_db().commit()
258
+ return {"code": result.get("code"), "msg": result.get("msg", ""),
259
+ "data": {"message_id": sent_id} if sent_id else {}}
260
+
261
+
262
+ def _card_origin(message_id: str) -> Optional[str]:
263
+ row = get_db().execute("SELECT client_id FROM card_origins WHERE message_id = ?",
264
+ (message_id,)).fetchone()
265
+ return row["client_id"] if row else None
266
+
267
+
152
268
  # ── Feishu API helpers ────────────────────────────────────────────────────────
153
269
 
154
270
  _feishu_token_cache: dict[str, Any] = {}
@@ -217,7 +333,13 @@ async def _route_to_local(feishu_user_id: str, payload: dict) -> Optional[Any]:
217
333
  client_id = _lookup_client(feishu_user_id)
218
334
  if not client_id:
219
335
  return None
336
+ message = (payload.get("event") or {}).get("message") or {}
337
+ _remember_forward(client_id, message.get("message_id", ""), message.get("chat_id", ""))
338
+ return await _route_to_client(client_id, payload)
339
+
220
340
 
341
+ async def _route_to_client(client_id: str, payload: dict, timeout: Optional[float] = None) -> Optional[Any]:
342
+ """Send an event to one connected client and wait for its result."""
221
343
  ws = _connections.get(client_id)
222
344
  if not ws:
223
345
  return None
@@ -232,7 +354,7 @@ async def _route_to_local(feishu_user_id: str, payload: dict) -> Optional[Any]:
232
354
  "id": req_id,
233
355
  "payload": payload,
234
356
  }))
235
- result = await asyncio.wait_for(future, timeout=_MSG_TIMEOUT)
357
+ result = await asyncio.wait_for(future, timeout=timeout or _MSG_TIMEOUT)
236
358
  return result
237
359
  except asyncio.TimeoutError:
238
360
  logger.warning("Timeout waiting for response from client_id=%s", client_id)
@@ -303,6 +425,14 @@ async def ws_endpoint(websocket: WebSocket):
303
425
  if response_msg.get("type") == "pong":
304
426
  continue
305
427
 
428
+ if response_msg.get("type") == "send":
429
+ async def _answer(request=response_msg, cid=client_id):
430
+ result = await _send_for_client(cid, request)
431
+ await websocket.send_text(json.dumps(
432
+ {"type": "send_result", "id": request.get("id", ""), "result": result}))
433
+ asyncio.create_task(_answer())
434
+ continue
435
+
306
436
  if response_msg.get("type") == "response":
307
437
  req_id = response_msg.get("id", "")
308
438
  future = _pending_responses.get(req_id)
@@ -398,6 +528,20 @@ async def feishu_event(request: Request):
398
528
  if "challenge" in payload:
399
529
  return {"challenge": payload["challenge"]}
400
530
 
531
+ # A button press on a card. Routed to the client that posted the card —
532
+ # it holds the approval and checks the presser against its approvers —
533
+ # and answered synchronously, because Feishu shows the response's toast
534
+ # and card to the presser and waits at most 3 s for it.
535
+ if (payload.get("header") or {}).get("event_type") == "card.action.trigger":
536
+ context = (payload.get("event") or {}).get("context") or {}
537
+ origin = _card_origin(context.get("open_message_id", ""))
538
+ if not origin:
539
+ return {"toast": {"type": "error", "content": "这张卡片已失效。"}}
540
+ result = await _route_to_client(origin, payload, timeout=2.5)
541
+ if isinstance(result, dict) and ("toast" in result or "card" in result):
542
+ return result
543
+ return {"toast": {"type": "error", "content": "Aria 本机未及时响应,请稍后再试。"}}
544
+
401
545
  # Extract sender + message_id
402
546
  event = payload.get("event", {})
403
547
  message = event.get("message", {})
@@ -91,6 +91,39 @@ async def _handle_message(raw_msg: dict, ws) -> None:
91
91
  await ws.send(reply)
92
92
 
93
93
 
94
+ # ── Sending through the relay ─────────────────────────────────────────────────
95
+ #
96
+ # This machine has no Feishu app credentials in relay mode, so the bot hands
97
+ # each outgoing message to the relay, which sends it — and refuses anything
98
+ # that is not a reply to a message it forwarded here, or a post to a chat this
99
+ # user has spoken to the bot in.
100
+
101
+ _pending_sends: dict[str, asyncio.Future] = {}
102
+ _SEND_TIMEOUT = 20
103
+
104
+
105
+ def _relay_sender(ws):
106
+ async def send(request: dict) -> dict:
107
+ import uuid
108
+ send_id = f"send_{uuid.uuid4().hex[:10]}"
109
+ future = asyncio.get_running_loop().create_future()
110
+ _pending_sends[send_id] = future
111
+ try:
112
+ await ws.send(json.dumps({"type": "send", "id": send_id, **request}))
113
+ return await asyncio.wait_for(future, timeout=_SEND_TIMEOUT)
114
+ except asyncio.TimeoutError:
115
+ return {"code": -1, "msg": "relay did not confirm the send"}
116
+ finally:
117
+ _pending_sends.pop(send_id, None)
118
+ return send
119
+
120
+
121
+ def _settle_send(msg: dict) -> None:
122
+ future = _pending_sends.get(msg.get("id", ""))
123
+ if future is not None and not future.done():
124
+ future.set_result(msg.get("result") or {})
125
+
126
+
94
127
  # ── Main loop ─────────────────────────────────────────────────────────────────
95
128
 
96
129
  async def _connect_and_serve(once: bool = False) -> None:
@@ -131,6 +164,9 @@ async def _connect_and_serve(once: bool = False) -> None:
131
164
 
132
165
  logger.info("Registered. Waiting for messages…")
133
166
  delay = _RECONNECT_DELAY_BASE # reset on success
167
+ bot = _get_feishu_bot()
168
+ if bot is not None and hasattr(bot, "set_relay_sender"):
169
+ bot.set_relay_sender(_relay_sender(ws))
134
170
 
135
171
  async for raw in ws:
136
172
  try:
@@ -143,6 +179,10 @@ async def _connect_and_serve(once: bool = False) -> None:
143
179
  await ws.send(json.dumps({"type": "pong"}))
144
180
  continue
145
181
 
182
+ if msg.get("type") == "send_result":
183
+ _settle_send(msg)
184
+ continue
185
+
146
186
  if msg.get("type") == "message":
147
187
  asyncio.create_task(_handle_message(msg, ws))
148
188
 
@@ -157,6 +197,10 @@ async def _connect_and_serve(once: bool = False) -> None:
157
197
  except Exception as e:
158
198
  logger.warning("Relay error: %s — retry in %ds", e, delay)
159
199
 
200
+ # Disconnected: sends must not go to a closed socket while we retry.
201
+ bot = _get_feishu_bot()
202
+ if bot is not None and hasattr(bot, "set_relay_sender"):
203
+ bot.set_relay_sender(None)
160
204
  await asyncio.sleep(delay)
161
205
  delay = min(delay * 2, _RECONNECT_DELAY_MAX)
162
206
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aria-code
3
- Version: 0.66.0
3
+ Version: 0.67.0
4
4
  Summary: AI coding and research workspace with optional finance and connected-domain tools
5
5
  License: Apache-2.0
6
6
  Project-URL: Homepage, https://github.com/artheras/aria-code
@@ -108,6 +108,9 @@ Requires-Dist: pytest-asyncio>=0.23.7; extra == "dev"
108
108
  Requires-Dist: pytest-timeout>=2.3.0; extra == "dev"
109
109
  Requires-Dist: ruff>=0.4.0; extra == "dev"
110
110
  Requires-Dist: mypy>=1.10.0; extra == "dev"
111
+ Requires-Dist: fastapi>=0.110.0; extra == "dev"
112
+ Requires-Dist: uvicorn>=0.29.0; extra == "dev"
113
+ Requires-Dist: python-multipart>=0.0.9; extra == "dev"
111
114
  Provides-Extra: full
112
115
  Requires-Dist: google-genai>=1.0.0; extra == "full"
113
116
  Requires-Dist: akshare>=1.14.68; extra == "full"
@@ -635,6 +635,7 @@ tests/test_quant_engine_namespace.py
635
635
  tests/test_rebind_contract.py
636
636
  tests/test_rebind_namespace_contract.py
637
637
  tests/test_relay_event_verification.py
638
+ tests/test_relay_sends_for_clients.py
638
639
  tests/test_release_chain.py
639
640
  tests/test_release_commit_identity.py
640
641
  tests/test_release_push_is_atomic.py
@@ -91,6 +91,9 @@ pytest-asyncio>=0.23.7
91
91
  pytest-timeout>=2.3.0
92
92
  ruff>=0.4.0
93
93
  mypy>=1.10.0
94
+ fastapi>=0.110.0
95
+ uvicorn>=0.29.0
96
+ python-multipart>=0.0.9
94
97
 
95
98
  [files]
96
99
  pdfplumber>=0.11.0
@@ -1,8 +1,8 @@
1
1
  """HTTP-level coverage for the internal project-review/workspace service.
2
2
 
3
- Requires the optional "service" extra (fastapi, uvicorn, python-multipart);
4
- skips cleanly when it is not installed, matching how the local CLI keeps
5
- this dependency optional.
3
+ Needs fastapi and python-multipart, which the dev extra and every CI test job
4
+ install. It still skips without them, for a local run of the core suite —
5
+ but it used to skip in CI too, because no workflow installed them.
6
6
  """
7
7
 
8
8
  from __future__ import annotations