aria-code 0.64.0__tar.gz → 0.65.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.64.0 → aria_code-0.65.0}/PKG-INFO +1 -1
- {aria_code-0.64.0 → aria_code-0.65.0}/pyproject.toml +1 -1
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/_version.py +1 -1
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/channels/README.md +15 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/channels/conversation.py +6 -0
- aria_code-0.65.0/src/aria_code/apps/channels/digest.py +185 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/aria_daemon.py +33 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/aria_feishu_bot.py +48 -5
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code.egg-info/PKG-INFO +1 -1
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code.egg-info/SOURCES.txt +2 -0
- aria_code-0.65.0/tests/test_shipper_digest.py +241 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/LICENSE +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/NOTICE +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/README.md +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/setup.cfg +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/adk_apps/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/adk_apps/aria_code_review/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/adk_apps/aria_code_review/agent.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/adk_apps/aria_research/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/adk_apps/aria_research/agent.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/base.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/code_review.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/deep/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/deep/calibration_loop.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/deep/critic.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/deep/deepen.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/deep/models.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/deep/pipeline.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/deep/quant_fusion.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/deep/themes.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/deep/tiers.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/engineering/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/engineering/coder.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/engineering/tester.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/financial/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/financial/cashflow_burn.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/financial/catalyst.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/financial/corporate_finance.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/financial/debate.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/financial/earnings.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/financial/fundamental.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/financial/macro.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/financial/news.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/financial/risk.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/financial/sector.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/financial/strategist.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/financial/stripe_revenue.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/financial/synthesis.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/financial/technical.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/orchestrator.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/portfolio_agent.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/realty/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/realty/asset_diagnosis.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/realty/business_match.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/realty/cashflow_verify.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/realty/contract_rules.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/realty/energy_anomaly.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/realty/exit_settlement.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/realty/fulfillment_risk.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/realty/ops_optimize.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/realty/revenue_share.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/registry.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/signal_scheme.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/sports/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/sports/football_agent.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/supervisor.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/team.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/warehouse/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/warehouse/contracts.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/warehouse/dashboard.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/warehouse/fulfillment_leadtime.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/warehouse/inbound_exceptions.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/warehouse/inventory_health.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/warehouse/local_run.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/warehouse/local_snapshot.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/warehouse/logistics_cost.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/warehouse/logistics_sync.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/agents/warehouse/workflow.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/aliyun_data_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/README.md +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/channels/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/channels/intake.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/channels/registry.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/channels/tradingview.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/README.md +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/_optional.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/bootstrap.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/broker_render.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/codegen_paths.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/_business_render.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/_ui.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/analysis_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/ashare_prediction_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/auth_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/backtest_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/broker_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/business_workflow_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/canvas_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/catalog.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/core_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/data_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/diagnostic_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/diagnostic_ops_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/file_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/finance_service_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/fx_commodity_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/market.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/market_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/market_context.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/market_render.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/model_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/ops_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/orchestrator_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/pdf_export_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/portfolio_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/report.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/scaffold_templates.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/session_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/session_ux_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/team.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/team_render.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/ui_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/warehouse_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/workflow_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/commands/workspace_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/config_paths.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/config_store.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/constants.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/context.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/deterministic.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/direct.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/finance_service_catalog.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/football_reports.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/github_app_auth.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/google_login.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/handlers/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/handlers/broker_handlers.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/handlers/chart_handlers.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/handlers/market_handlers.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/handlers/realty_handlers.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/handlers/sports_handlers.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/handlers/strategy_advice.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/helpers.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/hooks.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/i18n.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/intent.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/intent_router.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/intent_signals.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/lifecycle_hooks.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/local_tool_schemas.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/main.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/market_metadata.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/market_universe.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/message_processing.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/model_catalog.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/pdf_report.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/plan_mode.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/plotly_html.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/prediction_feedback.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/preflight.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/project_aria.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/prompt_assembly.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/prompts/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/prompts/coding.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/prompts/select.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/prompts/system_prompts.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/prompts/ui.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/provider_endpoints.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/provider_keys.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/providers/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/providers/base.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/providers/chat_routing.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/providers/collaboration.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/providers/llm/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/providers/llm/offline_responses.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/providers/llm/ollama_stream.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/providers/llm/response_cache.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/providers/llm/sse_stream.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/providers/runtime_bridge.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/providers/vertexai_stream.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/runtime_consumer.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/sandbox.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/session_export.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/session_jsonl.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/session_store.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/skills_catalog.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/todo_tracker.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/tool_executor.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/tool_registry.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/tool_scope.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/tools/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/tools/context.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/tools/file_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/tools/market_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/tools/notebook_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/tools/system_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/tools/write_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/tradingview_bridge.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/turn_planning.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/update_check.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/utils/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/cli/utils/market_detect.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/daemon/README.md +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/vscode/README.md +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/apps/vscode/package.json +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/aria_cli.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/aria_mcp_server.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/aria_relay_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/aria_relay_server.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/aria_telegram_bot.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ariarc.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/artifacts.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/backtest_engine.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/backtest_report.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/automation.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/base.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/capabilities.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/cn/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/cn/easytrader_broker.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/cn/futu_broker.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/cn/longbridge_broker.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/cn/tiger_broker.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/cn/xtquant_broker.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/config.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/intl/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/intl/alpaca_broker.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/intl/ibkr_broker.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/intl/trading212_broker.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/intl/webull_broker.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/paper_broker.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/planning.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/registry.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/brokers/trading.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/canva_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/change_store.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/clients/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/clients/aliyun_data_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/clients/aria_relay_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/clients/canva_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/clients/figma_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/clients/football_data_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/clients/kling_video_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/clients/market_data_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/clients/openai_image_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/clients/runway_video_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/clients/warehouse_erp_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/cloud_memory.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/command_safety.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/computer_use_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/dashboard_generator.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/data_analysis_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/data_cleaner.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/data_service.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/datasources/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/datasources/base.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/datasources/router.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/datasources/sources/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/datasources/sources/akshare_source.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/datasources/sources/alpha_vantage_source.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/datasources/sources/edgar_source.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/datasources/sources/finnhub_source.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/datasources/sources/fred_source.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/datasources/sources/tushare_source.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/datasources/sources/web_scraper_source.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/datasources/sources/world_bank_source.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/datasources/sources/yfinance_source.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/demo_player.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/doctor.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/domain/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/domain/backtest_engine.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/domain/backtest_report.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/domain/finance_formulas.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/domain/portfolio_ledger.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/domain/strategy_vault.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/evals/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/evals/harness.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/evals/runner.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/external_agent_runner.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/figma_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/file_analysis_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/finance_formulas.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/football_data_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/image_gen_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/intent_classifier.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/kling_video_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/licensing.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/local_finance_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/local_image_provider.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/local_llm_provider.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/macro_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/markdown_pdf.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/market_data_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/mcp_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/memory_manager.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/model_capability.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/notification_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/openai_image_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/adk_bridge/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/adk_bridge/code_review_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/adk_bridge/market_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_agents/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_agents/manifest.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_core/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_core/architecture.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_core/export.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_core/manifest.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_core/paths.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_core/secure_file.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_infra/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_infra/arthera.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_infra/doctor.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_infra/product.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_mcp/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_mcp/bridge.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_mcp/circuit.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_mcp/config.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_mcp/installer.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_mcp/server.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_mcp/tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_sdk/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_sdk/client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_sdk/providers.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_sdk/streaming.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_sdk/types.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_services/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_services/cache.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_services/context.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_services/context_checkpoints.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_services/data.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_services/provider_health.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_services/references.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_services/registry.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_services/research_protocol.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_services/research_quality.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_services/settings.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_services/usage.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_skills/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_skills/catalog.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_skills/loader.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_skills/registry.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_tools/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_tools/financial/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_tools/financial/_paths.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_tools/financial/compliance.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_tools/financial/factors.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_tools/financial/risk_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_tools/financial/strategy.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/aria_tools/registry.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/_namespace.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/backtest/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/backtest/core.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/backtest/engine.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/portfolio/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/portfolio/optimizer.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/sports/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/sports/calibrator.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/sports/dixon_coles.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/sports/elo.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/sports/form.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/sports/h2h.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/sports/ml_model.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/sports/predictor.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/sports/tracker.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/stochastic/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/stochastic/ito_calculus.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/stochastic/kelly_criterion.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/stochastic/options_pricing.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packages/quant_engine/stochastic/stochastic_processes.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packs/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packs/base.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packs/finance/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packs/logistics/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packs/payments/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packs/realty/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packs/registry.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/packs/rules.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/plan_utils.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/plugin_loader.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/portfolio_ledger.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/preview_server.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/privacy/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/privacy/feedback.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/project_review.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/project_review_api.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/project_review_server.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/project_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/providers/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/providers/llm/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/providers/llm/anthropic.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/providers/llm/autoconfig.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/providers/llm/base.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/providers/llm/custom.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/providers/llm/ollama.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/providers/llm/openai_compat.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/providers/llm/registry.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/providers/local_image_provider.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/providers/local_llm_provider.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/realty_data_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/report_exporters.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/report_generator.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/acceptance.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/agent_loop.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/approval.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/budget.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/checkpoints.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/crash_report.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/events.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/gateway.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/lsp.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/orchestrator.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/repo_map.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/run_state.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/run_store.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/self_healing.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/subagent.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/task_ledger.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/task_orchestrator.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/tool_executor.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/tool_policy.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runtime/worktrees.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/runway_video_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/safety/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/safety/permissions.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/safety/service.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/setup_wizard.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/spreadsheet_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/strategy_vault.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/artifact_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/broker_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/build_quant_engine.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/code_audit_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/computer_use_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/data_analysis_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/enterprise_finance_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/extended_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/file_analysis_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/image_gen_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/local_finance_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/logistics_carriers.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/logistics_inventory.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/logistics_io.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/logistics_tenancy.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/logistics_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/macro_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/notification_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/project_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/realty_data_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/spreadsheet_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/tools/stripe_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ui/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ui/banner.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ui/completer.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ui/console.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ui/image_render.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ui/input_box.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ui/picker.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ui/render/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ui/render/finance.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ui/render/market.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ui/render/output.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ui/render/responsive.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ui/render/team.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ui/robot.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/ui/startup_dashboard.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/utils/vscode_uri.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/video_analysis.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/video_editor.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/workspace/__init__.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/workspace/files.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/workspace/verify.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/workspace_changes.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/workspace_context.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/workspace_service.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code/workspace_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code.egg-info/dependency_links.txt +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code.egg-info/entry_points.txt +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code.egg-info/requires.txt +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/src/aria_code.egg-info/top_level.txt +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_adk_market_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_agent_team_fallback.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_analyze_file_tool.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_architecture_ledger_is_true.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_architecture_report.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_aria_cli_core.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_aria_mcp_server.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_aria_sdk.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_artifact_publishing.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_artifacts_and_reports.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_ashare_prediction_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_backtest_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_backtest_engine.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_backtest_report.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_binary_bundles_runtime_imports.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_broken_akshare_is_optional.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_broker_automation.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_broker_chat_confirm_gate.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_broker_planning.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_broker_safety.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_broker_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_budget.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_business_workflow_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_canva_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_canvas_cmds.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_channel_intake.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_channels.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_chart_handlers.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_chat_bots_fail_closed.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_chat_routing.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_ci_security_workflow.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_cli_app_split.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_cli_bootstrap.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_cli_config_store.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_cli_lifecycle_hooks.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_cli_runtime_consumer.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_cli_tool_executor_module.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_cloud_memory.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_code_audit_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_code_review_agent.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_codegen_output.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_coder_tester_self_healing.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_coder_tool_safety.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_collaboration.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_command_loggers.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_command_safety.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_completions_builder.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_config_paths.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_configured_provider.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_container_entrypoint.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_container_entrypoints.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_context_checkpoints.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_context_references.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_context_service.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_conversation_core.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_crash_report.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_credential_file_permissions.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_custom_providers.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_daemon_gateway_config.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_dashboard_generator.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_data_service.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_data_service_imports.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_datasource_routing.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_deep_analysis.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_degrades_without_quant_engine.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_dispatcher_pins_match_the_release.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_doctor.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_doctor_describes_the_current_install.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_doctor_npm_scope.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_engine_boundary.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_enterprise_tool_honesty.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_env_switch_docs.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_evals_harness.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_extended_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_feishu_swarm_config.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_finance_renderers.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_finance_service_catalog.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_first_run_works.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_football_agent.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_football_prediction_output.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_google_cloud_routing.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_google_login.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_google_search_provider.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_headless_is_agentic.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_image_gen_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_image_inputs.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_import_graph_budget.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_intent_router.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_intent_signals.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_kling_video_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_lazy_rebind.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_legacy_module_imports.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_license_consistency.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_licensing.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_local_image_provider.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_logistics_3pl.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_logistics_and_finance_agents.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_lsp.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_markdown_pdf.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_market_data_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_market_history_inheritance.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_market_history_tool.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_market_symbol_extraction.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_market_universe.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_mcp_circuit.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_mcp_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_model_capability_registry.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_model_choice_is_the_users.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_model_selection_state.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_native_binary_entrypoints.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_native_installer.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_new_modules.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_no_hardcoded_developer_paths.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_no_uncommitted_imports.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_ollama_stream_imports.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_ollama_stream_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_openai_image_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_operations_suite.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_output_rendering.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_packages_facade.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_packaging_constraints.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_packaging_manifest.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_packs_domains.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_pdf_report.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_pick_best_installed_model.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_plan_mode.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_platform_package_assembly.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_platform_packages.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_plotly_html_output.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_portfolio_ledger.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_post_turn_context_decision.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_preflight.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_preview_server.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_privacy_feedback.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_project_aria.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_project_review.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_project_review_api.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_prompt_assembly.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_prompt_selection.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_provider_autoconfig.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_provider_error_messages.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_provider_integration.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_provider_registry.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_public_service_status.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_quant_engine_namespace.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_rebind_contract.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_rebind_namespace_contract.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_relay_event_verification.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_release_chain.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_release_commit_identity.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_release_push_is_atomic.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_release_reaches_the_registries.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_release_verification_waits.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_release_workflow_permissions.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_report_charts.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_report_generator.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_research_protocol.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_research_quality.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_responsive_rendering.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_root_module_budget.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_rsi_without_pandas_ta.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_runtime_acceptance.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_runtime_agent_loop.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_runtime_approval.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_runtime_bridge.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_runtime_bridge_fallback.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_runtime_checkpoints.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_runtime_gateway.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_runtime_repo_map.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_runtime_run_store.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_runtime_tool_executor.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_runtime_worktrees.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_runway_video_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_safety_permissions.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_safety_service.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_safety_service_adoption.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_service_diagnostics_security.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_session_search.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_settings_service.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_single_import_root.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_skill_agent_binding.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_skill_catalog.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_skill_loader.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_spreadsheet_tools.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_sse_stream_contract.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_startup_dashboard.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_streaming_pipeline.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_stripe_agent.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_subagent.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_supervisor_routing.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_system_prompts.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_system_tools_output.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_task_orchestrator.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_team_synthesis.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_tls_trust_store.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_tool_policy.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_tool_scope.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_trading_service.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_tradingview_bridge.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_turn_planning.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_ui_completer_references.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_ui_console_theme.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_ui_input_box.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_ui_robot_banner.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_verification_hint.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_verification_policy.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_version_consistency.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_version_counter.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_video_analysis.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_video_editor.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_vscode_mcp.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_warehouse_agents.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_warehouse_cli_registration.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_warehouse_erp_client.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_warehouse_workflow.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_wheel_is_installable.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_workspace_changes.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_workspace_context.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_workspace_files.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_workspace_scope.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_workspace_service.py +0 -0
- {aria_code-0.64.0 → aria_code-0.65.0}/tests/test_workspace_verify.py +0 -0
|
@@ -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.65.0"
|
|
8
8
|
description = "AI coding and research workspace with optional finance and connected-domain tools"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "Apache-2.0" }
|
|
@@ -45,3 +45,18 @@ send(reply)
|
|
|
45
45
|
`aria_feishu_bot.feishu_inbound` is the Feishu version of that first step.
|
|
46
46
|
Conversation keys are `<channel>:<conversation id>`, so the same chat id on
|
|
47
47
|
two platforms is two conversations.
|
|
48
|
+
|
|
49
|
+
## The shipper digest (`digest.py`)
|
|
50
|
+
|
|
51
|
+
The first thing the conversation layer enables that a reply-only bot cannot:
|
|
52
|
+
each group bound to a shipper is sent, unprompted, what needs attention —
|
|
53
|
+
reorders, SKUs with too little history to plan, dead stock, waybills to query,
|
|
54
|
+
and safe carrier switches. `run_digests(store, senders)` walks the bindings and
|
|
55
|
+
hands each digest to that channel's sender, so a new channel registers a
|
|
56
|
+
`(conversation_id, title, body) -> bool` function and gets the digest too.
|
|
57
|
+
|
|
58
|
+
Data comes from the operator's `ARIA_SHIPPER_FEEDS` file, never from chat, and
|
|
59
|
+
is read through the logistics tools under `ARIA_OWNER_SCOPE`, so a shared
|
|
60
|
+
multi-shipper export yields only that shipper's lines. Configuration problems
|
|
61
|
+
go to the log, not the client's group; a day with nothing to report sends
|
|
62
|
+
nothing.
|
|
@@ -192,6 +192,12 @@ class ConversationStore:
|
|
|
192
192
|
with self._db() as db:
|
|
193
193
|
db.execute("DELETE FROM bindings WHERE conversation = ?", (key,))
|
|
194
194
|
|
|
195
|
+
def bindings(self) -> List[Tuple[str, str]]:
|
|
196
|
+
"""Every (conversation key, shipper) binding, for jobs that push to them."""
|
|
197
|
+
with self._db() as db:
|
|
198
|
+
return [tuple(row) for row in db.execute(
|
|
199
|
+
"SELECT conversation, owner_id FROM bindings ORDER BY conversation")]
|
|
200
|
+
|
|
195
201
|
def owner_for(self, key: str) -> Optional[str]:
|
|
196
202
|
with self._db() as db:
|
|
197
203
|
row = db.execute("SELECT owner_id FROM bindings WHERE conversation = ?", (key,)).fetchone()
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"""The daily shipper digest: what needs attention, pushed to the shipper's group.
|
|
2
|
+
|
|
3
|
+
A bot that only answers questions waits to be asked about the SKU that ran out
|
|
4
|
+
yesterday. This sends each shipper's group, unprompted, what the 3PL would
|
|
5
|
+
otherwise find out too late: what to reorder, what history is too thin to
|
|
6
|
+
plan from, what stock has stopped moving, which waybills to query with the
|
|
7
|
+
carrier, and where a cheaper carrier is at least as reliable.
|
|
8
|
+
|
|
9
|
+
Platform-neutral like the rest of apps/channels: it walks the conversations
|
|
10
|
+
bound to a shipper (ConversationStore) and hands each digest to that
|
|
11
|
+
channel's sender. Feishu is the first sender; another channel registers one.
|
|
12
|
+
|
|
13
|
+
Where the data comes from is the operator's decision, not the chat's:
|
|
14
|
+
ARIA_SHIPPER_FEEDS names a JSON file mapping each shipper to its exports —
|
|
15
|
+
|
|
16
|
+
{"ACME": {"inventory": "/data/acme/skus.csv", "waybills": "/data/acme/waybills.csv"},
|
|
17
|
+
"*": {"inventory": "/data/wms/all_skus.csv"}}
|
|
18
|
+
|
|
19
|
+
"*" is the fallback for shippers without their own entry, typically one
|
|
20
|
+
multi-shipper export. Letting a chat command set a path would let anyone in
|
|
21
|
+
the group read any CSV on the host.
|
|
22
|
+
|
|
23
|
+
Every number comes from plan_inventory_policy and score_carriers, run with
|
|
24
|
+
ARIA_OWNER_SCOPE set to the shipper — the same tool-level confinement a bound
|
|
25
|
+
conversation gets — so a shared multi-shipper export yields only that
|
|
26
|
+
shipper's lines, and a file without owner_id is refused rather than guessed.
|
|
27
|
+
Digests are built one at a time: the scope is process environment, and the
|
|
28
|
+
tools are synchronous, so nothing else runs while it is set.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from __future__ import annotations
|
|
32
|
+
|
|
33
|
+
import json
|
|
34
|
+
import logging
|
|
35
|
+
import os
|
|
36
|
+
from contextlib import contextmanager
|
|
37
|
+
from dataclasses import dataclass, field
|
|
38
|
+
from pathlib import Path
|
|
39
|
+
from typing import Awaitable, Callable, Dict, Iterator, List, Optional
|
|
40
|
+
|
|
41
|
+
from aria_code.apps.channels.conversation import ConversationStore
|
|
42
|
+
from aria_code.tools.logistics_tenancy import OWNER_SCOPE_ENV
|
|
43
|
+
|
|
44
|
+
logger = logging.getLogger(__name__)
|
|
45
|
+
|
|
46
|
+
FEEDS_ENV = "ARIA_SHIPPER_FEEDS"
|
|
47
|
+
MAX_LINES = 8 # per section; a digest is a prompt to look, not the report
|
|
48
|
+
|
|
49
|
+
# (conversation_id, title, body) -> delivered?
|
|
50
|
+
Sender = Callable[[str, str, str], Awaitable[bool]]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@dataclass
|
|
54
|
+
class Digest:
|
|
55
|
+
owner_id: str
|
|
56
|
+
title: str
|
|
57
|
+
body: str = ""
|
|
58
|
+
items: int = 0
|
|
59
|
+
problems: List[str] = field(default_factory=list)
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def worth_sending(self) -> bool:
|
|
63
|
+
return self.items > 0
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def load_feeds(path: Optional[str] = None) -> Dict[str, Dict[str, str]]:
|
|
67
|
+
"""The operator's shipper → export files map; {} when not configured."""
|
|
68
|
+
source = path or os.environ.get(FEEDS_ENV, "").strip()
|
|
69
|
+
if not source:
|
|
70
|
+
return {}
|
|
71
|
+
data = json.loads(Path(source).expanduser().read_text(encoding="utf-8"))
|
|
72
|
+
if not isinstance(data, dict):
|
|
73
|
+
raise ValueError(f"{FEEDS_ENV} must be a JSON object of shipper -> feeds")
|
|
74
|
+
return {str(k): {kind: str(v) for kind, v in (feeds or {}).items()} for k, feeds in data.items()}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def feeds_for(owner_id: str, feeds: Dict[str, Dict[str, str]]) -> Dict[str, str]:
|
|
78
|
+
return feeds.get(owner_id) or feeds.get("*") or {}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@contextmanager
|
|
82
|
+
def _confined_to(owner_id: str) -> Iterator[None]:
|
|
83
|
+
previous = os.environ.get(OWNER_SCOPE_ENV)
|
|
84
|
+
os.environ[OWNER_SCOPE_ENV] = owner_id
|
|
85
|
+
try:
|
|
86
|
+
yield
|
|
87
|
+
finally:
|
|
88
|
+
if previous is None:
|
|
89
|
+
os.environ.pop(OWNER_SCOPE_ENV, None)
|
|
90
|
+
else:
|
|
91
|
+
os.environ[OWNER_SCOPE_ENV] = previous
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _section(title: str, lines: List[str]) -> str:
|
|
95
|
+
shown = lines[:MAX_LINES]
|
|
96
|
+
more = f"\n- …另有 {len(lines) - MAX_LINES} 项" if len(lines) > MAX_LINES else ""
|
|
97
|
+
return f"**{title}({len(lines)})**\n" + "\n".join(f"- {line}" for line in shown) + more
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def build_digest(owner_id: str, feeds: Dict[str, Dict[str, str]]) -> Digest:
|
|
101
|
+
from aria_code.tools.logistics_carriers import tool_score_carriers
|
|
102
|
+
from aria_code.tools.logistics_inventory import tool_plan_inventory_policy
|
|
103
|
+
|
|
104
|
+
digest = Digest(owner_id=owner_id, title=f"📦 {owner_id} 今日库存与运费提醒")
|
|
105
|
+
sources = feeds_for(owner_id, feeds)
|
|
106
|
+
sections: List[str] = []
|
|
107
|
+
|
|
108
|
+
with _confined_to(owner_id):
|
|
109
|
+
if sources.get("inventory"):
|
|
110
|
+
result = tool_plan_inventory_policy({"file_path": sources["inventory"]})
|
|
111
|
+
if result.get("success"):
|
|
112
|
+
items = result["data"]["items"]
|
|
113
|
+
reorder = [i for i in items if i.get("action") == "reorder"]
|
|
114
|
+
thin = [i for i in items if i.get("action") == "insufficient_history"]
|
|
115
|
+
dead = [i for i in items if i.get("movement") == "dead"]
|
|
116
|
+
if reorder:
|
|
117
|
+
sections.append(_section("建议补货", [
|
|
118
|
+
f"{i['sku']}:订 {i['suggested_order_qty']}(现有可用 {i['inventory_position']:g},"
|
|
119
|
+
f"补货点 {i['reorder_point']},约可撑 {i['days_of_cover']} 天)" for i in reorder]))
|
|
120
|
+
if thin:
|
|
121
|
+
sections.append(_section("历史不足、未给建议", [
|
|
122
|
+
f"{i['sku']}:仅 {i['history_days']} 天出库记录" for i in thin]))
|
|
123
|
+
if dead:
|
|
124
|
+
sections.append(_section("呆滞库存", [
|
|
125
|
+
f"{i['sku']}:在库 {i['on_hand']:g}" for i in dead]))
|
|
126
|
+
digest.items += len(reorder) + len(thin) + len(dead)
|
|
127
|
+
else:
|
|
128
|
+
digest.problems.append(f"inventory: {result.get('error')}")
|
|
129
|
+
|
|
130
|
+
if sources.get("waybills"):
|
|
131
|
+
result = tool_score_carriers({"file_path": sources["waybills"]})
|
|
132
|
+
if result.get("success"):
|
|
133
|
+
data = result["data"]
|
|
134
|
+
anomalies, savings = data.get("anomalies") or [], data.get("savings") or []
|
|
135
|
+
if anomalies:
|
|
136
|
+
sections.append(_section("运费待核对", [
|
|
137
|
+
f"{a['waybill_no']}({a['carrier']} {a['lane']}):{a['detail']}" for a in anomalies]))
|
|
138
|
+
if savings:
|
|
139
|
+
sections.append(_section("可节省的线路", [
|
|
140
|
+
f"{s['lane']}:{s['from_carrier']} → {s['to_carrier']},"
|
|
141
|
+
f"按近期运量约省 {s['estimated_saving']:g}(准时率不低于现承运商)" for s in savings]))
|
|
142
|
+
digest.items += len(anomalies) + len(savings)
|
|
143
|
+
else:
|
|
144
|
+
digest.problems.append(f"waybills: {result.get('error')}")
|
|
145
|
+
|
|
146
|
+
if not sources:
|
|
147
|
+
digest.problems.append(f"no feeds configured for {owner_id}")
|
|
148
|
+
digest.body = "\n\n".join(sections) + (
|
|
149
|
+
"\n\n建议数量未计入起订量、箱规和供应商条款;运费异常请先与承运商核对再下结论。" if sections else "")
|
|
150
|
+
return digest
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
async def run_digests(store: ConversationStore, senders: Dict[str, Sender],
|
|
154
|
+
feeds: Optional[Dict[str, Dict[str, str]]] = None) -> List[Dict[str, str]]:
|
|
155
|
+
"""Send today's digest to every bound conversation that has something to say.
|
|
156
|
+
|
|
157
|
+
Returns one record per conversation for the log. Problems — a missing
|
|
158
|
+
feed, a file the tenancy check refused — go to the log only: a client's
|
|
159
|
+
group is not where a 3PL's configuration errors belong.
|
|
160
|
+
"""
|
|
161
|
+
feeds = load_feeds() if feeds is None else feeds
|
|
162
|
+
report: List[Dict[str, str]] = []
|
|
163
|
+
built: Dict[str, Digest] = {}
|
|
164
|
+
for conversation, owner_id in store.bindings():
|
|
165
|
+
channel, _, conversation_id = conversation.partition(":")
|
|
166
|
+
send = senders.get(channel)
|
|
167
|
+
if send is None:
|
|
168
|
+
report.append({"conversation": conversation, "status": "no_sender"})
|
|
169
|
+
continue
|
|
170
|
+
if owner_id not in built:
|
|
171
|
+
try:
|
|
172
|
+
built[owner_id] = build_digest(owner_id, feeds)
|
|
173
|
+
except Exception as exc: # one bad feed must not stop the others
|
|
174
|
+
logger.warning("digest for %s failed: %s", owner_id, exc)
|
|
175
|
+
report.append({"conversation": conversation, "status": "error"})
|
|
176
|
+
continue
|
|
177
|
+
digest = built[owner_id]
|
|
178
|
+
for problem in digest.problems:
|
|
179
|
+
logger.warning("digest %s: %s", owner_id, problem)
|
|
180
|
+
if not digest.worth_sending:
|
|
181
|
+
report.append({"conversation": conversation, "status": "nothing_to_report"})
|
|
182
|
+
continue
|
|
183
|
+
delivered = await send(conversation_id, digest.title, digest.body)
|
|
184
|
+
report.append({"conversation": conversation, "status": "sent" if delivered else "send_failed"})
|
|
185
|
+
return report
|
|
@@ -1080,6 +1080,25 @@ async def _execute_job(job: dict) -> None:
|
|
|
1080
1080
|
conn.commit()
|
|
1081
1081
|
|
|
1082
1082
|
|
|
1083
|
+
# ── Shipper digest ───────────────────────────────────────────────────────────
|
|
1084
|
+
|
|
1085
|
+
async def _run_shipper_digests() -> None:
|
|
1086
|
+
"""Push each bound shipper group its digest (apps/channels/digest.py)."""
|
|
1087
|
+
try:
|
|
1088
|
+
from apps.channels.conversation import ConversationStore
|
|
1089
|
+
from apps.channels.digest import run_digests
|
|
1090
|
+
|
|
1091
|
+
senders = {}
|
|
1092
|
+
if os.environ.get("FEISHU_APP_ID") and os.environ.get("FEISHU_APP_SECRET"):
|
|
1093
|
+
from aria_feishu_bot import send_digest_card
|
|
1094
|
+
senders["feishu"] = send_digest_card
|
|
1095
|
+
report = await run_digests(ConversationStore(), senders)
|
|
1096
|
+
for line in report:
|
|
1097
|
+
logger.info("shipper digest %s: %s", line["conversation"], line["status"])
|
|
1098
|
+
except Exception as exc:
|
|
1099
|
+
logger.error("shipper digest job failed: %s", exc)
|
|
1100
|
+
|
|
1101
|
+
|
|
1083
1102
|
# ── APScheduler cron ─────────────────────────────────────────────────────────
|
|
1084
1103
|
|
|
1085
1104
|
def _start_scheduler() -> None:
|
|
@@ -1152,6 +1171,20 @@ def _start_scheduler() -> None:
|
|
|
1152
1171
|
)
|
|
1153
1172
|
logger.info("Registered 4 default scheduled jobs (morning / US / evening / weekly)")
|
|
1154
1173
|
|
|
1174
|
+
# Shipper digest: each group bound to a shipper gets what needs
|
|
1175
|
+
# attention. Only when the operator has said where the data is.
|
|
1176
|
+
if os.environ.get("ARIA_SHIPPER_FEEDS", "").strip():
|
|
1177
|
+
cron = os.environ.get("ARIA_DIGEST_CRON", "30 8 * * 1-6").strip()
|
|
1178
|
+
scheduler.add_job(
|
|
1179
|
+
_run_shipper_digests,
|
|
1180
|
+
CronTrigger.from_crontab(cron, timezone="Asia/Shanghai"),
|
|
1181
|
+
id="default_shipper_digest",
|
|
1182
|
+
name="货主库存与运费提醒",
|
|
1183
|
+
replace_existing=True,
|
|
1184
|
+
misfire_grace_time=1800,
|
|
1185
|
+
)
|
|
1186
|
+
logger.info("Registered shipper digest [%s]", cron)
|
|
1187
|
+
|
|
1155
1188
|
scheduler.start()
|
|
1156
1189
|
logger.info("APScheduler started with %d job(s)", len(scheduler.get_jobs()))
|
|
1157
1190
|
return scheduler
|
|
@@ -297,11 +297,17 @@ async def _reply_card_raw(message_id: str, title: str, body: str,
|
|
|
297
297
|
|
|
298
298
|
|
|
299
299
|
async def send_card_to_chat(chat_id: str, title: str, body: str,
|
|
300
|
-
color: str = "blue", receive_id_type: str = "chat_id") ->
|
|
301
|
-
"""Send a new card message to a chat (group or user).
|
|
300
|
+
color: str = "blue", receive_id_type: str = "chat_id") -> bool:
|
|
301
|
+
"""Send a new card message to a chat (group or user). True if Feishu accepted it.
|
|
302
|
+
|
|
303
|
+
The content is the card itself. It was wrapped as {"card": ...} — the
|
|
304
|
+
custom-webhook format, which /im/v1/messages rejects — and the response
|
|
305
|
+
was never read, so every proactive send failed without a trace. Nothing
|
|
306
|
+
scheduled depended on it until the shipper digest.
|
|
307
|
+
"""
|
|
302
308
|
token = await _get_access_token()
|
|
303
309
|
if not token:
|
|
304
|
-
return
|
|
310
|
+
return False
|
|
305
311
|
elements = _build_card_elements(body)
|
|
306
312
|
card = {
|
|
307
313
|
"config": {"wide_screen_mode": True},
|
|
@@ -311,17 +317,23 @@ async def send_card_to_chat(chat_id: str, title: str, body: str,
|
|
|
311
317
|
try:
|
|
312
318
|
import httpx
|
|
313
319
|
async with httpx.AsyncClient(timeout=15) as client:
|
|
314
|
-
await client.post(
|
|
320
|
+
resp = await client.post(
|
|
315
321
|
f"{_FEISHU_API}/im/v1/messages?receive_id_type={receive_id_type}",
|
|
316
322
|
headers={"Authorization": f"Bearer {token}"},
|
|
317
323
|
json={
|
|
318
324
|
"receive_id": chat_id,
|
|
319
325
|
"msg_type": "interactive",
|
|
320
|
-
"content": json.dumps(
|
|
326
|
+
"content": json.dumps(card),
|
|
321
327
|
},
|
|
322
328
|
)
|
|
329
|
+
result = resp.json()
|
|
323
330
|
except Exception as exc:
|
|
324
331
|
logger.warning("send_card_to_chat failed: %s", exc)
|
|
332
|
+
return False
|
|
333
|
+
if result.get("code") != 0:
|
|
334
|
+
logger.warning("send_card_to_chat rejected: code=%s msg=%s", result.get("code"), result.get("msg"))
|
|
335
|
+
return False
|
|
336
|
+
return True
|
|
325
337
|
|
|
326
338
|
|
|
327
339
|
# ── Command router ─────────────────────────────────────────────────────────────
|
|
@@ -1082,6 +1094,34 @@ def feishu_inbound(event: Dict[str, Any], text: str) -> InboundMessage:
|
|
|
1082
1094
|
)
|
|
1083
1095
|
|
|
1084
1096
|
|
|
1097
|
+
async def _send_digest_now(conversation: str, message_id: str) -> None:
|
|
1098
|
+
"""/digest: this group's shipper digest, now, as a reply."""
|
|
1099
|
+
from aria_code.apps.channels.digest import build_digest, load_feeds
|
|
1100
|
+
|
|
1101
|
+
owner = _conversation_store().owner_for(conversation)
|
|
1102
|
+
if not owner:
|
|
1103
|
+
await reply_text(message_id, "本群未绑定货主,没有可发送的简报。管理员可发送 /owner <货主ID> 绑定。")
|
|
1104
|
+
return
|
|
1105
|
+
try:
|
|
1106
|
+
digest = build_digest(owner, load_feeds())
|
|
1107
|
+
except Exception as exc:
|
|
1108
|
+
logger.warning("digest for %s failed: %s", owner, exc)
|
|
1109
|
+
digest = None
|
|
1110
|
+
if digest is None or digest.problems and not digest.worth_sending:
|
|
1111
|
+
# The details are for the operator's log, not the client's group.
|
|
1112
|
+
await reply_text(message_id, "暂时无法生成简报,已记录到运维日志。")
|
|
1113
|
+
return
|
|
1114
|
+
if not digest.worth_sending:
|
|
1115
|
+
await reply_text(message_id, f"{owner}:今天没有需要处理的补货、呆滞或运费异常。")
|
|
1116
|
+
return
|
|
1117
|
+
await reply_card(message_id, digest.title, digest.body, "orange")
|
|
1118
|
+
|
|
1119
|
+
|
|
1120
|
+
async def send_digest_card(chat_id: str, title: str, body: str) -> bool:
|
|
1121
|
+
"""The Feishu sender for apps.channels.digest.run_digests."""
|
|
1122
|
+
return await send_card_to_chat(chat_id, title, body, "orange")
|
|
1123
|
+
|
|
1124
|
+
|
|
1085
1125
|
# ── Main event dispatcher (called by feishu_routes.py or standalone) ──────────
|
|
1086
1126
|
|
|
1087
1127
|
async def dispatch_event(raw: Dict[str, Any], *, authorized_by_binding: bool = False) -> Dict[str, Any]:
|
|
@@ -1163,6 +1203,9 @@ async def dispatch_event(raw: Dict[str, Any], *, authorized_by_binding: bool = F
|
|
|
1163
1203
|
if owner_reply is not None:
|
|
1164
1204
|
await reply_text(msg_id, owner_reply)
|
|
1165
1205
|
return {"code": 0}
|
|
1206
|
+
if text.strip().lower() in ("/digest", "/简报"):
|
|
1207
|
+
asyncio.create_task(_send_digest_now(inbound.key, msg_id))
|
|
1208
|
+
return {"code": 0}
|
|
1166
1209
|
|
|
1167
1210
|
# A task copies the context it is created in, so every aria subprocess
|
|
1168
1211
|
# the tasks below start runs under this conversation's shipper scope.
|
|
@@ -143,6 +143,7 @@ src/aria_code/apps/__init__.py
|
|
|
143
143
|
src/aria_code/apps/channels/README.md
|
|
144
144
|
src/aria_code/apps/channels/__init__.py
|
|
145
145
|
src/aria_code/apps/channels/conversation.py
|
|
146
|
+
src/aria_code/apps/channels/digest.py
|
|
146
147
|
src/aria_code/apps/channels/intake.py
|
|
147
148
|
src/aria_code/apps/channels/registry.py
|
|
148
149
|
src/aria_code/apps/channels/tradingview.py
|
|
@@ -663,6 +664,7 @@ tests/test_safety_service_adoption.py
|
|
|
663
664
|
tests/test_service_diagnostics_security.py
|
|
664
665
|
tests/test_session_search.py
|
|
665
666
|
tests/test_settings_service.py
|
|
667
|
+
tests/test_shipper_digest.py
|
|
666
668
|
tests/test_single_import_root.py
|
|
667
669
|
tests/test_skill_agent_binding.py
|
|
668
670
|
tests/test_skill_catalog.py
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"""The daily shipper digest: right content, right group, nothing else's.
|
|
2
|
+
|
|
3
|
+
apps/channels/digest.py pushes each group bound to a shipper what needs
|
|
4
|
+
attention. These pin what a 3PL would be embarrassed by: one shipper's lines
|
|
5
|
+
in another's group, a digest built from a file nobody can attribute, a
|
|
6
|
+
configuration error shown to a client, and a "sent" that was never delivered.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import asyncio
|
|
12
|
+
import csv
|
|
13
|
+
import json
|
|
14
|
+
import os
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from unittest import mock
|
|
17
|
+
|
|
18
|
+
import pytest
|
|
19
|
+
|
|
20
|
+
from aria_code.apps.channels.conversation import ConversationStore
|
|
21
|
+
from aria_code.apps.channels.digest import build_digest, load_feeds, run_digests
|
|
22
|
+
from aria_code.tools.logistics_tenancy import OWNER_SCOPE_ENV
|
|
23
|
+
|
|
24
|
+
ROOT = Path(__file__).resolve().parents[1]
|
|
25
|
+
INVENTORY = ROOT / "evals" / "fixtures" / "inventory_reorder" / "skus.csv" # all ACME
|
|
26
|
+
WAYBILLS = ROOT / "evals" / "fixtures" / "freight_audit" / "waybills.csv" # no owner_id
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@pytest.fixture(autouse=True)
|
|
30
|
+
def isolated(monkeypatch, tmp_path):
|
|
31
|
+
for key in (OWNER_SCOPE_ENV, "ARIA_SHIPPER_FEEDS", "FEISHU_ALLOWED_USER_IDS", "ARIA_CHANNEL_ADMINS"):
|
|
32
|
+
monkeypatch.delenv(key, raising=False)
|
|
33
|
+
monkeypatch.setenv("ARIA_CONVERSATIONS_DB", str(tmp_path / "bot.db"))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _shared_export(tmp_path) -> dict:
|
|
37
|
+
"""One multi-shipper WMS/TMS export each — the common 3PL setup."""
|
|
38
|
+
inventory = tmp_path / "all_skus.csv"
|
|
39
|
+
rows = list(csv.DictReader(INVENTORY.open()))
|
|
40
|
+
beta = [{**r, "owner_id": "BETA", "sku": "B" + r["sku"][1:]} for r in rows]
|
|
41
|
+
with inventory.open("w", newline="") as handle:
|
|
42
|
+
writer = csv.DictWriter(handle, fieldnames=list(rows[0]))
|
|
43
|
+
writer.writeheader()
|
|
44
|
+
writer.writerows(rows + beta)
|
|
45
|
+
waybills = tmp_path / "all_waybills.csv"
|
|
46
|
+
rows = list(csv.DictReader(WAYBILLS.open()))
|
|
47
|
+
with waybills.open("w", newline="") as handle:
|
|
48
|
+
writer = csv.DictWriter(handle, fieldnames=["owner_id", *rows[0]])
|
|
49
|
+
writer.writeheader()
|
|
50
|
+
writer.writerows({"owner_id": "ACME", **r} for r in rows)
|
|
51
|
+
return {"*": {"inventory": str(inventory), "waybills": str(waybills)}}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class TestBuildDigest:
|
|
55
|
+
def test_a_shipper_sees_its_reorders_thin_history_and_freight_issues(self, tmp_path):
|
|
56
|
+
digest = build_digest("ACME", _shared_export(tmp_path))
|
|
57
|
+
assert digest.worth_sending and not digest.problems
|
|
58
|
+
for expected in ("A100", "A200", "A600", "A400", "W1007", "W1093", "YTO → JD"):
|
|
59
|
+
assert expected in digest.body
|
|
60
|
+
assert "A500" not in digest.body, "covered by an open purchase order"
|
|
61
|
+
|
|
62
|
+
def test_a_shared_export_yields_only_that_shippers_lines(self, tmp_path):
|
|
63
|
+
digest = build_digest("BETA", _shared_export(tmp_path))
|
|
64
|
+
assert "B100" in digest.body
|
|
65
|
+
assert "A100" not in digest.body
|
|
66
|
+
assert "W1007" not in digest.body, "the waybills are all ACME's"
|
|
67
|
+
|
|
68
|
+
def test_a_file_that_cannot_be_attributed_is_refused_not_guessed(self):
|
|
69
|
+
digest = build_digest("ACME", {"ACME": {"waybills": str(WAYBILLS)}})
|
|
70
|
+
assert not digest.worth_sending
|
|
71
|
+
assert digest.problems and "owner_id" in digest.problems[0]
|
|
72
|
+
|
|
73
|
+
def test_no_feeds_is_a_problem_not_an_empty_success(self):
|
|
74
|
+
digest = build_digest("ACME", {})
|
|
75
|
+
assert not digest.worth_sending and digest.problems
|
|
76
|
+
|
|
77
|
+
def test_the_scope_does_not_outlive_the_digest(self, tmp_path):
|
|
78
|
+
build_digest("ACME", _shared_export(tmp_path))
|
|
79
|
+
assert OWNER_SCOPE_ENV not in os.environ
|
|
80
|
+
|
|
81
|
+
def test_feeds_come_from_the_operators_file(self, tmp_path, monkeypatch):
|
|
82
|
+
path = tmp_path / "feeds.json"
|
|
83
|
+
path.write_text(json.dumps({"ACME": {"inventory": "/data/a.csv"}}))
|
|
84
|
+
monkeypatch.setenv("ARIA_SHIPPER_FEEDS", str(path))
|
|
85
|
+
assert load_feeds() == {"ACME": {"inventory": "/data/a.csv"}}
|
|
86
|
+
monkeypatch.delenv("ARIA_SHIPPER_FEEDS")
|
|
87
|
+
assert load_feeds() == {}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class TestRunDigests:
|
|
91
|
+
def test_each_bound_group_gets_its_own_shippers_digest(self, tmp_path):
|
|
92
|
+
store = ConversationStore(tmp_path / "c.db")
|
|
93
|
+
store.bind_owner("feishu:oc_acme", "ACME", bound_by="t")
|
|
94
|
+
store.bind_owner("feishu:oc_gamma", "GAMMA", bound_by="t") # nothing in the export
|
|
95
|
+
store.bind_owner("telegram:42", "ACME", bound_by="t") # no telegram sender here
|
|
96
|
+
sent = []
|
|
97
|
+
|
|
98
|
+
async def send(conversation_id, title, body):
|
|
99
|
+
sent.append((conversation_id, body))
|
|
100
|
+
return True
|
|
101
|
+
|
|
102
|
+
report = asyncio.run(run_digests(store, {"feishu": send}, _shared_export(tmp_path)))
|
|
103
|
+
statuses = {r["conversation"]: r["status"] for r in report}
|
|
104
|
+
assert statuses == {"feishu:oc_acme": "sent", "feishu:oc_gamma": "nothing_to_report",
|
|
105
|
+
"telegram:42": "no_sender"}
|
|
106
|
+
assert [c for c, _ in sent] == ["oc_acme"]
|
|
107
|
+
assert "A100" in sent[0][1]
|
|
108
|
+
|
|
109
|
+
def test_a_failed_send_is_reported_as_failed(self, tmp_path):
|
|
110
|
+
store = ConversationStore(tmp_path / "c.db")
|
|
111
|
+
store.bind_owner("feishu:oc_acme", "ACME", bound_by="t")
|
|
112
|
+
|
|
113
|
+
async def send(*args):
|
|
114
|
+
return False
|
|
115
|
+
|
|
116
|
+
report = asyncio.run(run_digests(store, {"feishu": send}, _shared_export(tmp_path)))
|
|
117
|
+
assert report == [{"conversation": "feishu:oc_acme", "status": "send_failed"}]
|
|
118
|
+
|
|
119
|
+
def test_problems_stay_in_the_log(self, tmp_path):
|
|
120
|
+
store = ConversationStore(tmp_path / "c.db")
|
|
121
|
+
store.bind_owner("feishu:oc_acme", "ACME", bound_by="t")
|
|
122
|
+
sent = []
|
|
123
|
+
|
|
124
|
+
async def send(*args):
|
|
125
|
+
sent.append(args)
|
|
126
|
+
return True
|
|
127
|
+
|
|
128
|
+
asyncio.run(run_digests(store, {"feishu": send}, {"ACME": {"waybills": str(WAYBILLS)}}))
|
|
129
|
+
assert sent == []
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
# ── Feishu ────────────────────────────────────────────────────────────────────
|
|
133
|
+
|
|
134
|
+
import aria_code.aria_feishu_bot as bot # noqa: E402
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class _Response:
|
|
138
|
+
def __init__(self, payload):
|
|
139
|
+
self._payload = payload
|
|
140
|
+
|
|
141
|
+
def json(self):
|
|
142
|
+
return self._payload
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class _Client:
|
|
146
|
+
def __init__(self, payload, posts):
|
|
147
|
+
self.payload, self.posts = payload, posts
|
|
148
|
+
|
|
149
|
+
async def __aenter__(self):
|
|
150
|
+
return self
|
|
151
|
+
|
|
152
|
+
async def __aexit__(self, *exc):
|
|
153
|
+
return False
|
|
154
|
+
|
|
155
|
+
async def post(self, url, **kwargs):
|
|
156
|
+
self.posts.append(kwargs["json"])
|
|
157
|
+
return _Response(self.payload)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _send(payload):
|
|
161
|
+
posts = []
|
|
162
|
+
|
|
163
|
+
async def token():
|
|
164
|
+
return "t"
|
|
165
|
+
|
|
166
|
+
async def go():
|
|
167
|
+
with mock.patch.object(bot, "_get_access_token", token), \
|
|
168
|
+
mock.patch("httpx.AsyncClient", lambda **kw: _Client(payload, posts)):
|
|
169
|
+
return await bot.send_card_to_chat("oc_acme", "title", "body")
|
|
170
|
+
|
|
171
|
+
return asyncio.run(go()), posts
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class TestFeishuSend:
|
|
175
|
+
def test_the_content_is_the_card_itself(self):
|
|
176
|
+
ok, posts = _send({"code": 0})
|
|
177
|
+
assert ok
|
|
178
|
+
card = json.loads(posts[0]["content"])
|
|
179
|
+
assert "card" not in card, "the {'card': ...} wrapper is the webhook format; the API rejects it"
|
|
180
|
+
assert card["header"]["title"]["content"] == "title"
|
|
181
|
+
|
|
182
|
+
def test_a_rejected_send_is_not_reported_as_delivered(self):
|
|
183
|
+
ok, _ = _send({"code": 230002, "msg": "bot not in chat"})
|
|
184
|
+
assert ok is False
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class TestDigestCommand:
|
|
188
|
+
def _run(self, monkeypatch, tmp_path, *, bound):
|
|
189
|
+
monkeypatch.setenv("FEISHU_ALLOWED_USER_IDS", "ou_ops")
|
|
190
|
+
monkeypatch.setenv("ARIA_SHIPPER_FEEDS", str(tmp_path / "feeds.json"))
|
|
191
|
+
(tmp_path / "feeds.json").write_text(json.dumps(_shared_export(tmp_path)))
|
|
192
|
+
if bound:
|
|
193
|
+
bot._conversation_store().bind_owner("feishu:oc_acme", "ACME", bound_by="t")
|
|
194
|
+
out = {"text": [], "cards": []}
|
|
195
|
+
|
|
196
|
+
async def reply_text(message_id, text):
|
|
197
|
+
out["text"].append(text)
|
|
198
|
+
|
|
199
|
+
async def reply_card(message_id, title, body, *args, **kwargs):
|
|
200
|
+
out["cards"].append((title, body))
|
|
201
|
+
|
|
202
|
+
event = {"header": {"event_type": "im.message.receive_v1"}, "event": {
|
|
203
|
+
"sender": {"sender_id": {"open_id": "ou_ops"}},
|
|
204
|
+
"message": {"message_id": "om_1", "chat_id": "oc_acme", "chat_type": "group",
|
|
205
|
+
"message_type": "text", "content": json.dumps({"text": "@_user_1 /digest"}),
|
|
206
|
+
"mentions": [{"key": "@_user_1", "id": {"open_id": "ou_bot"}}]}}}
|
|
207
|
+
|
|
208
|
+
async def go():
|
|
209
|
+
with mock.patch.object(bot, "reply_text", reply_text), \
|
|
210
|
+
mock.patch.object(bot, "reply_card", reply_card):
|
|
211
|
+
await bot.dispatch_event(event)
|
|
212
|
+
for _ in range(3):
|
|
213
|
+
await asyncio.sleep(0)
|
|
214
|
+
|
|
215
|
+
asyncio.run(go())
|
|
216
|
+
return out
|
|
217
|
+
|
|
218
|
+
def test_in_a_bound_group_it_replies_with_the_digest(self, monkeypatch, tmp_path):
|
|
219
|
+
out = self._run(monkeypatch, tmp_path, bound=True)
|
|
220
|
+
assert len(out["cards"]) == 1 and "A100" in out["cards"][0][1]
|
|
221
|
+
|
|
222
|
+
def test_in_an_unbound_group_it_says_how_to_bind(self, monkeypatch, tmp_path):
|
|
223
|
+
out = self._run(monkeypatch, tmp_path, bound=False)
|
|
224
|
+
assert out["cards"] == [] and "/owner" in out["text"][0]
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class TestDaemonJob:
|
|
228
|
+
def test_it_sends_through_feishu_when_the_app_is_configured(self, monkeypatch):
|
|
229
|
+
import aria_code.aria_daemon as daemon
|
|
230
|
+
monkeypatch.setenv("FEISHU_APP_ID", "cli_x")
|
|
231
|
+
monkeypatch.setenv("FEISHU_APP_SECRET", "s")
|
|
232
|
+
seen = {}
|
|
233
|
+
|
|
234
|
+
async def fake_run(store, senders, feeds=None):
|
|
235
|
+
seen["channels"] = sorted(senders)
|
|
236
|
+
return []
|
|
237
|
+
|
|
238
|
+
with mock.patch("aria_code.apps.channels.digest.run_digests", fake_run), \
|
|
239
|
+
mock.patch("apps.channels.digest.run_digests", fake_run, create=True):
|
|
240
|
+
asyncio.run(daemon._run_shipper_digests())
|
|
241
|
+
assert seen["channels"] == ["feishu"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|