aria-code 0.79.0__tar.gz → 0.81.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.
- {aria_code-0.79.0/src/aria_code.egg-info → aria_code-0.81.0}/PKG-INFO +1 -1
- {aria_code-0.79.0 → aria_code-0.81.0}/pyproject.toml +1 -1
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/_version.py +1 -1
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/analysis_cmds.py +6 -1
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/market_context.py +7 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/deterministic.py +7 -1
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/handlers/market_handlers.py +94 -42
- aria_code-0.81.0/src/aria_code/apps/cli/market_hours.py +100 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/utils/market_detect.py +43 -10
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/aria_cli.py +62 -23
- {aria_code-0.79.0 → aria_code-0.81.0/src/aria_code.egg-info}/PKG-INFO +1 -1
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code.egg-info/SOURCES.txt +3 -0
- aria_code-0.81.0/tests/test_market_answers_in_english.py +210 -0
- aria_code-0.81.0/tests/test_market_hours.py +73 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/LICENSE +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/NOTICE +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/README.md +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/setup.cfg +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/adk_apps/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/adk_apps/aria_code_review/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/adk_apps/aria_code_review/agent.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/adk_apps/aria_research/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/adk_apps/aria_research/agent.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/base.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/code_review.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/deep/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/deep/calibration_loop.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/deep/critic.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/deep/deepen.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/deep/models.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/deep/pipeline.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/deep/quant_fusion.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/deep/themes.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/deep/tiers.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/engineering/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/engineering/coder.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/engineering/tester.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/financial/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/financial/cashflow_burn.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/financial/catalyst.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/financial/corporate_finance.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/financial/debate.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/financial/earnings.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/financial/fundamental.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/financial/macro.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/financial/news.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/financial/risk.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/financial/sector.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/financial/strategist.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/financial/stripe_revenue.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/financial/synthesis.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/financial/technical.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/orchestrator.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/portfolio_agent.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/realty/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/realty/asset_diagnosis.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/realty/business_match.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/realty/cashflow_verify.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/realty/contract_rules.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/realty/energy_anomaly.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/realty/exit_settlement.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/realty/fulfillment_risk.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/realty/ops_optimize.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/realty/revenue_share.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/registry.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/signal_scheme.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/sports/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/sports/football_agent.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/supervisor.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/team.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/warehouse/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/warehouse/contracts.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/warehouse/dashboard.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/warehouse/fulfillment_leadtime.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/warehouse/inbound_exceptions.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/warehouse/inventory_health.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/warehouse/local_run.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/warehouse/local_snapshot.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/warehouse/logistics_cost.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/warehouse/logistics_sync.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/agents/warehouse/workflow.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/aliyun_data_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/README.md +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/channels/README.md +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/channels/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/channels/approvals.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/channels/conversation.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/channels/digest.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/channels/intake.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/channels/registry.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/channels/tradingview.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/README.md +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/_optional.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/bootstrap.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/broker_render.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/codegen_paths.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/_business_render.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/_ui.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/ashare_prediction_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/auth_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/backtest_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/broker_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/business_workflow_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/canvas_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/catalog.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/core_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/data_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/diagnostic_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/diagnostic_ops_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/file_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/finance_service_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/fx_commodity_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/market.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/market_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/market_render.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/model_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/ops_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/orchestrator_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/pdf_export_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/portfolio_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/report.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/scaffold_templates.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/session_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/session_ux_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/team.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/team_render.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/ui_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/warehouse_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/workflow_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/commands/workspace_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/config_paths.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/config_store.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/constants.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/context.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/direct.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/finance_service_catalog.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/football_reports.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/github_app_auth.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/google_login.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/handlers/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/handlers/broker_handlers.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/handlers/chart_handlers.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/handlers/realty_handlers.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/handlers/sports_handlers.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/handlers/strategy_advice.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/helpers.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/hooks.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/i18n.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/intent.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/intent_router.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/intent_signals.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/lifecycle_hooks.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/local_tool_schemas.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/main.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/market_metadata.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/market_universe.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/message_processing.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/model_catalog.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/pdf_report.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/plan_mode.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/plotly_html.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/prediction_feedback.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/preflight.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/project_aria.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/prompt_assembly.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/prompts/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/prompts/coding.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/prompts/select.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/prompts/system_prompts.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/prompts/ui.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/provider_endpoints.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/provider_keys.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/providers/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/providers/base.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/providers/chat_routing.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/providers/collaboration.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/providers/llm/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/providers/llm/offline_responses.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/providers/llm/ollama_stream.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/providers/llm/response_cache.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/providers/llm/sse_stream.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/providers/runtime_bridge.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/providers/vertexai_stream.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/review_runner.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/runtime_consumer.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/sandbox.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/session_export.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/session_jsonl.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/session_store.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/skills_catalog.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/todo_tracker.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/tool_executor.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/tool_registry.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/tool_scope.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/tools/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/tools/context.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/tools/file_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/tools/market_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/tools/notebook_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/tools/system_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/tools/write_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/tradingview_bridge.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/turn_planning.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/update_check.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/updater.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/cli/utils/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/daemon/README.md +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/vscode/README.md +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/apps/vscode/package.json +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/aria_daemon.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/aria_feishu_bot.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/aria_mcp_server.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/aria_relay_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/aria_relay_server.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/aria_telegram_bot.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ariarc.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/artifacts.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/backtest_engine.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/backtest_report.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/automation.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/base.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/capabilities.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/cn/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/cn/easytrader_broker.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/cn/futu_broker.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/cn/longbridge_broker.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/cn/tiger_broker.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/cn/xtquant_broker.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/config.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/intl/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/intl/alpaca_broker.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/intl/ibkr_broker.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/intl/trading212_broker.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/intl/webull_broker.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/paper_broker.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/planning.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/registry.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/brokers/trading.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/canva_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/change_store.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/clients/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/clients/aliyun_data_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/clients/aria_relay_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/clients/canva_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/clients/figma_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/clients/football_data_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/clients/kling_video_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/clients/market_data_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/clients/openai_image_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/clients/runway_video_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/clients/warehouse_erp_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/cloud_memory.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/command_safety.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/computer_use_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/dashboard_generator.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/data_analysis_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/data_cleaner.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/data_service.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/datasources/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/datasources/base.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/datasources/router.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/datasources/sources/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/datasources/sources/akshare_source.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/datasources/sources/alpha_vantage_source.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/datasources/sources/edgar_source.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/datasources/sources/finnhub_source.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/datasources/sources/fred_source.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/datasources/sources/tushare_source.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/datasources/sources/web_scraper_source.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/datasources/sources/world_bank_source.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/datasources/sources/yfinance_source.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/demo_player.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/doctor.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/domain/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/domain/backtest_engine.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/domain/backtest_report.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/domain/finance_formulas.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/domain/portfolio_ledger.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/domain/strategy_vault.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/evals/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/evals/harness.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/evals/runner.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/external_agent_runner.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/figma_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/file_analysis_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/finance_formulas.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/football_data_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/image_gen_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/intent_classifier.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/kling_video_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/licensing.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/local_finance_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/local_image_provider.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/local_llm_provider.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/macro_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/markdown_pdf.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/market_data_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/mcp_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/memory_manager.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/model_capability.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/notification_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/openai_image_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/adk_bridge/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/adk_bridge/code_review_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/adk_bridge/market_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_agents/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_agents/manifest.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_core/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_core/architecture.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_core/export.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_core/manifest.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_core/paths.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_core/secure_file.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_infra/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_infra/arthera.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_infra/doctor.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_infra/product.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_mcp/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_mcp/bridge.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_mcp/circuit.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_mcp/config.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_mcp/installer.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_mcp/server.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_mcp/tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_sdk/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_sdk/client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_sdk/providers.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_sdk/streaming.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_sdk/types.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_services/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_services/cache.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_services/context.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_services/context_checkpoints.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_services/data.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_services/provider_health.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_services/references.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_services/registry.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_services/research_protocol.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_services/research_quality.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_services/settings.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_services/usage.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_skills/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_skills/catalog.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_skills/loader.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_skills/registry.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_tools/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_tools/financial/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_tools/financial/_paths.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_tools/financial/compliance.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_tools/financial/factors.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_tools/financial/risk_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_tools/financial/strategy.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/aria_tools/registry.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/_namespace.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/backtest/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/backtest/core.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/backtest/engine.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/portfolio/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/portfolio/optimizer.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/sports/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/sports/calibrator.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/sports/dixon_coles.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/sports/elo.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/sports/form.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/sports/h2h.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/sports/ml_model.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/sports/predictor.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/sports/tracker.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/stochastic/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/stochastic/ito_calculus.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/stochastic/kelly_criterion.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/stochastic/options_pricing.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packages/quant_engine/stochastic/stochastic_processes.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packs/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packs/base.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packs/finance/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packs/logistics/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packs/payments/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packs/realty/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packs/registry.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/packs/rules.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/plan_utils.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/plugin_loader.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/portfolio_ledger.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/preview_server.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/privacy/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/privacy/feedback.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/project_review.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/project_review_api.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/project_review_server.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/project_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/providers/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/providers/llm/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/providers/llm/anthropic.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/providers/llm/autoconfig.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/providers/llm/base.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/providers/llm/custom.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/providers/llm/ollama.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/providers/llm/openai_compat.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/providers/llm/registry.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/providers/local_image_provider.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/providers/local_llm_provider.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/providers/tool_messages.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/realty_data_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/relay_store.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/report_exporters.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/report_generator.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/review_service.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/acceptance.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/agent_loop.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/approval.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/budget.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/checkpoints.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/crash_report.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/events.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/gateway.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/lsp.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/orchestrator.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/repo_map.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/run_state.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/run_store.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/self_healing.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/subagent.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/task_ledger.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/task_orchestrator.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/tool_executor.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/tool_policy.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runtime/worktrees.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/runway_video_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/safety/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/safety/permissions.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/safety/service.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/setup_wizard.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/spreadsheet_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/strategy_vault.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/artifact_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/broker_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/build_quant_engine.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/code_audit_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/computer_use_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/data_analysis_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/enterprise_finance_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/extended_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/file_analysis_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/image_gen_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/local_finance_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/logistics_carriers.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/logistics_inventory.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/logistics_io.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/logistics_tenancy.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/logistics_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/macro_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/notification_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/project_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/realty_data_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/spreadsheet_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/tools/stripe_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ui/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ui/banner.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ui/completer.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ui/console.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ui/image_render.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ui/input_box.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ui/picker.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ui/render/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ui/render/finance.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ui/render/market.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ui/render/output.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ui/render/responsive.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ui/render/team.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ui/robot.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/ui/startup_dashboard.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/utils/vscode_uri.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/video_analysis.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/video_editor.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/workspace/__init__.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/workspace/files.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/workspace/verify.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/workspace_changes.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/workspace_context.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/workspace_service.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code/workspace_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code.egg-info/dependency_links.txt +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code.egg-info/entry_points.txt +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code.egg-info/requires.txt +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/src/aria_code.egg-info/top_level.txt +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_adk_market_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_agent_team_fallback.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_analyze_file_tool.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_architecture_ledger_is_true.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_architecture_report.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_aria_cli_core.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_aria_mcp_server.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_aria_sdk.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_artifact_publishing.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_artifacts_and_reports.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_ashare_prediction_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_backtest_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_backtest_engine.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_backtest_report.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_binary_bundles_runtime_imports.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_broken_akshare_is_optional.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_broker_automation.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_broker_chat_confirm_gate.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_broker_planning.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_broker_safety.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_broker_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_budget.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_business_workflow_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_canva_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_canvas_cmds.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_card_approvals.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_channel_intake.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_channels.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_chart_handlers.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_chat_bots_fail_closed.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_chat_routing.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_ci_security_workflow.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_cli_app_split.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_cli_bootstrap.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_cli_config_store.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_cli_lifecycle_hooks.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_cli_runtime_consumer.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_cli_tool_executor_module.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_cli_updater.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_cloud_memory.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_code_audit_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_code_review_agent.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_codegen_output.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_coder_tester_self_healing.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_coder_tool_safety.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_collaboration.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_command_loggers.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_command_safety.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_completions_builder.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_config_paths.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_configured_provider.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_container_entrypoint.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_container_entrypoints.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_context_checkpoints.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_context_references.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_context_service.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_conversation_core.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_crash_report.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_credential_file_permissions.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_custom_providers.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_daemon_gateway_config.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_dashboard_generator.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_data_service.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_data_service_imports.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_datasource_routing.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_deep_analysis.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_degrades_without_quant_engine.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_dispatcher_pins_match_the_release.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_doctor.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_doctor_describes_the_current_install.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_doctor_npm_scope.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_engine_boundary.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_enterprise_tool_honesty.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_env_switch_docs.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_evals_harness.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_event_import_roots.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_extended_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_feishu_swarm_config.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_finalize_release.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_finance_renderers.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_finance_service_catalog.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_first_run_works.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_football_agent.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_football_prediction_output.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_google_cloud_models.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_google_cloud_routing.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_google_login.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_google_search_provider.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_headless_is_agentic.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_honest_surfaces.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_image_gen_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_image_inputs.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_import_graph_budget.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_intent_router.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_intent_signals.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_kling_video_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_lazy_rebind.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_legacy_module_imports.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_license_consistency.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_licensing.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_local_image_provider.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_logistics_3pl.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_logistics_and_finance_agents.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_lsp.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_markdown_pdf.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_market_data_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_market_history_inheritance.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_market_history_tool.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_market_questions_on_backend.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_market_symbol_extraction.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_market_universe.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_mcp_circuit.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_mcp_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_model_capability_registry.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_model_choice_is_the_users.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_model_selection_state.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_native_binary_entrypoints.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_native_installer.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_new_modules.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_no_hardcoded_developer_paths.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_no_uncommitted_imports.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_ollama_stream_imports.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_ollama_stream_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_openai_image_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_operations_suite.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_output_rendering.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_packages_facade.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_packaging_constraints.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_packaging_manifest.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_packs_domains.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_pdf_report.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_pick_best_installed_model.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_plan_mode.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_platform_package_assembly.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_platform_packages.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_plotly_html_output.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_portfolio_ledger.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_post_turn_context_decision.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_preflight.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_preview_server.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_privacy_feedback.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_project_aria.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_project_review.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_project_review_api.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_prompt_assembly.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_prompt_selection.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_provider_autoconfig.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_provider_error_messages.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_provider_integration.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_provider_registry.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_public_service_status.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_quant_engine_namespace.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_rebind_contract.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_rebind_namespace_contract.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_relay_client_credentials.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_relay_event_verification.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_relay_sends_for_clients.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_relay_store.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_relay_url.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_release_chain.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_release_commit_identity.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_release_push_is_atomic.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_release_reaches_the_registries.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_release_verification_waits.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_release_workflow_permissions.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_report_charts.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_report_generator.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_research_protocol.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_research_quality.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_responsive_rendering.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_review_service.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_root_module_budget.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_rsi_without_pandas_ta.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_runtime_acceptance.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_runtime_agent_loop.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_runtime_approval.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_runtime_bridge.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_runtime_bridge_fallback.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_runtime_checkpoints.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_runtime_event_identity.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_runtime_gateway.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_runtime_repo_map.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_runtime_run_store.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_runtime_tool_executor.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_runtime_worktrees.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_runway_video_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_safety_permissions.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_safety_service.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_safety_service_adoption.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_service_diagnostics_security.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_session_search.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_settings_service.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_shipper_digest.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_single_import_root.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_skill_agent_binding.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_skill_catalog.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_skill_loader.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_spreadsheet_tools.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_sse_stream_contract.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_startup_dashboard.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_startup_latency.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_streaming_pipeline.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_stripe_agent.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_subagent.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_supervisor_routing.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_system_prompts.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_system_tools_output.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_task_orchestrator.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_team_synthesis.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_tls_trust_store.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_tool_policy.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_tool_rounds_on_openai_apis.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_tool_scope.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_trading_service.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_tradingview_bridge.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_turn_planning.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_ui_completer_references.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_ui_console_theme.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_ui_input_box.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_ui_language_and_model.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_ui_robot_banner.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_update_health_routes.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_verification_hint.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_verification_policy.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_version_consistency.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_version_counter.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_video_analysis.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_video_editor.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_vscode_mcp.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_warehouse_agents.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_warehouse_cli_registration.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_warehouse_erp_client.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_warehouse_workflow.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_wheel_is_installable.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_workspace_changes.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_workspace_context.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_workspace_files.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_workspace_scope.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.0}/tests/test_workspace_service.py +0 -0
- {aria_code-0.79.0 → aria_code-0.81.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.
|
|
3
|
+
Version: 0.81.0
|
|
4
4
|
Summary: Open-source AI agent for coding, financial analysis and logistics operations: numbers you can check, client data kept apart, actions a person approves
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Project-URL: Homepage, https://github.com/artheras/aria-code
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "aria-code"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.81.0"
|
|
8
8
|
description = "Open-source AI agent for coding, financial analysis and logistics operations: numbers you can check, client data kept apart, actions a person approves"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "Apache-2.0" }
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from aria_code.apps.cli.commands.market import parse_analysis_args
|
|
6
|
+
from aria_code.apps.cli.commands.market_context import context_has_price
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
import logging
|
|
@@ -121,7 +122,11 @@ class AnalysisCommandsMixin:
|
|
|
121
122
|
label = "Focus on" if response_lang == "en" else "重点分析"
|
|
122
123
|
ctx += f"\n\n### {heading}\n- {label}: {parsed.focus}"
|
|
123
124
|
|
|
124
|
-
|
|
125
|
+
# The prompt carries the fetched data, so the evidence gate must not
|
|
126
|
+
# refuse the answer for want of a tool call: "analyze Apple stock"
|
|
127
|
+
# lands here, and on the backend route there are no tools to call.
|
|
128
|
+
await self.terminal.send_message(build_analyze_prompt(symbol, ctx, is_cn, response_lang=response_lang),
|
|
129
|
+
evidence_grounded=context_has_price(ctx))
|
|
125
130
|
try:
|
|
126
131
|
_resp = next((m["content"] for m in reversed(self.terminal.conversation)
|
|
127
132
|
if m.get("role") == "assistant" and m.get("content")), "")
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import logging
|
|
7
|
+
import re
|
|
7
8
|
import time
|
|
8
9
|
from typing import Any, Callable, Optional
|
|
9
10
|
|
|
@@ -14,6 +15,12 @@ TA_SESSION_CACHE: dict[str, dict[str, Any]] = {}
|
|
|
14
15
|
TA_SESSION_CACHE_TTL = 600
|
|
15
16
|
|
|
16
17
|
|
|
18
|
+
def context_has_price(context: str) -> bool:
|
|
19
|
+
"""Whether an /analyze context carries a fetched price — the header line
|
|
20
|
+
build_analyze_context writes as "- Price: 333.69" ("- 价格: 333.69")."""
|
|
21
|
+
return re.search(r"^- (?:Price|价格): \d", context or "", re.MULTILINE) is not None
|
|
22
|
+
|
|
23
|
+
|
|
17
24
|
def _cached_ta(symbol: str) -> dict[str, Any]:
|
|
18
25
|
cached = TA_SESSION_CACHE.get(symbol)
|
|
19
26
|
if cached and (time.time() - float(cached.get("ts", 0))) < TA_SESSION_CACHE_TTL:
|
|
@@ -26,6 +26,7 @@ from aria_code.apps.cli.utils.market_detect import (
|
|
|
26
26
|
_is_realty_query,
|
|
27
27
|
_is_stock_chart_analysis_request,
|
|
28
28
|
)
|
|
29
|
+
from aria_code.packages.aria_services.research_protocol import requires_financial_evidence
|
|
29
30
|
|
|
30
31
|
|
|
31
32
|
BrokerRegistryFactory = Callable[[], Any]
|
|
@@ -178,8 +179,13 @@ def run_deterministic_chain(
|
|
|
178
179
|
if not deterministic.get("success") and not config.model_has_tools:
|
|
179
180
|
deterministic = _try_handle_market_overview(message)
|
|
180
181
|
|
|
182
|
+
# The evidence gate refuses a market answer given without data, and a
|
|
183
|
+
# model with no tools cannot fetch any — so whatever the gate will demand
|
|
184
|
+
# data for is fetched here, in any wording ("How's NVDA this week?" as
|
|
185
|
+
# well as "分析苹果股票").
|
|
181
186
|
if not deterministic.get("success") and not config.model_has_tools:
|
|
182
|
-
deterministic = _try_handle_market_snapshot_analysis(
|
|
187
|
+
deterministic = _try_handle_market_snapshot_analysis(
|
|
188
|
+
message, history=history, evidence_required=requires_financial_evidence(message))
|
|
183
189
|
|
|
184
190
|
return deterministic
|
|
185
191
|
|
|
@@ -7,6 +7,7 @@ _HAS_MDC and _get_mdc are resolved via lazy import to avoid circular deps.
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
import json
|
|
9
9
|
import os
|
|
10
|
+
import re
|
|
10
11
|
import sys
|
|
11
12
|
from datetime import datetime
|
|
12
13
|
from pathlib import Path
|
|
@@ -22,6 +23,7 @@ from aria_code.apps.cli.utils.market_detect import (
|
|
|
22
23
|
_detect_market_overview,
|
|
23
24
|
_PRIVATE_COMPANY_PROFILES,
|
|
24
25
|
)
|
|
26
|
+
from aria_code.apps.cli.market_hours import market_session
|
|
25
27
|
from aria_code.apps.cli.market_metadata import enrich_market_quote, market_display_label
|
|
26
28
|
from aria_code.packages.aria_core.paths import aria_home
|
|
27
29
|
|
|
@@ -133,6 +135,14 @@ def _snapshot_signal(price, change_pct, rsi, macd_hist, ma20, ma60) -> tuple[str
|
|
|
133
135
|
return signal, score, confidence, label
|
|
134
136
|
|
|
135
137
|
|
|
138
|
+
# _snapshot_signal's labels, for a reply in English.
|
|
139
|
+
_SIGNAL_LABELS_EN = {
|
|
140
|
+
"强势多头": "strongly bullish", "偏多": "bullish", "短线偏强": "short-term firm",
|
|
141
|
+
"震荡观察": "range-bound", "短线偏弱": "short-term soft", "偏空": "bearish",
|
|
142
|
+
"强势空头": "strongly bearish", "指标不足": "insufficient data",
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
|
|
136
146
|
def _support_resistance_for_row(currency: str, price, ma20, ma60, bb_lower, bb_upper) -> tuple[str, str]:
|
|
137
147
|
p = _num_or_none(price)
|
|
138
148
|
if p is None:
|
|
@@ -374,7 +384,7 @@ def _append_timeframe_levels(
|
|
|
374
384
|
raw_name = str(row.get("name") or "—")
|
|
375
385
|
name = _timeframe_display_name(raw_name, english=english)
|
|
376
386
|
source = _timeframe_source_label(str(row.get("source") or ""), english=english)
|
|
377
|
-
horizon = str(row.get("horizon") or "—")
|
|
387
|
+
horizon = _horizon_label(str(row.get("horizon") or "—"), english=english)
|
|
378
388
|
support = row.get("support") or []
|
|
379
389
|
resistance = row.get("resistance") or []
|
|
380
390
|
action = _level_action_line(name, support, resistance, currency, english=english)
|
|
@@ -397,6 +407,18 @@ def _append_timeframe_levels(
|
|
|
397
407
|
lines.append(f" - 用法:{action}")
|
|
398
408
|
|
|
399
409
|
|
|
410
|
+
_HORIZON_UNITS_EN = {"日": "days", "周": "weeks", "月": "months"}
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
def _horizon_label(horizon: str, *, english: bool) -> str:
|
|
414
|
+
if not english:
|
|
415
|
+
return horizon
|
|
416
|
+
if horizon == "快照":
|
|
417
|
+
return "snapshot"
|
|
418
|
+
match = re.fullmatch(r"\s*(\d+\s*-\s*\d+)\s*([日周月])\s*", horizon)
|
|
419
|
+
return f"{match.group(1)} {_HORIZON_UNITS_EN[match.group(2)]}" if match else horizon
|
|
420
|
+
|
|
421
|
+
|
|
400
422
|
def _build_timeframe_levels(
|
|
401
423
|
mdc,
|
|
402
424
|
symbol: str,
|
|
@@ -1058,6 +1080,8 @@ def _try_handle_multi_market_snapshot(message: str, symbols: list[str]) -> dict:
|
|
|
1058
1080
|
macd_text = f"{row['macd_hist']:.4f}" if row.get("macd_hist") is not None else "—"
|
|
1059
1081
|
sig = row.get("signal") or "—"
|
|
1060
1082
|
sig_label = row.get("signal_label") or ""
|
|
1083
|
+
if _en:
|
|
1084
|
+
sig_label = _SIGNAL_LABELS_EN.get(sig_label, sig_label)
|
|
1061
1085
|
sig_text = f"{sig} / {sig_label}" if sig_label and sig != "—" else sig
|
|
1062
1086
|
table.append(
|
|
1063
1087
|
f"| {row['symbol']} | {row.get('name') or row['symbol']} | {price} | "
|
|
@@ -1104,6 +1128,8 @@ def _try_handle_multi_market_snapshot(message: str, symbols: list[str]) -> dict:
|
|
|
1104
1128
|
vol = _fmt_int(row.get("volume")) if row.get("volume") else ""
|
|
1105
1129
|
sig = row.get("signal") or "—"
|
|
1106
1130
|
sig_label = row.get("signal_label") or "指标不足"
|
|
1131
|
+
if _en:
|
|
1132
|
+
sig_label = _SIGNAL_LABELS_EN.get(sig_label, sig_label)
|
|
1107
1133
|
score = int(row.get("signal_score") or 0)
|
|
1108
1134
|
conf = float(row.get("signal_confidence") or 0)
|
|
1109
1135
|
table.append("")
|
|
@@ -1417,14 +1443,18 @@ def _try_handle_market_overview(message: str) -> dict:
|
|
|
1417
1443
|
"tools_used": ["market_overview"]}
|
|
1418
1444
|
|
|
1419
1445
|
|
|
1420
|
-
def _try_handle_market_snapshot_analysis(message: str, history: list = None
|
|
1446
|
+
def _try_handle_market_snapshot_analysis(message: str, history: list = None, *,
|
|
1447
|
+
evidence_required: bool = False) -> dict:
|
|
1421
1448
|
"""Deterministic path for simple market analysis.
|
|
1422
1449
|
|
|
1423
1450
|
Local small models tend to mangle injected quote fields into fragments like
|
|
1424
1451
|
"N/A/N/A/-1.24%". For snapshot requests, format the data directly.
|
|
1452
|
+
``evidence_required``: see ``_is_market_snapshot_request``.
|
|
1425
1453
|
"""
|
|
1426
|
-
if not _is_market_snapshot_request(message, history):
|
|
1454
|
+
if not _is_market_snapshot_request(message, history, evidence_required=evidence_required):
|
|
1427
1455
|
return {"success": False, "error": "not_market_snapshot"}
|
|
1456
|
+
# The reply is in the language of the question, failures included.
|
|
1457
|
+
_en = _detect_lang(message) == "en"
|
|
1428
1458
|
|
|
1429
1459
|
_etf_symbols = _resolve_etf_snapshot_symbols(message)
|
|
1430
1460
|
if len(_etf_symbols) >= 2:
|
|
@@ -1447,6 +1477,15 @@ def _try_handle_market_snapshot_analysis(message: str, history: list = None) ->
|
|
|
1447
1477
|
return {
|
|
1448
1478
|
"success": True,
|
|
1449
1479
|
"response": (
|
|
1480
|
+
"## ❓ Unrecognised stock\n\n"
|
|
1481
|
+
"The company or brand in your message did not resolve to a known ticker.\n\n"
|
|
1482
|
+
"Try again with the ticker, for example:\n"
|
|
1483
|
+
"- China A-shares: `/quote 600519` (Kweichow Moutai)\n"
|
|
1484
|
+
"- Hong Kong: `/quote 0700.HK` (Tencent)\n"
|
|
1485
|
+
"- US: `/quote AAPL`\n"
|
|
1486
|
+
"- Europe: `/quote MC.PA` (LVMH)\n\n"
|
|
1487
|
+
"*Tip: `/ta <ticker>` gives the full technical analysis.*"
|
|
1488
|
+
) if _en else (
|
|
1450
1489
|
"## ❓ 无法识别的股票\n\n"
|
|
1451
1490
|
"未能将消息中提到的公司/品牌解析为已知股票代码。\n\n"
|
|
1452
1491
|
"请提供具体代码后重试,例如:\n"
|
|
@@ -1474,6 +1513,10 @@ def _try_handle_market_snapshot_analysis(message: str, history: list = None) ->
|
|
|
1474
1513
|
return {
|
|
1475
1514
|
"success": True,
|
|
1476
1515
|
"response": (
|
|
1516
|
+
f"## {symbol} market snapshot\n\n"
|
|
1517
|
+
"The local market data client is not loaded, so there is no live quote.\n\n"
|
|
1518
|
+
f"Run `/quote {symbol}` to retry."
|
|
1519
|
+
) if _en else (
|
|
1477
1520
|
f"## {symbol} 市场快照\n\n"
|
|
1478
1521
|
"当前本地行情客户端未加载,无法获取实时行情。\n\n"
|
|
1479
1522
|
f"可运行 `/quote {symbol}` 重试。"
|
|
@@ -1485,18 +1528,22 @@ def _try_handle_market_snapshot_analysis(message: str, history: list = None) ->
|
|
|
1485
1528
|
import time as _time_snap
|
|
1486
1529
|
|
|
1487
1530
|
def _clean_network_error(raw: str) -> str:
|
|
1488
|
-
"""Convert raw exception strings to readable
|
|
1531
|
+
"""Convert raw exception strings to readable messages."""
|
|
1489
1532
|
if "Connection aborted" in raw or "RemoteDisconnected" in raw:
|
|
1490
|
-
return "
|
|
1533
|
+
return ("the server closed the connection; try again shortly" if _en
|
|
1534
|
+
else "网络连接被中断(服务器关闭连接),请稍后重试")
|
|
1491
1535
|
if "Connection refused" in raw:
|
|
1492
|
-
return "
|
|
1536
|
+
return ("connection refused; the data service is unavailable for now" if _en
|
|
1537
|
+
else "连接被拒绝,数据服务暂时不可用")
|
|
1493
1538
|
if "timeout" in raw.lower() or "timed out" in raw.lower():
|
|
1494
|
-
return "连接超时,请稍后重试"
|
|
1539
|
+
return "the connection timed out; try again shortly" if _en else "连接超时,请稍后重试"
|
|
1495
1540
|
if "NoneType" in raw or raw.strip() in ("None", ""):
|
|
1496
|
-
return
|
|
1541
|
+
return _no_price
|
|
1497
1542
|
return raw
|
|
1498
1543
|
|
|
1499
|
-
|
|
1544
|
+
_no_price = "the data source returned no valid price" if _en else "当前数据源未返回有效价格"
|
|
1545
|
+
|
|
1546
|
+
quote = {"success": False, "error": "not initialised" if _en else "未初始化"}
|
|
1500
1547
|
_snapshot_quality = {}
|
|
1501
1548
|
import contextlib as _ctxlib_snapshot
|
|
1502
1549
|
import io as _io_snapshot
|
|
@@ -1653,20 +1700,26 @@ def _try_handle_market_snapshot_analysis(message: str, history: list = None) ->
|
|
|
1653
1700
|
price = _num(quote.get("price"))
|
|
1654
1701
|
|
|
1655
1702
|
if not quote.get("success") or price is None or price == 0:
|
|
1656
|
-
err = quote.get("error") or
|
|
1703
|
+
err = quote.get("error") or _no_price
|
|
1657
1704
|
if "NoneType" in str(err):
|
|
1658
|
-
err =
|
|
1705
|
+
err = _no_price
|
|
1659
1706
|
is_rate_limit = "rate" in str(err).lower() or "429" in str(err) or "too many" in str(err).lower()
|
|
1660
1707
|
if is_rate_limit:
|
|
1661
1708
|
if _fh_tried:
|
|
1662
1709
|
# Finnhub was tried but also failed — both sources exhausted
|
|
1663
|
-
_hint = "\n\n[
|
|
1710
|
+
_hint = ("\n\n[Note] yfinance and Finnhub are both rate-limited; wait 30 seconds and retry."
|
|
1711
|
+
if _en else "\n\n[提示] yfinance 和 Finnhub 均触发频率限制,请稍等 30 秒后重试。")
|
|
1664
1712
|
elif _fh_key:
|
|
1665
1713
|
# Key configured but Finnhub wasn't tried (shouldn't happen, but defensive)
|
|
1666
|
-
_hint = "\n\n[
|
|
1714
|
+
_hint = ("\n\n[Note] The data source is rate-limited; wait 30 seconds and retry."
|
|
1715
|
+
if _en else "\n\n[提示] 数据源请求频率受限,请稍等 30 秒后重试。")
|
|
1667
1716
|
else:
|
|
1668
1717
|
# No Finnhub key — suggest configuring one
|
|
1669
1718
|
_hint = (
|
|
1719
|
+
"\n\n[Note] The data source is rate-limited: wait 30 seconds and retry, "
|
|
1720
|
+
"or add a Finnhub key as a fallback source: `/apikey set finnhub <key>` "
|
|
1721
|
+
"(sign up: https://finnhub.io/register)"
|
|
1722
|
+
) if _en else (
|
|
1670
1723
|
"\n\n[提示] 数据源请求频率受限:请稍等 30 秒后重试,"
|
|
1671
1724
|
"或配置 Finnhub key 使用备用数据源:`/apikey set finnhub <key>`"
|
|
1672
1725
|
"(注册:https://finnhub.io/register)"
|
|
@@ -1676,6 +1729,10 @@ def _try_handle_market_snapshot_analysis(message: str, history: list = None) ->
|
|
|
1676
1729
|
return {
|
|
1677
1730
|
"success": True,
|
|
1678
1731
|
"response": (
|
|
1732
|
+
f"## {symbol} market snapshot\n\n"
|
|
1733
|
+
f"No valid quote right now: {err}{_hint}\n\n"
|
|
1734
|
+
f"Run `/quote {symbol}` to retry; RSI, MACD and support/resistance are withheld until data is back."
|
|
1735
|
+
) if _en else (
|
|
1679
1736
|
f"## {symbol} 市场快照\n\n"
|
|
1680
1737
|
f"当前无法获取有效行情:{err}{_hint}\n\n"
|
|
1681
1738
|
f"可运行 `/quote {symbol}` 重试;在数据恢复前不输出 RSI、MACD 或支撑/阻力位。"
|
|
@@ -2085,22 +2142,8 @@ def _try_handle_market_snapshot_analysis(message: str, history: list = None) ->
|
|
|
2085
2142
|
_price_pos = int((price - low) / _range_size * 100) if _range_size and _range_size > 0 else None
|
|
2086
2143
|
_swing_pct = round(_range_size / price * 100, 2) if _range_size and price else None
|
|
2087
2144
|
_chg_abs = abs(chg) if chg is not None else None
|
|
2088
|
-
_pa_lines = []
|
|
2089
|
-
if _price_pos is not None:
|
|
2090
|
-
_pos_label = "日内高位" if _price_pos >= 70 else ("日内低位" if _price_pos <= 30 else "日内中段")
|
|
2091
|
-
_pa_lines.append(f"价格位置:{_pos_label}(日内第 {_price_pos} 百分位)")
|
|
2092
|
-
if _swing_pct:
|
|
2093
|
-
_pa_lines.append(f"日内振幅:{_swing_pct:.1f}%{'(波动偏大)' if _swing_pct > 3 else ''}")
|
|
2094
|
-
if chg is not None and _chg_abs is not None:
|
|
2095
|
-
if _chg_abs < 0.01:
|
|
2096
|
-
_pa_lines.append("今日动能:持平")
|
|
2097
|
-
else:
|
|
2098
|
-
_mo = "上涨" if chg > 0 else "下跌"
|
|
2099
|
-
_strength = "(大幅)" if _chg_abs > 2 else ("(温和)" if _chg_abs < 0.5 else "")
|
|
2100
|
-
_pa_lines.append(f"今日动能:{_mo} {_chg_abs:.2f}%{_strength}")
|
|
2101
2145
|
|
|
2102
2146
|
# ── Build output ──────────────────────────────────────────────────────
|
|
2103
|
-
weekday = datetime.now().weekday()
|
|
2104
2147
|
ti_provider = ti.get("provider", "")
|
|
2105
2148
|
quote_chain = quote.get("provider_chain") or [provider]
|
|
2106
2149
|
data_src = " -> ".join(str(p) for p in quote_chain if p)
|
|
@@ -2117,8 +2160,11 @@ def _try_handle_market_snapshot_analysis(message: str, history: list = None) ->
|
|
|
2117
2160
|
signal_str = _SIGNAL_LABELS.get(_lang, _SIGNAL_LABELS["zh"])[_sig_key]
|
|
2118
2161
|
_L = {
|
|
2119
2162
|
"disclaimer": "Not investment advice" if _en else "不构成投资建议",
|
|
2120
|
-
"
|
|
2121
|
-
"
|
|
2163
|
+
"session_open": "Market open" if _en else "盘中",
|
|
2164
|
+
"session_pre": "Pre-market" if _en else "盘前",
|
|
2165
|
+
"session_post": "After-hours" if _en else "盘后",
|
|
2166
|
+
"session_closed": "Market closed" if _en else "休市",
|
|
2167
|
+
"session_24/7": "24/7 market" if _en else "全天交易",
|
|
2122
2168
|
"price_hdr": "Metric" if _en else "指标",
|
|
2123
2169
|
"value_hdr": "Value" if _en else "数值",
|
|
2124
2170
|
"latest": "Last price" if _en else "最新价",
|
|
@@ -2163,7 +2209,7 @@ def _try_handle_market_snapshot_analysis(message: str, history: list = None) ->
|
|
|
2163
2209
|
"pos_low": "Lower range" if _en else "日内低位",
|
|
2164
2210
|
"pos_mid": "Mid range" if _en else "日内中段",
|
|
2165
2211
|
"pos_pct": "day percentile" if _en else "百分位",
|
|
2166
|
-
"swing_high": "(high volatility)" if _en else "(波动偏大)",
|
|
2212
|
+
"swing_high": " (high volatility)" if _en else "(波动偏大)",
|
|
2167
2213
|
"flat": "Flat" if _en else "持平",
|
|
2168
2214
|
"rising": "Up" if _en else "上涨",
|
|
2169
2215
|
"falling": "Down" if _en else "下跌",
|
|
@@ -2174,7 +2220,10 @@ def _try_handle_market_snapshot_analysis(message: str, history: list = None) ->
|
|
|
2174
2220
|
"day_swing": "Day swing" if _en else "日内振幅",
|
|
2175
2221
|
}
|
|
2176
2222
|
|
|
2177
|
-
|
|
2223
|
+
_sep = ": " if _en else ":"
|
|
2224
|
+
# On the exchange's clock, not this machine's; nothing when it is unknown.
|
|
2225
|
+
_session = market_session(symbol)
|
|
2226
|
+
session_note = _L.get(f"session_{_session}", "") if _session else ""
|
|
2178
2227
|
|
|
2179
2228
|
def _money(v: float | int | None) -> str:
|
|
2180
2229
|
try:
|
|
@@ -2270,10 +2319,10 @@ def _try_handle_market_snapshot_analysis(message: str, history: list = None) ->
|
|
|
2270
2319
|
lines.append(f"## {_header_name} `{symbol}`")
|
|
2271
2320
|
else:
|
|
2272
2321
|
lines.append(f"## `{symbol}`")
|
|
2273
|
-
lines.append(
|
|
2322
|
+
lines.append("*" + " · ".join(p for p in (data_src, _now_str, session_note, _L["disclaimer"]) if p) + "*")
|
|
2274
2323
|
lines.append("")
|
|
2275
|
-
lines.append(f"**{'Takeaway' if _en else '结论'}
|
|
2276
|
-
lines.append(f"**{'Watch' if _en else '观察位'}
|
|
2324
|
+
lines.append(f"**{'Takeaway' if _en else '结论'}**{_sep}{_summary_line}")
|
|
2325
|
+
lines.append(f"**{'Watch' if _en else '观察位'}**{_sep}{_watch_line}")
|
|
2277
2326
|
lines.append("")
|
|
2278
2327
|
|
|
2279
2328
|
# ── Price table ──
|
|
@@ -2295,7 +2344,8 @@ def _try_handle_market_snapshot_analysis(message: str, history: list = None) ->
|
|
|
2295
2344
|
lines.append("|---------|------|------|")
|
|
2296
2345
|
if rsi is not None:
|
|
2297
2346
|
_rsi_meaning = _L["overbought"] if rsi >= 70 else (_L["oversold"] if rsi <= 30 else _L["neutral"])
|
|
2298
|
-
|
|
2347
|
+
# rsi_view carries a Chinese gloss; the Meaning column says it in English.
|
|
2348
|
+
lines.append(f"| RSI(14) | {f'{rsi:.1f}' if _en else rsi_view} | {_rsi_meaning} |")
|
|
2299
2349
|
else:
|
|
2300
2350
|
lines.append("| RSI(14) | — | — |")
|
|
2301
2351
|
if mhist is not None:
|
|
@@ -2318,17 +2368,19 @@ def _try_handle_market_snapshot_analysis(message: str, history: list = None) ->
|
|
|
2318
2368
|
_pa_lines_l10n = []
|
|
2319
2369
|
if _price_pos is not None:
|
|
2320
2370
|
_pos_label = _L["pos_high"] if _price_pos >= 70 else (_L["pos_low"] if _price_pos <= 30 else _L["pos_mid"])
|
|
2321
|
-
_pa_lines_l10n.append(
|
|
2371
|
+
_pa_lines_l10n.append(
|
|
2372
|
+
f"{_L['day_pos']}: {_pos_label} ({_price_pos}th percentile of the day's range)" if _en else
|
|
2373
|
+
f"{_L['day_pos']}:{_pos_label}(日内第 {_price_pos} {_L['pos_pct']})")
|
|
2322
2374
|
if _swing_pct:
|
|
2323
2375
|
_swing_note = _L["swing_high"] if _swing_pct > 3 else ""
|
|
2324
|
-
_pa_lines_l10n.append(f"{_L['day_swing']}
|
|
2376
|
+
_pa_lines_l10n.append(f"{_L['day_swing']}{_sep}{_swing_pct:.1f}%{_swing_note}")
|
|
2325
2377
|
if chg is not None and _chg_abs is not None:
|
|
2326
2378
|
if _chg_abs < 0.01:
|
|
2327
|
-
_pa_lines_l10n.append(f"{_L['day_momentum']}
|
|
2379
|
+
_pa_lines_l10n.append(f"{_L['day_momentum']}{_sep}{_L['flat']}")
|
|
2328
2380
|
else:
|
|
2329
2381
|
_mo = _L["rising"] if chg > 0 else _L["falling"]
|
|
2330
2382
|
_strength = _L["strong"] if _chg_abs > 2 else (_L["mild"] if _chg_abs < 0.5 else "")
|
|
2331
|
-
_pa_lines_l10n.append(f"{_L['day_momentum']}
|
|
2383
|
+
_pa_lines_l10n.append(f"{_L['day_momentum']}{_sep}{_mo} {_chg_abs:.2f}%{_strength}")
|
|
2332
2384
|
|
|
2333
2385
|
# ── Signal ──
|
|
2334
2386
|
lines.append("")
|
|
@@ -2338,7 +2390,7 @@ def _try_handle_market_snapshot_analysis(message: str, history: list = None) ->
|
|
|
2338
2390
|
if _en else
|
|
2339
2391
|
f" · 量化分 {_signal_score:+d} · 置信度 {_signal_confidence:.0%}"
|
|
2340
2392
|
)
|
|
2341
|
-
lines.append(f"{_L['signal_lbl']}
|
|
2393
|
+
lines.append(f"{_L['signal_lbl']}{_sep}`{signal}` — {signal_str}{_score_detail}")
|
|
2342
2394
|
_reason_parts = []
|
|
2343
2395
|
if _positive_reasons:
|
|
2344
2396
|
_reason_parts.append(("support: " if _en else "支撑:") + _join_reasons(_positive_reasons[:3]))
|
|
@@ -2347,13 +2399,13 @@ def _try_handle_market_snapshot_analysis(message: str, history: list = None) ->
|
|
|
2347
2399
|
if _neutral_reasons:
|
|
2348
2400
|
_reason_parts.append(("neutral: " if _en else "中性:") + _join_reasons(_neutral_reasons[:2]))
|
|
2349
2401
|
if _reason_parts:
|
|
2350
|
-
lines.append(f"**{'Signal drivers' if _en else '信号拆解'}
|
|
2402
|
+
lines.append(f"**{'Signal drivers' if _en else '信号拆解'}**{_sep}" + ("; ".join(_reason_parts) if _en else ";".join(_reason_parts)))
|
|
2351
2403
|
else:
|
|
2352
2404
|
lines.append(_L["pa_hdr"])
|
|
2353
2405
|
for _pal in _pa_lines_l10n:
|
|
2354
2406
|
lines.append(f"- {_pal}")
|
|
2355
2407
|
lines.append("")
|
|
2356
|
-
lines.append(f"{_L['signal_lbl']}
|
|
2408
|
+
lines.append(f"{_L['signal_lbl']}{_sep}`{signal}` — {_L['sig_no_ta']}")
|
|
2357
2409
|
|
|
2358
2410
|
# ── Config hint (show only when TA missing) ──
|
|
2359
2411
|
if not _enough_data:
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""Whether a symbol's exchange is in session, judged on the exchange's clock.
|
|
2
|
+
|
|
3
|
+
Two places judged it on the clock of the machine running Aria. The snapshot
|
|
4
|
+
header said "Market open" on any local weekday, so at 09:00 on Monday in
|
|
5
|
+
Shanghai — Sunday evening in New York — AAPL was "Market open". The context
|
|
6
|
+
sent to the model compared local hours with New York's 09:30–16:00, so a user
|
|
7
|
+
in Beijing had the US market "open" through the New York night.
|
|
8
|
+
|
|
9
|
+
Exchange holidays are not known here: on a holiday the usual hours still read
|
|
10
|
+
as a session. An unknown exchange, or a time zone this machine lacks, gives
|
|
11
|
+
``None``, and callers then say nothing rather than guess.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import re
|
|
17
|
+
from datetime import datetime, time, timezone
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
from zoneinfo import ZoneInfo
|
|
21
|
+
except ImportError: # pragma: no cover - Python < 3.9
|
|
22
|
+
ZoneInfo = None # type: ignore[assignment]
|
|
23
|
+
|
|
24
|
+
_EU = ((time(9, 0), time(17, 30)),)
|
|
25
|
+
|
|
26
|
+
# Exchange -> (time zone, regular sessions in local time).
|
|
27
|
+
_EXCHANGES: dict[str, tuple[str, tuple[tuple[time, time], ...]]] = {
|
|
28
|
+
"US": ("America/New_York", ((time(9, 30), time(16, 0)),)),
|
|
29
|
+
"CN": ("Asia/Shanghai", ((time(9, 30), time(11, 30)), (time(13, 0), time(15, 0)))),
|
|
30
|
+
"HK": ("Asia/Hong_Kong", ((time(9, 30), time(12, 0)), (time(13, 0), time(16, 0)))),
|
|
31
|
+
"JP": ("Asia/Tokyo", ((time(9, 0), time(11, 30)), (time(12, 30), time(15, 30)))),
|
|
32
|
+
"UK": ("Europe/London", ((time(8, 0), time(16, 30)),)),
|
|
33
|
+
"FR": ("Europe/Paris", _EU),
|
|
34
|
+
"DE": ("Europe/Berlin", _EU),
|
|
35
|
+
"NL": ("Europe/Amsterdam", _EU),
|
|
36
|
+
"IT": ("Europe/Rome", _EU),
|
|
37
|
+
"ES": ("Europe/Madrid", _EU),
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
_SUFFIXES = {
|
|
41
|
+
".HK": "HK", ".SS": "CN", ".SZ": "CN", ".SH": "CN", ".T": "JP", ".L": "UK",
|
|
42
|
+
".PA": "FR", ".DE": "DE", ".AS": "NL", ".MI": "IT", ".MC": "ES",
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# US extended hours, New York time.
|
|
46
|
+
_US_PRE = (time(4, 0), time(9, 30))
|
|
47
|
+
_US_POST = (time(16, 0), time(20, 0))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def exchange_for(symbol: str) -> str | None:
|
|
51
|
+
""""US", "CN", "HK", … for a symbol; "CRYPTO" for a coin pair; None if unknown."""
|
|
52
|
+
s = str(symbol or "").strip().upper()
|
|
53
|
+
if not s or s.startswith("^") or s.endswith(("=X", "=F")):
|
|
54
|
+
return None
|
|
55
|
+
if re.fullmatch(r"[A-Z0-9]{2,10}-(USD|USDT|USDC|EUR)", s):
|
|
56
|
+
return "CRYPTO"
|
|
57
|
+
for suffix, exchange in _SUFFIXES.items():
|
|
58
|
+
if s.endswith(suffix):
|
|
59
|
+
return exchange
|
|
60
|
+
if re.fullmatch(r"(SH|SZ)?\d{6}", s):
|
|
61
|
+
return "CN"
|
|
62
|
+
if re.fullmatch(r"[A-Z]{1,5}([.-][A-Z])?", s):
|
|
63
|
+
return "US"
|
|
64
|
+
return None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _local_now(exchange: str, now: datetime | None) -> datetime | None:
|
|
68
|
+
if ZoneInfo is None:
|
|
69
|
+
return None
|
|
70
|
+
try:
|
|
71
|
+
zone = ZoneInfo(_EXCHANGES[exchange][0])
|
|
72
|
+
except Exception: # no tz database on this machine
|
|
73
|
+
return None
|
|
74
|
+
moment = now or datetime.now(timezone.utc)
|
|
75
|
+
if moment.tzinfo is None:
|
|
76
|
+
moment = moment.astimezone() # a naive time is this machine's local time
|
|
77
|
+
return moment.astimezone(zone)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def market_session(symbol: str, now: datetime | None = None) -> str | None:
|
|
81
|
+
""""open", "pre", "post", "closed" or "24/7" for the symbol's exchange; None if unknown."""
|
|
82
|
+
exchange = exchange_for(symbol)
|
|
83
|
+
if exchange == "CRYPTO":
|
|
84
|
+
return "24/7"
|
|
85
|
+
if exchange is None:
|
|
86
|
+
return None
|
|
87
|
+
local = _local_now(exchange, now)
|
|
88
|
+
if local is None:
|
|
89
|
+
return None
|
|
90
|
+
if local.weekday() >= 5:
|
|
91
|
+
return "closed"
|
|
92
|
+
clock = local.time()
|
|
93
|
+
if any(start <= clock < end for start, end in _EXCHANGES[exchange][1]):
|
|
94
|
+
return "open"
|
|
95
|
+
if exchange == "US":
|
|
96
|
+
if _US_PRE[0] <= clock < _US_PRE[1]:
|
|
97
|
+
return "pre"
|
|
98
|
+
if _US_POST[0] <= clock < _US_POST[1]:
|
|
99
|
+
return "post"
|
|
100
|
+
return "closed"
|
|
@@ -1231,6 +1231,33 @@ def _is_blocked_market_symbol_candidate(symbol: str) -> bool:
|
|
|
1231
1231
|
)
|
|
1232
1232
|
|
|
1233
1233
|
|
|
1234
|
+
def _is_english_function_word(message: str, match) -> bool:
|
|
1235
|
+
""""I" the pronoun and "A" the article, read as one-letter tickers.
|
|
1236
|
+
|
|
1237
|
+
"Should I sell my Tesla shares?" came back as a comparison of ``I`` and
|
|
1238
|
+
TSLA, and "I think AAPL is cheap" as a quote for ``I``. "A" is skipped only
|
|
1239
|
+
before a lowercase word ("A good time to buy MSFT?"), so "A股" is still
|
|
1240
|
+
the A-share market; F, T, C and the other one-letter tickers are untouched.
|
|
1241
|
+
"""
|
|
1242
|
+
symbol = match.group(1)
|
|
1243
|
+
if symbol == "I":
|
|
1244
|
+
return True
|
|
1245
|
+
return symbol == "A" and _re_sym.match(r"A [a-z]", message[match.start(1):match.start(1) + 3]) is not None
|
|
1246
|
+
|
|
1247
|
+
|
|
1248
|
+
def _first_bare_ticker(pattern: str, message: str) -> str:
|
|
1249
|
+
"""The first capitalised word the pattern finds, unless it is a blocked term.
|
|
1250
|
+
|
|
1251
|
+
English function words are passed over; a blocked term still ends the
|
|
1252
|
+
search, as it always has, so "Run the API tests for CI" stays no ticker.
|
|
1253
|
+
"""
|
|
1254
|
+
for match in _re_sym.finditer(pattern, message):
|
|
1255
|
+
if _is_english_function_word(message, match):
|
|
1256
|
+
continue
|
|
1257
|
+
return "" if _is_blocked_market_symbol_candidate(match.group(1)) else match.group(1)
|
|
1258
|
+
return ""
|
|
1259
|
+
|
|
1260
|
+
|
|
1234
1261
|
def _extract_market_symbol(message: str) -> str:
|
|
1235
1262
|
"""Extract a likely market symbol from Chinese company names or tickers."""
|
|
1236
1263
|
resolved = _resolve_market_symbol(message)
|
|
@@ -1248,15 +1275,12 @@ def _extract_market_symbol(message: str) -> str:
|
|
|
1248
1275
|
m = _re_sym.search(r'(?<![A-Za-z0-9])(\^[A-Z0-9]{2,10}|[A-Z]{2,8}=F|[A-Z]{6}=X|DX-Y\.NYB)(?![A-Za-z0-9])', message, _re_sym.I)
|
|
1249
1276
|
if m:
|
|
1250
1277
|
return m.group(1).upper()
|
|
1251
|
-
|
|
1252
|
-
if
|
|
1253
|
-
return
|
|
1278
|
+
symbol = _first_bare_ticker(r'\b([A-Z]{1,5}(?:\.(?:HK|SH|SZ))?)\b', message)
|
|
1279
|
+
if symbol:
|
|
1280
|
+
return symbol
|
|
1254
1281
|
# Chinese text immediately after a ticker ("AAPL的市场") prevents \b from
|
|
1255
1282
|
# matching because Unicode word-boundary rules treat 的 as a word char.
|
|
1256
|
-
|
|
1257
|
-
if m and not _is_blocked_market_symbol_candidate(m.group(1)):
|
|
1258
|
-
return m.group(1)
|
|
1259
|
-
return ""
|
|
1283
|
+
return _first_bare_ticker(r'(?<![A-Za-z])([A-Z]{1,5}(?:\.(?:HK|SH|SZ))?)(?![A-Za-z])', message)
|
|
1260
1284
|
|
|
1261
1285
|
def _extract_market_symbols(message: str, limit: int = 6) -> list[str]:
|
|
1262
1286
|
"""Extract all likely market symbols, preserving mention order."""
|
|
@@ -1289,12 +1313,12 @@ def _extract_market_symbols(message: str, limit: int = 6) -> list[str]:
|
|
|
1289
1313
|
|
|
1290
1314
|
for match in _re_sym.finditer(r'\b([A-Z]{1,5}(?:\.(?:HK|SH|SZ))?)\b', message):
|
|
1291
1315
|
symbol = match.group(1)
|
|
1292
|
-
if not _is_blocked_market_symbol_candidate(symbol):
|
|
1316
|
+
if not _is_blocked_market_symbol_candidate(symbol) and not _is_english_function_word(message, match):
|
|
1293
1317
|
add_hit(match.start(), symbol)
|
|
1294
1318
|
|
|
1295
1319
|
for match in _re_sym.finditer(r'(?<![A-Za-z])([A-Z]{1,5}(?:\.(?:HK|SH|SZ))?)(?![A-Za-z])', message):
|
|
1296
1320
|
symbol = match.group(1)
|
|
1297
|
-
if not _is_blocked_market_symbol_candidate(symbol):
|
|
1321
|
+
if not _is_blocked_market_symbol_candidate(symbol) and not _is_english_function_word(message, match):
|
|
1298
1322
|
add_hit(match.start(), symbol)
|
|
1299
1323
|
|
|
1300
1324
|
ordered: list[str] = []
|
|
@@ -1507,12 +1531,19 @@ def _detect_market_overview(message: str):
|
|
|
1507
1531
|
return None
|
|
1508
1532
|
|
|
1509
1533
|
|
|
1510
|
-
def _is_market_snapshot_request(message: str, history: list = None
|
|
1534
|
+
def _is_market_snapshot_request(message: str, history: list = None, *,
|
|
1535
|
+
evidence_required: bool = False) -> bool:
|
|
1511
1536
|
"""Return True for simple quote / market snapshot analysis requests.
|
|
1512
1537
|
|
|
1513
1538
|
跟进问题("现在的股票和趋势呢"):当前消息无标的时回溯会话历史继承。
|
|
1514
1539
|
但如果消息中包含未能识别的公司名,则不视为跟进问题(不继承历史标的)。
|
|
1515
1540
|
房价/楼市类问题直接拒绝,防止继承上一个股票代码。
|
|
1541
|
+
|
|
1542
|
+
``evidence_required`` is the evidence gate's verdict on this message. When
|
|
1543
|
+
the gate will refuse an answer without data and the message names an
|
|
1544
|
+
instrument, it is a snapshot request whatever its wording: the word lists
|
|
1545
|
+
below were written for Chinese, so "How's NVDA this week?" matched none of
|
|
1546
|
+
them, nothing fetched data on a route without tools, and the gate refused.
|
|
1516
1547
|
"""
|
|
1517
1548
|
# Real-estate questions must never be routed to the stock snapshot path
|
|
1518
1549
|
if _is_realty_query(message):
|
|
@@ -1528,6 +1559,8 @@ def _is_market_snapshot_request(message: str, history: list = None) -> bool:
|
|
|
1528
1559
|
_is_coding = any(k in message.lower() for k in _coding_kw)
|
|
1529
1560
|
if _is_coding or _is_stock_chart_analysis_request(message) or _is_visual_market_artifact_request(message):
|
|
1530
1561
|
return False
|
|
1562
|
+
if evidence_required and _extract_market_symbol(message):
|
|
1563
|
+
return True
|
|
1531
1564
|
low = message.lower()
|
|
1532
1565
|
# Unambiguously market-specific wording. These carry enough intent on their
|
|
1533
1566
|
# own to inherit a symbol from an earlier turn ("行情呢" / "现价多少").
|