aria-code 0.167.0__py3-none-macosx_13_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aria_bots/__init__.py +7 -0
- aria_bots/channels/README.md +97 -0
- aria_bots/channels/__init__.py +1 -0
- aria_bots/channels/approvals.py +263 -0
- aria_bots/channels/conversation.py +280 -0
- aria_bots/channels/digest.py +186 -0
- aria_bots/channels/registry.py +95 -0
- aria_bots/engine.py +144 -0
- aria_bots/feishu_bot.py +1385 -0
- aria_bots/logistics/__init__.py +1 -0
- aria_bots/logistics/carriers.py +253 -0
- aria_bots/logistics/freight.py +154 -0
- aria_bots/logistics/inventory.py +242 -0
- aria_bots/logistics/mcp_server.py +156 -0
- aria_bots/logistics/records.py +119 -0
- aria_bots/logistics/tenancy.py +152 -0
- aria_bots/market.py +91 -0
- aria_bots/relay_client.py +326 -0
- aria_bots/telegram_bot.py +299 -0
- aria_code/__init__.py +111 -0
- aria_code/_bin/aria-native +0 -0
- aria_code/_bin/aria-runtime +0 -0
- aria_code/_version.py +20 -0
- aria_code/account_memory.py +296 -0
- aria_code/account_session.py +166 -0
- aria_code/adk_apps/__init__.py +1 -0
- aria_code/adk_apps/aria_code_review/__init__.py +1 -0
- aria_code/adk_apps/aria_code_review/agent.py +32 -0
- aria_code/adk_apps/aria_research/__init__.py +1 -0
- aria_code/adk_apps/aria_research/agent.py +31 -0
- aria_code/agents/__init__.py +49 -0
- aria_code/agents/base.py +329 -0
- aria_code/agents/code_review.py +200 -0
- aria_code/agents/deep/__init__.py +37 -0
- aria_code/agents/deep/calibration_loop.py +144 -0
- aria_code/agents/deep/critic.py +125 -0
- aria_code/agents/deep/deepen.py +193 -0
- aria_code/agents/deep/models.py +149 -0
- aria_code/agents/deep/pipeline.py +164 -0
- aria_code/agents/deep/quant_fusion.py +192 -0
- aria_code/agents/deep/themes.py +95 -0
- aria_code/agents/deep/tiers.py +106 -0
- aria_code/agents/engineering/__init__.py +14 -0
- aria_code/agents/engineering/coder.py +222 -0
- aria_code/agents/engineering/tester.py +145 -0
- aria_code/agents/financial/__init__.py +21 -0
- aria_code/agents/financial/cashflow_burn.py +119 -0
- aria_code/agents/financial/catalyst.py +279 -0
- aria_code/agents/financial/corporate_finance.py +175 -0
- aria_code/agents/financial/debate.py +224 -0
- aria_code/agents/financial/earnings.py +315 -0
- aria_code/agents/financial/fundamental.py +178 -0
- aria_code/agents/financial/macro.py +111 -0
- aria_code/agents/financial/news.py +231 -0
- aria_code/agents/financial/risk.py +146 -0
- aria_code/agents/financial/sector.py +279 -0
- aria_code/agents/financial/strategist.py +121 -0
- aria_code/agents/financial/stripe_revenue.py +127 -0
- aria_code/agents/financial/synthesis.py +274 -0
- aria_code/agents/financial/technical.py +277 -0
- aria_code/agents/orchestrator.py +44 -0
- aria_code/agents/portfolio_agent.py +392 -0
- aria_code/agents/realty/__init__.py +62 -0
- aria_code/agents/realty/asset_diagnosis.py +152 -0
- aria_code/agents/realty/business_match.py +166 -0
- aria_code/agents/realty/cashflow_verify.py +209 -0
- aria_code/agents/realty/contract_rules.py +210 -0
- aria_code/agents/realty/energy_anomaly.py +189 -0
- aria_code/agents/realty/exit_settlement.py +208 -0
- aria_code/agents/realty/fulfillment_risk.py +206 -0
- aria_code/agents/realty/ops_optimize.py +160 -0
- aria_code/agents/realty/revenue_share.py +215 -0
- aria_code/agents/registry.py +168 -0
- aria_code/agents/signal_scheme.py +111 -0
- aria_code/agents/sports/__init__.py +0 -0
- aria_code/agents/sports/football_agent.py +197 -0
- aria_code/agents/supervisor.py +113 -0
- aria_code/agents/team.py +500 -0
- aria_code/agents/video/__init__.py +16 -0
- aria_code/agents/video/director.py +376 -0
- aria_code/agents/video/qa_agent.py +143 -0
- aria_code/agents/video/script_doctor.py +112 -0
- aria_code/agents/warehouse/__init__.py +25 -0
- aria_code/agents/warehouse/contracts.py +26 -0
- aria_code/agents/warehouse/dashboard.py +155 -0
- aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
- aria_code/agents/warehouse/inbound_exceptions.py +25 -0
- aria_code/agents/warehouse/inventory_health.py +24 -0
- aria_code/agents/warehouse/local_run.py +71 -0
- aria_code/agents/warehouse/local_snapshot.py +132 -0
- aria_code/agents/warehouse/logistics_cost.py +84 -0
- aria_code/agents/warehouse/logistics_sync.py +21 -0
- aria_code/agents/warehouse/navigation.schema.json +110 -0
- aria_code/agents/warehouse/task_agent.py +172 -0
- aria_code/agents/warehouse/workflow.py +31 -0
- aria_code/aliyun_data_client.py +4 -0
- aria_code/apps/README.md +12 -0
- aria_code/apps/__init__.py +2 -0
- aria_code/apps/channels/README.md +9 -0
- aria_code/apps/channels/__init__.py +17 -0
- aria_code/apps/channels/approvals.py +11 -0
- aria_code/apps/channels/conversation.py +11 -0
- aria_code/apps/channels/digest.py +11 -0
- aria_code/apps/channels/intake.py +92 -0
- aria_code/apps/channels/registry.py +11 -0
- aria_code/apps/channels/tradingview.py +94 -0
- aria_code/apps/cli/README.md +13 -0
- aria_code/apps/cli/__init__.py +2 -0
- aria_code/apps/cli/_optional.py +120 -0
- aria_code/apps/cli/app_server.py +656 -0
- aria_code/apps/cli/auto_update.py +125 -0
- aria_code/apps/cli/bootstrap.py +206 -0
- aria_code/apps/cli/broker_render.py +206 -0
- aria_code/apps/cli/chat_turn.py +1327 -0
- aria_code/apps/cli/cloud_models.py +231 -0
- aria_code/apps/cli/codegen_paths.py +29 -0
- aria_code/apps/cli/commands/__init__.py +34 -0
- aria_code/apps/cli/commands/_business_render.py +78 -0
- aria_code/apps/cli/commands/_ui.py +71 -0
- aria_code/apps/cli/commands/analysis_cmds.py +378 -0
- aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
- aria_code/apps/cli/commands/auth_cmds.py +215 -0
- aria_code/apps/cli/commands/backtest_cmds.py +2518 -0
- aria_code/apps/cli/commands/broker_cmds.py +1236 -0
- aria_code/apps/cli/commands/business_workflow_cmds.py +379 -0
- aria_code/apps/cli/commands/canvas_cmds.py +77 -0
- aria_code/apps/cli/commands/catalog.py +189 -0
- aria_code/apps/cli/commands/core_cmds.py +2748 -0
- aria_code/apps/cli/commands/data_cmds.py +521 -0
- aria_code/apps/cli/commands/diagnostic_cmds.py +285 -0
- aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
- aria_code/apps/cli/commands/engineering_cmds.py +399 -0
- aria_code/apps/cli/commands/file_cmds.py +312 -0
- aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
- aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
- aria_code/apps/cli/commands/market.py +544 -0
- aria_code/apps/cli/commands/market_cmds.py +1419 -0
- aria_code/apps/cli/commands/market_context.py +432 -0
- aria_code/apps/cli/commands/market_render.py +7 -0
- aria_code/apps/cli/commands/model_cmds.py +2374 -0
- aria_code/apps/cli/commands/ops_cmds.py +721 -0
- aria_code/apps/cli/commands/orchestrator_cmds.py +181 -0
- aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
- aria_code/apps/cli/commands/portfolio_cmds.py +1316 -0
- aria_code/apps/cli/commands/report.py +476 -0
- aria_code/apps/cli/commands/scaffold_templates.py +617 -0
- aria_code/apps/cli/commands/session_cmds.py +236 -0
- aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
- aria_code/apps/cli/commands/team.py +723 -0
- aria_code/apps/cli/commands/team_render.py +8 -0
- aria_code/apps/cli/commands/ui_cmds.py +401 -0
- aria_code/apps/cli/commands/warehouse_cmds.py +297 -0
- aria_code/apps/cli/commands/workflow_cmds.py +629 -0
- aria_code/apps/cli/commands/workspace_cmds.py +1543 -0
- aria_code/apps/cli/config_paths.py +73 -0
- aria_code/apps/cli/config_store.py +158 -0
- aria_code/apps/cli/constants.py +88 -0
- aria_code/apps/cli/context.py +34 -0
- aria_code/apps/cli/conversation_policy.py +53 -0
- aria_code/apps/cli/deterministic.py +200 -0
- aria_code/apps/cli/direct.py +48 -0
- aria_code/apps/cli/earnings_view.py +172 -0
- aria_code/apps/cli/endpoint_migration.py +64 -0
- aria_code/apps/cli/exec_events.py +255 -0
- aria_code/apps/cli/file_references.py +155 -0
- aria_code/apps/cli/finance_service_catalog.py +111 -0
- aria_code/apps/cli/football_reports.py +231 -0
- aria_code/apps/cli/github_app_auth.py +135 -0
- aria_code/apps/cli/google_login.py +239 -0
- aria_code/apps/cli/handlers/__init__.py +11 -0
- aria_code/apps/cli/handlers/broker_handlers.py +122 -0
- aria_code/apps/cli/handlers/chart_handlers.py +1314 -0
- aria_code/apps/cli/handlers/market_handlers.py +2570 -0
- aria_code/apps/cli/handlers/realty_handlers.py +114 -0
- aria_code/apps/cli/handlers/sports_handlers.py +22 -0
- aria_code/apps/cli/handlers/strategy_advice.py +82 -0
- aria_code/apps/cli/headless.py +352 -0
- aria_code/apps/cli/helpers.py +326 -0
- aria_code/apps/cli/hooks.py +180 -0
- aria_code/apps/cli/i18n.py +310 -0
- aria_code/apps/cli/intent.py +136 -0
- aria_code/apps/cli/intent_router.py +305 -0
- aria_code/apps/cli/intent_shadow.py +72 -0
- aria_code/apps/cli/intent_signals.py +347 -0
- aria_code/apps/cli/lifecycle_hooks.py +48 -0
- aria_code/apps/cli/local_tool_schemas.py +550 -0
- aria_code/apps/cli/main.py +39 -0
- aria_code/apps/cli/market_hours.py +100 -0
- aria_code/apps/cli/market_metadata.py +135 -0
- aria_code/apps/cli/market_universe.py +487 -0
- aria_code/apps/cli/message_processing.py +310 -0
- aria_code/apps/cli/mixin_binding.py +32 -0
- aria_code/apps/cli/model_catalog.py +652 -0
- aria_code/apps/cli/model_probe.py +169 -0
- aria_code/apps/cli/model_retirement.py +65 -0
- aria_code/apps/cli/native_branding.py +12 -0
- aria_code/apps/cli/native_bridge.py +118 -0
- aria_code/apps/cli/native_entry.py +58 -0
- aria_code/apps/cli/pdf_report.py +977 -0
- aria_code/apps/cli/plan_mode.py +139 -0
- aria_code/apps/cli/plotly_html.py +15 -0
- aria_code/apps/cli/prediction_feedback.py +202 -0
- aria_code/apps/cli/preflight.py +502 -0
- aria_code/apps/cli/project_aria.py +60 -0
- aria_code/apps/cli/prompt_assembly.py +78 -0
- aria_code/apps/cli/prompts/__init__.py +0 -0
- aria_code/apps/cli/prompts/coding.py +71 -0
- aria_code/apps/cli/prompts/select.py +193 -0
- aria_code/apps/cli/prompts/system_prompts.py +562 -0
- aria_code/apps/cli/prompts/ui.py +436 -0
- aria_code/apps/cli/provider_endpoints.py +237 -0
- aria_code/apps/cli/provider_keys.py +73 -0
- aria_code/apps/cli/providers/__init__.py +1 -0
- aria_code/apps/cli/providers/base.py +775 -0
- aria_code/apps/cli/providers/chat_routing.py +139 -0
- aria_code/apps/cli/providers/collaboration.py +98 -0
- aria_code/apps/cli/providers/llm/__init__.py +1 -0
- aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
- aria_code/apps/cli/providers/llm/ollama_stream.py +1574 -0
- aria_code/apps/cli/providers/llm/response_cache.py +60 -0
- aria_code/apps/cli/providers/llm/sse_stream.py +298 -0
- aria_code/apps/cli/providers/runtime_bridge.py +586 -0
- aria_code/apps/cli/providers/vertexai_stream.py +592 -0
- aria_code/apps/cli/release_download.py +159 -0
- aria_code/apps/cli/review_runner.py +111 -0
- aria_code/apps/cli/runtime_consumer.py +769 -0
- aria_code/apps/cli/sandbox.py +32 -0
- aria_code/apps/cli/session_export.py +120 -0
- aria_code/apps/cli/session_jsonl.py +208 -0
- aria_code/apps/cli/session_refresh.py +123 -0
- aria_code/apps/cli/session_store.py +125 -0
- aria_code/apps/cli/skills_catalog.py +273 -0
- aria_code/apps/cli/task_isolation.py +211 -0
- aria_code/apps/cli/terminal_chrome.py +412 -0
- aria_code/apps/cli/todo_tracker.py +190 -0
- aria_code/apps/cli/tool_executor.py +932 -0
- aria_code/apps/cli/tool_registry.py +34 -0
- aria_code/apps/cli/tool_scope.py +113 -0
- aria_code/apps/cli/tools/__init__.py +40 -0
- aria_code/apps/cli/tools/context.py +46 -0
- aria_code/apps/cli/tools/file_tools.py +181 -0
- aria_code/apps/cli/tools/market_tools.py +626 -0
- aria_code/apps/cli/tools/notebook_tools.py +111 -0
- aria_code/apps/cli/tools/system_tools.py +656 -0
- aria_code/apps/cli/tools/write_tools.py +961 -0
- aria_code/apps/cli/tradingview_bridge.py +529 -0
- aria_code/apps/cli/transactions.py +269 -0
- aria_code/apps/cli/turn_planning.py +137 -0
- aria_code/apps/cli/update_check.py +257 -0
- aria_code/apps/cli/updater.py +373 -0
- aria_code/apps/cli/utils/__init__.py +0 -0
- aria_code/apps/cli/utils/market_detect.py +1663 -0
- aria_code/apps/cli/web_login.py +136 -0
- aria_code/apps/cli/workflow_runner.py +127 -0
- aria_code/apps/cli/workspace_route.py +121 -0
- aria_code/apps/daemon/README.md +14 -0
- aria_code/apps/vscode/README.md +115 -0
- aria_code/apps/vscode/package.json +70 -0
- aria_code/aria_cli.py +5244 -0
- aria_code/aria_daemon.py +1372 -0
- aria_code/aria_feishu_bot.py +16 -0
- aria_code/aria_mcp_server.py +61 -0
- aria_code/aria_relay_client.py +4 -0
- aria_code/aria_telegram_bot.py +11 -0
- aria_code/ariarc.py +385 -0
- aria_code/artifacts.py +581 -0
- aria_code/backtest_engine.py +4 -0
- aria_code/backtest_report.py +4 -0
- aria_code/brokers/__init__.py +78 -0
- aria_code/brokers/automation.py +193 -0
- aria_code/brokers/base.py +231 -0
- aria_code/brokers/capabilities.py +264 -0
- aria_code/brokers/cn/__init__.py +10 -0
- aria_code/brokers/cn/easytrader_broker.py +193 -0
- aria_code/brokers/cn/futu_broker.py +194 -0
- aria_code/brokers/cn/longbridge_broker.py +190 -0
- aria_code/brokers/cn/tiger_broker.py +196 -0
- aria_code/brokers/cn/xtquant_broker.py +225 -0
- aria_code/brokers/config.py +414 -0
- aria_code/brokers/intl/__init__.py +5 -0
- aria_code/brokers/intl/alpaca_broker.py +183 -0
- aria_code/brokers/intl/ibkr_broker.py +215 -0
- aria_code/brokers/intl/trading212_broker.py +183 -0
- aria_code/brokers/intl/webull_broker.py +156 -0
- aria_code/brokers/paper_broker.py +266 -0
- aria_code/brokers/planning.py +296 -0
- aria_code/brokers/registry.py +213 -0
- aria_code/brokers/trading.py +267 -0
- aria_code/canva_client.py +4 -0
- aria_code/change_store.py +127 -0
- aria_code/clients/__init__.py +0 -0
- aria_code/clients/aliyun_data_client.py +660 -0
- aria_code/clients/aria_relay_client.py +16 -0
- aria_code/clients/canva_client.py +284 -0
- aria_code/clients/figma_client.py +100 -0
- aria_code/clients/football_data_client.py +1671 -0
- aria_code/clients/kling_video_client.py +182 -0
- aria_code/clients/market_data_client.py +1985 -0
- aria_code/clients/openai_image_client.py +242 -0
- aria_code/clients/runway_video_client.py +157 -0
- aria_code/clients/warehouse_erp_client.py +105 -0
- aria_code/cloud_memory.py +190 -0
- aria_code/command_safety.py +19 -0
- aria_code/computer_use_server.py +276 -0
- aria_code/computer_use_tools.py +4 -0
- aria_code/dashboard_generator.py +579 -0
- aria_code/data_analysis_tools.py +4 -0
- aria_code/data_cleaner.py +483 -0
- aria_code/data_service.py +513 -0
- aria_code/datasources/__init__.py +23 -0
- aria_code/datasources/base.py +166 -0
- aria_code/datasources/router.py +253 -0
- aria_code/datasources/sec_statements.py +217 -0
- aria_code/datasources/sources/__init__.py +15 -0
- aria_code/datasources/sources/akshare_source.py +269 -0
- aria_code/datasources/sources/alpha_vantage_source.py +203 -0
- aria_code/datasources/sources/edgar_source.py +219 -0
- aria_code/datasources/sources/finnhub_source.py +198 -0
- aria_code/datasources/sources/fred_source.py +223 -0
- aria_code/datasources/sources/tushare_source.py +143 -0
- aria_code/datasources/sources/web_scraper_source.py +278 -0
- aria_code/datasources/sources/world_bank_source.py +206 -0
- aria_code/datasources/sources/yfinance_source.py +152 -0
- aria_code/doctor.py +860 -0
- aria_code/domain/__init__.py +0 -0
- aria_code/domain/_finance_core/__init__.py +5 -0
- aria_code/domain/_finance_core/backtest_engine.py +325 -0
- aria_code/domain/_finance_core/performance_stats.py +101 -0
- aria_code/domain/backtest_engine.py +75 -0
- aria_code/domain/backtest_report.py +488 -0
- aria_code/domain/finance_formulas.py +389 -0
- aria_code/domain/performance_stats.py +6 -0
- aria_code/domain/portfolio_ledger.py +307 -0
- aria_code/domain/strategy_vault.py +421 -0
- aria_code/evals/__init__.py +37 -0
- aria_code/evals/behavior.py +113 -0
- aria_code/evals/gap.py +93 -0
- aria_code/evals/harness.py +949 -0
- aria_code/evals/review_probe.py +132 -0
- aria_code/evals/runner.py +425 -0
- aria_code/evals/scorecard.py +322 -0
- aria_code/evals/summary.py +125 -0
- aria_code/external_agent_runner.py +115 -0
- aria_code/figma_client.py +4 -0
- aria_code/file_analysis_tools.py +4 -0
- aria_code/finance_formulas.py +4 -0
- aria_code/football_data_client.py +4 -0
- aria_code/image_gen_tools.py +4 -0
- aria_code/intent_classifier.py +459 -0
- aria_code/kling_video_client.py +4 -0
- aria_code/licensing.py +151 -0
- aria_code/local_finance_tools.py +4 -0
- aria_code/local_image_provider.py +4 -0
- aria_code/local_llm_provider.py +4 -0
- aria_code/macro_tools.py +4 -0
- aria_code/markdown_pdf.py +289 -0
- aria_code/market_data_client.py +4 -0
- aria_code/mcp_client.py +744 -0
- aria_code/memory_manager.py +273 -0
- aria_code/model_capability.py +512 -0
- aria_code/notification_tools.py +4 -0
- aria_code/openai_image_client.py +4 -0
- aria_code/packages/__init__.py +26 -0
- aria_code/packages/adk_bridge/__init__.py +11 -0
- aria_code/packages/adk_bridge/code_review_tools.py +49 -0
- aria_code/packages/adk_bridge/market_tools.py +125 -0
- aria_code/packages/aria_agents/__init__.py +5 -0
- aria_code/packages/aria_agents/manifest.py +78 -0
- aria_code/packages/aria_core/__init__.py +34 -0
- aria_code/packages/aria_core/architecture.py +269 -0
- aria_code/packages/aria_core/export.py +147 -0
- aria_code/packages/aria_core/manifest.py +65 -0
- aria_code/packages/aria_core/paths.py +57 -0
- aria_code/packages/aria_core/secure_file.py +68 -0
- aria_code/packages/aria_infra/__init__.py +15 -0
- aria_code/packages/aria_infra/arthera.py +58 -0
- aria_code/packages/aria_infra/doctor.py +246 -0
- aria_code/packages/aria_infra/product.py +40 -0
- aria_code/packages/aria_mcp/__init__.py +25 -0
- aria_code/packages/aria_mcp/bridge.py +232 -0
- aria_code/packages/aria_mcp/circuit.py +82 -0
- aria_code/packages/aria_mcp/config.py +162 -0
- aria_code/packages/aria_mcp/installer.py +95 -0
- aria_code/packages/aria_mcp/server.py +1705 -0
- aria_code/packages/aria_mcp/tools.py +81 -0
- aria_code/packages/aria_sdk/__init__.py +19 -0
- aria_code/packages/aria_sdk/client.py +393 -0
- aria_code/packages/aria_sdk/providers.py +70 -0
- aria_code/packages/aria_sdk/streaming.py +75 -0
- aria_code/packages/aria_sdk/types.py +86 -0
- aria_code/packages/aria_services/__init__.py +92 -0
- aria_code/packages/aria_services/cache.py +60 -0
- aria_code/packages/aria_services/context.py +356 -0
- aria_code/packages/aria_services/context_checkpoints.py +157 -0
- aria_code/packages/aria_services/data.py +11 -0
- aria_code/packages/aria_services/provider_health.py +304 -0
- aria_code/packages/aria_services/references.py +247 -0
- aria_code/packages/aria_services/registry.py +249 -0
- aria_code/packages/aria_services/research_protocol.py +137 -0
- aria_code/packages/aria_services/research_quality.py +186 -0
- aria_code/packages/aria_services/settings.py +160 -0
- aria_code/packages/aria_services/usage.py +151 -0
- aria_code/packages/aria_skills/__init__.py +46 -0
- aria_code/packages/aria_skills/catalog.py +149 -0
- aria_code/packages/aria_skills/loader.py +455 -0
- aria_code/packages/aria_skills/registry.py +84 -0
- aria_code/packages/aria_tools/__init__.py +5 -0
- aria_code/packages/aria_tools/financial/__init__.py +5 -0
- aria_code/packages/aria_tools/financial/_paths.py +92 -0
- aria_code/packages/aria_tools/registry.py +129 -0
- aria_code/packages/quant_engine/__init__.py +33 -0
- aria_code/packages/quant_engine/_namespace.py +24 -0
- aria_code/packages/quant_engine/backtest/__init__.py +10 -0
- aria_code/packages/quant_engine/backtest/core.py +53 -0
- aria_code/packages/quant_engine/backtest/engine.py +102 -0
- aria_code/packages/quant_engine/portfolio/__init__.py +9 -0
- aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
- aria_code/packages/quant_engine/sports/__init__.py +76 -0
- aria_code/packages/quant_engine/sports/calibrator.py +354 -0
- aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
- aria_code/packages/quant_engine/sports/elo.py +300 -0
- aria_code/packages/quant_engine/sports/form.py +188 -0
- aria_code/packages/quant_engine/sports/h2h.py +195 -0
- aria_code/packages/quant_engine/sports/predictor.py +312 -0
- aria_code/packages/quant_engine/sports/tracker.py +665 -0
- aria_code/packages/quant_engine/stochastic/__init__.py +31 -0
- aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
- aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
- aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
- aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
- aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
- aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
- aria_code/packs/__init__.py +85 -0
- aria_code/packs/base.py +168 -0
- aria_code/packs/finance/__init__.py +250 -0
- aria_code/packs/healthcare/__init__.py +40 -0
- aria_code/packs/logistics/__init__.py +171 -0
- aria_code/packs/payments/__init__.py +139 -0
- aria_code/packs/realty/__init__.py +190 -0
- aria_code/packs/registry.py +202 -0
- aria_code/packs/rules.py +90 -0
- aria_code/plan_utils.py +194 -0
- aria_code/plugin_loader.py +328 -0
- aria_code/portfolio_ledger.py +4 -0
- aria_code/preview_server.py +449 -0
- aria_code/privacy/__init__.py +5 -0
- aria_code/privacy/feedback.py +123 -0
- aria_code/project_review.py +278 -0
- aria_code/project_review_api.py +235 -0
- aria_code/project_review_server.py +18 -0
- aria_code/project_tools.py +4 -0
- aria_code/providers/__init__.py +30 -0
- aria_code/providers/google_video_provider.py +256 -0
- aria_code/providers/llm/__init__.py +19 -0
- aria_code/providers/llm/anthropic.py +184 -0
- aria_code/providers/llm/arthera_gateway.py +90 -0
- aria_code/providers/llm/autoconfig.py +213 -0
- aria_code/providers/llm/base.py +139 -0
- aria_code/providers/llm/custom.py +158 -0
- aria_code/providers/llm/ollama.py +137 -0
- aria_code/providers/llm/openai_compat.py +350 -0
- aria_code/providers/llm/registry.py +457 -0
- aria_code/providers/local_image_provider.py +202 -0
- aria_code/providers/local_llm_provider.py +549 -0
- aria_code/providers/ollama_models.py +79 -0
- aria_code/providers/openai_params.py +32 -0
- aria_code/providers/tool_messages.py +100 -0
- aria_code/realty_data_tools.py +4 -0
- aria_code/report_exporters.py +150 -0
- aria_code/report_generator.py +1764 -0
- aria_code/review_service.py +497 -0
- aria_code/runtime/__init__.py +176 -0
- aria_code/runtime/acceptance.py +632 -0
- aria_code/runtime/agent_loop.py +1851 -0
- aria_code/runtime/agent_profiles.py +75 -0
- aria_code/runtime/approval.py +71 -0
- aria_code/runtime/baseline.py +219 -0
- aria_code/runtime/budget.py +232 -0
- aria_code/runtime/checkpoints.py +481 -0
- aria_code/runtime/consult.py +65 -0
- aria_code/runtime/contract.py +282 -0
- aria_code/runtime/delivery.py +432 -0
- aria_code/runtime/events.py +113 -0
- aria_code/runtime/gateway.py +167 -0
- aria_code/runtime/lsp.py +484 -0
- aria_code/runtime/native_index.py +153 -0
- aria_code/runtime/orchestrator.py +55 -0
- aria_code/runtime/processes.py +343 -0
- aria_code/runtime/project_graph.py +614 -0
- aria_code/runtime/repo_map.py +712 -0
- aria_code/runtime/research_bundle.py +105 -0
- aria_code/runtime/review.py +269 -0
- aria_code/runtime/run_state.py +127 -0
- aria_code/runtime/run_store.py +522 -0
- aria_code/runtime/scoped_runs.py +113 -0
- aria_code/runtime/self_healing.py +422 -0
- aria_code/runtime/semantic_diff.py +171 -0
- aria_code/runtime/subagent.py +721 -0
- aria_code/runtime/symbol_edit.py +117 -0
- aria_code/runtime/task_brief.py +46 -0
- aria_code/runtime/task_context.py +145 -0
- aria_code/runtime/task_ledger.py +108 -0
- aria_code/runtime/task_orchestrator.py +90 -0
- aria_code/runtime/task_outcome.py +33 -0
- aria_code/runtime/task_verification.py +266 -0
- aria_code/runtime/task_worktree.py +448 -0
- aria_code/runtime/tool_executor.py +329 -0
- aria_code/runtime/tool_policy.py +107 -0
- aria_code/runtime/transactions.py +216 -0
- aria_code/runtime/windows_job.py +115 -0
- aria_code/runtime/workflows.py +222 -0
- aria_code/runtime/worktrees.py +215 -0
- aria_code/runway_video_client.py +4 -0
- aria_code/safety/__init__.py +27 -0
- aria_code/safety/client_isolation.py +178 -0
- aria_code/safety/permissions.py +339 -0
- aria_code/safety/risk.py +699 -0
- aria_code/safety/sandbox.py +148 -0
- aria_code/safety/service.py +102 -0
- aria_code/service_endpoints.py +14 -0
- aria_code/setup_wizard.py +684 -0
- aria_code/spreadsheet_tools.py +4 -0
- aria_code/strategy_vault.py +4 -0
- aria_code/tools/__init__.py +0 -0
- aria_code/tools/artifact_tools.py +252 -0
- aria_code/tools/broker_tools.py +92 -0
- aria_code/tools/build_quant_engine.py +97 -0
- aria_code/tools/code_audit_tools.py +192 -0
- aria_code/tools/computer_use_tools.py +509 -0
- aria_code/tools/data_analysis_tools.py +831 -0
- aria_code/tools/enterprise_finance_tools.py +202 -0
- aria_code/tools/extended_tools.py +240 -0
- aria_code/tools/file_analysis_tools.py +880 -0
- aria_code/tools/image_gen_tools.py +114 -0
- aria_code/tools/local_finance_tools.py +3488 -0
- aria_code/tools/logistics_carriers.py +11 -0
- aria_code/tools/logistics_inventory.py +11 -0
- aria_code/tools/logistics_io.py +11 -0
- aria_code/tools/logistics_tenancy.py +11 -0
- aria_code/tools/logistics_tools.py +11 -0
- aria_code/tools/macro_tools.py +412 -0
- aria_code/tools/notification_tools.py +249 -0
- aria_code/tools/project_tools.py +525 -0
- aria_code/tools/realty_data_tools.py +662 -0
- aria_code/tools/spreadsheet_tools.py +399 -0
- aria_code/tools/stripe_tools.py +115 -0
- aria_code/tools/video_tools.py +500 -0
- aria_code/training/__init__.py +1 -0
- aria_code/training/compare.py +117 -0
- aria_code/training/prelude_commands.py +111 -0
- aria_code/training/prelude_eval.py +390 -0
- aria_code/training/prelude_real.py +183 -0
- aria_code/training/prelude_train.py +248 -0
- aria_code/training/sft_dataset.py +230 -0
- aria_code/training/trajectory_dataset.py +263 -0
- aria_code/ui/__init__.py +105 -0
- aria_code/ui/banner.py +404 -0
- aria_code/ui/completer.py +571 -0
- aria_code/ui/console.py +285 -0
- aria_code/ui/input_box.py +505 -0
- aria_code/ui/mentions.py +206 -0
- aria_code/ui/picker.py +248 -0
- aria_code/ui/render/__init__.py +11 -0
- aria_code/ui/render/actions.py +297 -0
- aria_code/ui/render/finance.py +1732 -0
- aria_code/ui/render/market.py +253 -0
- aria_code/ui/render/output.py +954 -0
- aria_code/ui/render/responsive.py +75 -0
- aria_code/ui/render/team.py +367 -0
- aria_code/ui/robot.py +239 -0
- aria_code/ui/startup_dashboard.py +110 -0
- aria_code/video_analysis.py +147 -0
- aria_code/video_editor.py +518 -0
- aria_code/video_workflow/__init__.py +8 -0
- aria_code/video_workflow/__main__.py +61 -0
- aria_code/video_workflow/engines/__init__.py +18 -0
- aria_code/video_workflow/engines/base.py +69 -0
- aria_code/video_workflow/engines/custom_model.py +204 -0
- aria_code/video_workflow/engines/google_veo.py +94 -0
- aria_code/video_workflow/engines/local_engine.py +71 -0
- aria_code/video_workflow/engines/registry.py +98 -0
- aria_code/video_workflow/google_models.py +278 -0
- aria_code/video_workflow/music/__init__.py +5 -0
- aria_code/video_workflow/music/foley_service.py +132 -0
- aria_code/video_workflow/music/service.py +212 -0
- aria_code/video_workflow/pipeline.py +620 -0
- aria_code/video_workflow/plan.py +202 -0
- aria_code/video_workflow/session.py +297 -0
- aria_code/workspace/__init__.py +6 -0
- aria_code/workspace/files.py +219 -0
- aria_code/workspace/verify.py +167 -0
- aria_code/workspace_changes.py +199 -0
- aria_code/workspace_service.py +196 -0
- aria_code/workspace_tools.py +150 -0
- aria_code-0.167.0.dist-info/METADATA +330 -0
- aria_code-0.167.0.dist-info/RECORD +601 -0
- aria_code-0.167.0.dist-info/WHEEL +5 -0
- aria_code-0.167.0.dist-info/entry_points.txt +5 -0
- aria_code-0.167.0.dist-info/licenses/LICENSE +201 -0
- aria_code-0.167.0.dist-info/licenses/NOTICE +49 -0
- aria_code-0.167.0.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,186 @@
|
|
|
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_bots.channels.conversation import ConversationStore
|
|
42
|
+
from aria_bots.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_bots.logistics.carriers import tool_score_carriers
|
|
102
|
+
from aria_bots.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
|
+
+ "\n在群里 @Aria 发送 /补货,可发起采购单草稿审批。")
|
|
121
|
+
if thin:
|
|
122
|
+
sections.append(_section("历史不足、未给建议", [
|
|
123
|
+
f"{i['sku']}:仅 {i['history_days']} 天出库记录" for i in thin]))
|
|
124
|
+
if dead:
|
|
125
|
+
sections.append(_section("呆滞库存", [
|
|
126
|
+
f"{i['sku']}:在库 {i['on_hand']:g}" for i in dead]))
|
|
127
|
+
digest.items += len(reorder) + len(thin) + len(dead)
|
|
128
|
+
else:
|
|
129
|
+
digest.problems.append(f"inventory: {result.get('error')}")
|
|
130
|
+
|
|
131
|
+
if sources.get("waybills"):
|
|
132
|
+
result = tool_score_carriers({"file_path": sources["waybills"]})
|
|
133
|
+
if result.get("success"):
|
|
134
|
+
data = result["data"]
|
|
135
|
+
anomalies, savings = data.get("anomalies") or [], data.get("savings") or []
|
|
136
|
+
if anomalies:
|
|
137
|
+
sections.append(_section("运费待核对", [
|
|
138
|
+
f"{a['waybill_no']}({a['carrier']} {a['lane']}):{a['detail']}" for a in anomalies]))
|
|
139
|
+
if savings:
|
|
140
|
+
sections.append(_section("可节省的线路", [
|
|
141
|
+
f"{s['lane']}:{s['from_carrier']} → {s['to_carrier']},"
|
|
142
|
+
f"按近期运量约省 {s['estimated_saving']:g}(准时率不低于现承运商)" for s in savings]))
|
|
143
|
+
digest.items += len(anomalies) + len(savings)
|
|
144
|
+
else:
|
|
145
|
+
digest.problems.append(f"waybills: {result.get('error')}")
|
|
146
|
+
|
|
147
|
+
if not sources:
|
|
148
|
+
digest.problems.append(f"no feeds configured for {owner_id}")
|
|
149
|
+
digest.body = "\n\n".join(sections) + (
|
|
150
|
+
"\n\n建议数量未计入起订量、箱规和供应商条款;运费异常请先与承运商核对再下结论。" if sections else "")
|
|
151
|
+
return digest
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
async def run_digests(store: ConversationStore, senders: Dict[str, Sender],
|
|
155
|
+
feeds: Optional[Dict[str, Dict[str, str]]] = None) -> List[Dict[str, str]]:
|
|
156
|
+
"""Send today's digest to every bound conversation that has something to say.
|
|
157
|
+
|
|
158
|
+
Returns one record per conversation for the log. Problems — a missing
|
|
159
|
+
feed, a file the tenancy check refused — go to the log only: a client's
|
|
160
|
+
group is not where a 3PL's configuration errors belong.
|
|
161
|
+
"""
|
|
162
|
+
feeds = load_feeds() if feeds is None else feeds
|
|
163
|
+
report: List[Dict[str, str]] = []
|
|
164
|
+
built: Dict[str, Digest] = {}
|
|
165
|
+
for conversation, owner_id in store.bindings():
|
|
166
|
+
channel, _, conversation_id = conversation.partition(":")
|
|
167
|
+
send = senders.get(channel)
|
|
168
|
+
if send is None:
|
|
169
|
+
report.append({"conversation": conversation, "status": "no_sender"})
|
|
170
|
+
continue
|
|
171
|
+
if owner_id not in built:
|
|
172
|
+
try:
|
|
173
|
+
built[owner_id] = build_digest(owner_id, feeds)
|
|
174
|
+
except Exception as exc: # one bad feed must not stop the others
|
|
175
|
+
logger.warning("digest for %s failed: %s", owner_id, exc)
|
|
176
|
+
report.append({"conversation": conversation, "status": "error"})
|
|
177
|
+
continue
|
|
178
|
+
digest = built[owner_id]
|
|
179
|
+
for problem in digest.problems:
|
|
180
|
+
logger.warning("digest %s: %s", owner_id, problem)
|
|
181
|
+
if not digest.worth_sending:
|
|
182
|
+
report.append({"conversation": conversation, "status": "nothing_to_report"})
|
|
183
|
+
continue
|
|
184
|
+
delivered = await send(conversation_id, digest.title, digest.body)
|
|
185
|
+
report.append({"conversation": conversation, "status": "sent" if delivered else "send_failed"})
|
|
186
|
+
return report
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""Channel registry — the declared inventory of external entrypoints.
|
|
2
|
+
|
|
3
|
+
First slice of the channels layer (contract: "Channels submit structured
|
|
4
|
+
tasks to gateway/runtime and never call CLI internals directly"). The
|
|
5
|
+
registry is pure data + config resolution: it names each channel, its
|
|
6
|
+
direction, the config/env that enables it, and which capability it maps to,
|
|
7
|
+
so the daemon and doctor can reason about channels uniformly instead of each
|
|
8
|
+
integration hard-coding its own discovery.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from dataclasses import dataclass, field
|
|
14
|
+
from typing import Any, Dict, List, Mapping, Tuple
|
|
15
|
+
|
|
16
|
+
CHANNEL_TASK_SCHEMA = "aria.channel_task.v1"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass(frozen=True)
|
|
20
|
+
class ChannelSpec:
|
|
21
|
+
name: str
|
|
22
|
+
direction: str # "inbound" | "outbound" | "both"
|
|
23
|
+
description: str
|
|
24
|
+
capabilities: Tuple[str, ...] = ()
|
|
25
|
+
# Any of these config keys (or env vars) being truthy enables the channel.
|
|
26
|
+
config_keys: Tuple[str, ...] = ()
|
|
27
|
+
env_keys: Tuple[str, ...] = ()
|
|
28
|
+
|
|
29
|
+
def enabled(self, config: Mapping[str, Any], env: Mapping[str, str]) -> bool:
|
|
30
|
+
for key in self.config_keys:
|
|
31
|
+
if config.get(key):
|
|
32
|
+
return True
|
|
33
|
+
for key in self.env_keys:
|
|
34
|
+
if str(env.get(key, "") or "").strip():
|
|
35
|
+
return True
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def default_channels() -> List[ChannelSpec]:
|
|
40
|
+
return [
|
|
41
|
+
ChannelSpec(
|
|
42
|
+
name="tradingview",
|
|
43
|
+
direction="inbound",
|
|
44
|
+
description="TradingView alert webhooks → structured alert tasks",
|
|
45
|
+
capabilities=("alerts.ingest", "orders.preview"),
|
|
46
|
+
config_keys=("tradingview_webhook",),
|
|
47
|
+
env_keys=("ARIA_WEBHOOK_SECRET",),
|
|
48
|
+
),
|
|
49
|
+
ChannelSpec(
|
|
50
|
+
name="webhook_jobs",
|
|
51
|
+
direction="inbound",
|
|
52
|
+
description="Generic daemon webhook job queue (/webhook/trigger)",
|
|
53
|
+
capabilities=("tasks.enqueue",),
|
|
54
|
+
env_keys=("WEBHOOK_TOKEN",),
|
|
55
|
+
),
|
|
56
|
+
ChannelSpec(
|
|
57
|
+
name="telegram",
|
|
58
|
+
direction="both",
|
|
59
|
+
description="Telegram bot push + command intake via the daemon",
|
|
60
|
+
capabilities=("notify.push", "chat.intake"),
|
|
61
|
+
config_keys=("telegram_bot_token",),
|
|
62
|
+
env_keys=("TELEGRAM_BOT_TOKEN",),
|
|
63
|
+
),
|
|
64
|
+
ChannelSpec(
|
|
65
|
+
name="feishu",
|
|
66
|
+
direction="outbound",
|
|
67
|
+
description="Feishu webhook card push",
|
|
68
|
+
capabilities=("notify.push",),
|
|
69
|
+
config_keys=("feishu_webhook",),
|
|
70
|
+
env_keys=("FEISHU_WEBHOOK_URL",),
|
|
71
|
+
),
|
|
72
|
+
ChannelSpec(
|
|
73
|
+
name="macos_notify",
|
|
74
|
+
direction="outbound",
|
|
75
|
+
description="Local macOS notification center",
|
|
76
|
+
capabilities=("notify.push",),
|
|
77
|
+
config_keys=("macos_notifications",),
|
|
78
|
+
),
|
|
79
|
+
ChannelSpec(
|
|
80
|
+
name="email",
|
|
81
|
+
direction="outbound",
|
|
82
|
+
description="SMTP email push",
|
|
83
|
+
capabilities=("notify.push",),
|
|
84
|
+
config_keys=("email_smtp_host",),
|
|
85
|
+
env_keys=("ARIA_SMTP_HOST",),
|
|
86
|
+
),
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def channel_map() -> Dict[str, ChannelSpec]:
|
|
91
|
+
return {spec.name: spec for spec in default_channels()}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def enabled_channels(config: Mapping[str, Any], env: Mapping[str, str]) -> List[ChannelSpec]:
|
|
95
|
+
return [spec for spec in default_channels() if spec.enabled(config, env)]
|
aria_bots/engine.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"""Run one chat turn on the Go engine (`aria-runtime stream`).
|
|
2
|
+
|
|
3
|
+
The bots used to shell out to aria_cli.py. Now a turn is
|
|
4
|
+
|
|
5
|
+
aria-runtime stream --format=jsonl --quiet --no-banner --prompt=...
|
|
6
|
+
|
|
7
|
+
in a workspace of its own, read as JSONL until `turn.completed`. The engine
|
|
8
|
+
runs headless: a tool that needs approval is refused, because nobody in the
|
|
9
|
+
chat can answer the prompt. An operator grants named tools with
|
|
10
|
+
ARIA_BOT_ALLOW_TOOLS.
|
|
11
|
+
|
|
12
|
+
The logistics tools reach the engine as an MCP server the bots register
|
|
13
|
+
through ARIA_MCP_EXTRA_CONFIG, so the user's own mcp_servers.json is left
|
|
14
|
+
alone. A conversation bound to a shipper passes ARIA_OWNER_SCOPE down; the
|
|
15
|
+
engine hands its environment to the MCP server, where logistics.tenancy
|
|
16
|
+
enforces it.
|
|
17
|
+
"""
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import asyncio
|
|
21
|
+
import json
|
|
22
|
+
import os
|
|
23
|
+
import shutil
|
|
24
|
+
import sys
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
from typing import Iterable, Optional
|
|
27
|
+
|
|
28
|
+
from .logistics.tenancy import OWNER_SCOPE_ENV
|
|
29
|
+
|
|
30
|
+
ENGINE_ENV = "ARIA_RUNTIME"
|
|
31
|
+
MAX_PROMPT = 65536
|
|
32
|
+
LOGISTICS_SERVER = "aria-logistics"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def state_dir() -> Path:
|
|
36
|
+
base = os.environ.get("ARIA_BOTS_HOME", "").strip()
|
|
37
|
+
return Path(base).expanduser() if base else Path.home() / ".aria" / "bots"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def find_engine() -> Optional[str]:
|
|
41
|
+
"""ARIA_RUNTIME when it names an aria-runtime, else aria-runtime on PATH."""
|
|
42
|
+
configured = os.environ.get(ENGINE_ENV, "").strip()
|
|
43
|
+
if configured:
|
|
44
|
+
path = Path(configured).expanduser()
|
|
45
|
+
if path.name.removesuffix(".exe").startswith("aria-runtime") and path.is_file() and os.access(path, os.X_OK):
|
|
46
|
+
return str(path)
|
|
47
|
+
return shutil.which("aria-runtime")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def mcp_config() -> Path:
|
|
51
|
+
"""The servers the bots add to every engine turn (rewritten each time)."""
|
|
52
|
+
folder = state_dir()
|
|
53
|
+
folder.mkdir(parents=True, exist_ok=True)
|
|
54
|
+
server = {
|
|
55
|
+
"name": LOGISTICS_SERVER,
|
|
56
|
+
"command": sys.executable,
|
|
57
|
+
"args": ["-m", "aria_bots.logistics.mcp_server"],
|
|
58
|
+
"description": "Freight analysis, carrier scoring and inventory policy, scoped per shipper",
|
|
59
|
+
}
|
|
60
|
+
path = folder / "mcp_servers.json"
|
|
61
|
+
path.write_text(json.dumps({"servers": [server]}, indent=2), encoding="utf-8")
|
|
62
|
+
return path
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def allowed_tools() -> list[str]:
|
|
66
|
+
return [t.strip() for t in os.environ.get("ARIA_BOT_ALLOW_TOOLS", "").split(",") if t.strip()]
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def with_history(prompt: str, history: Optional[Iterable[dict]]) -> str:
|
|
70
|
+
"""The engine takes one prompt; earlier messages go in front of it."""
|
|
71
|
+
lines = []
|
|
72
|
+
for item in history or []:
|
|
73
|
+
role = "Assistant" if item.get("role") == "assistant" else "User"
|
|
74
|
+
content = str(item.get("content", "")).strip()
|
|
75
|
+
if content:
|
|
76
|
+
lines.append(f"{role}: {content}")
|
|
77
|
+
if not lines:
|
|
78
|
+
return prompt
|
|
79
|
+
return "Earlier in this conversation:\n" + "\n".join(lines) + "\n\nNow answer:\n" + prompt
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def command(engine: str, prompt: str) -> list[str]:
|
|
83
|
+
argv = [engine, "stream", "--format=jsonl", "--quiet", "--no-banner", f"--prompt={prompt}"]
|
|
84
|
+
tools = allowed_tools()
|
|
85
|
+
if tools:
|
|
86
|
+
argv += ["--allow-tools", ",".join(tools)]
|
|
87
|
+
return argv
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def environment(owner: Optional[str]) -> dict[str, str]:
|
|
91
|
+
env = {**os.environ, "ARIA_BOT_MODE": "1", "ARIA_MCP_EXTRA_CONFIG": str(mcp_config())}
|
|
92
|
+
env.pop(OWNER_SCOPE_ENV, None)
|
|
93
|
+
if owner:
|
|
94
|
+
env[OWNER_SCOPE_ENV] = owner
|
|
95
|
+
return env
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def read_answer(stdout: bytes) -> tuple[bool, str]:
|
|
99
|
+
"""(success, answer) from the engine's JSONL; deltas when no final text."""
|
|
100
|
+
deltas: list[str] = []
|
|
101
|
+
for raw in stdout.splitlines():
|
|
102
|
+
try:
|
|
103
|
+
event = json.loads(raw)
|
|
104
|
+
except ValueError:
|
|
105
|
+
continue
|
|
106
|
+
if not isinstance(event, dict):
|
|
107
|
+
continue
|
|
108
|
+
kind = event.get("type")
|
|
109
|
+
if kind == "answer.delta":
|
|
110
|
+
deltas.append(str(event.get("text") or event.get("delta") or ""))
|
|
111
|
+
elif kind == "turn.completed":
|
|
112
|
+
answer = str(event.get("response") or "".join(deltas)).strip()
|
|
113
|
+
return bool(event.get("success")), answer or str(event.get("error") or "")
|
|
114
|
+
return False, "".join(deltas).strip()
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
async def run_turn(prompt: str, *, engine: str, owner: Optional[str] = None,
|
|
118
|
+
history: Optional[Iterable[dict]] = None, timeout: float = 120) -> str:
|
|
119
|
+
"""The answer text, or a message starting with ❌ / ⏱️ when there is none."""
|
|
120
|
+
prompt = with_history(prompt, history)
|
|
121
|
+
if len(prompt.encode("utf-8")) > MAX_PROMPT:
|
|
122
|
+
return "❌ 消息太长,请缩短后重试。"
|
|
123
|
+
workspace = state_dir() / "workspace"
|
|
124
|
+
workspace.mkdir(parents=True, exist_ok=True)
|
|
125
|
+
proc = await asyncio.create_subprocess_exec(
|
|
126
|
+
*command(engine, prompt),
|
|
127
|
+
stdin=asyncio.subprocess.PIPE,
|
|
128
|
+
stdout=asyncio.subprocess.PIPE,
|
|
129
|
+
stderr=asyncio.subprocess.PIPE,
|
|
130
|
+
cwd=str(workspace),
|
|
131
|
+
env=environment(owner),
|
|
132
|
+
)
|
|
133
|
+
try:
|
|
134
|
+
# One newline acknowledges the host; EOF after it, so nothing can wait on input.
|
|
135
|
+
stdout, stderr = await asyncio.wait_for(proc.communicate(b"\n"), timeout=timeout)
|
|
136
|
+
except asyncio.TimeoutError:
|
|
137
|
+
proc.kill()
|
|
138
|
+
await proc.wait()
|
|
139
|
+
return f"⏱️ 查询超时(>{int(timeout)}s),请简化问题后重试。"
|
|
140
|
+
ok, answer = read_answer(stdout)
|
|
141
|
+
if answer and (ok or proc.returncode == 0):
|
|
142
|
+
return answer[:3000]
|
|
143
|
+
detail = answer or stderr.decode("utf-8", errors="replace").strip()[-500:] or f"exit {proc.returncode}"
|
|
144
|
+
return f"❌ Aria 引擎未能完成:{detail}"
|