aria-code 0.167.0__py3-none-win_amd64.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.exe +0 -0
- aria_code/_bin/aria-runtime.exe +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
aria_code/packs/rules.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""Where a pack learns what "correct" means in *this* workspace.
|
|
2
|
+
|
|
3
|
+
A pack knows the shape of its domain — that a waybill is a waybill, that
|
|
4
|
+
``ch_3P…`` is a Stripe charge. It cannot know how a particular company checks
|
|
5
|
+
that work on those things was done right: which script reconciles their ledger,
|
|
6
|
+
which job validates their schema, what their build is called. That knowledge
|
|
7
|
+
belongs to the workspace, not to the pack, and it is the one thing that has to
|
|
8
|
+
come from outside for the closed loop to mean anything in a domain the core
|
|
9
|
+
never learned.
|
|
10
|
+
|
|
11
|
+
So packs read it from the project's own ``.ariarc``::
|
|
12
|
+
|
|
13
|
+
"acceptance": {
|
|
14
|
+
"default": ["python3 -m pytest -q"],
|
|
15
|
+
"logistics": ["python3 scripts/reconcile_waybills.py"],
|
|
16
|
+
"payments": ["python3 scripts/verify_stripe_sync.py"]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
``default`` applies to every turn. A pack-named list applies only when that
|
|
20
|
+
pack resolved a concrete entity from the user's message — the same activation
|
|
21
|
+
rule that governs everything else a pack contributes, so declaring a logistics
|
|
22
|
+
check cannot slow down or perturb a payments question.
|
|
23
|
+
|
|
24
|
+
This is the whole productisation story for a new industry: a company does not
|
|
25
|
+
extend Aria to adopt it, they declare what green looks like and the loop they
|
|
26
|
+
already have starts holding that line.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from __future__ import annotations
|
|
30
|
+
|
|
31
|
+
import logging
|
|
32
|
+
from typing import Sequence
|
|
33
|
+
|
|
34
|
+
logger = logging.getLogger(__name__)
|
|
35
|
+
|
|
36
|
+
DEFAULT_KEY = "default"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _coerce(value: object) -> tuple[str, ...]:
|
|
40
|
+
"""Accept a string or a list of them; ignore anything else.
|
|
41
|
+
|
|
42
|
+
Hand-edited config is the input here, so a single command written as a
|
|
43
|
+
bare string is the expected mistake, not an error worth failing a turn
|
|
44
|
+
over.
|
|
45
|
+
"""
|
|
46
|
+
if isinstance(value, str):
|
|
47
|
+
text = value.strip()
|
|
48
|
+
return (text,) if text else ()
|
|
49
|
+
if isinstance(value, (list, tuple)):
|
|
50
|
+
out: list[str] = []
|
|
51
|
+
for item in value:
|
|
52
|
+
if isinstance(item, str) and item.strip():
|
|
53
|
+
out.append(item.strip())
|
|
54
|
+
return tuple(out)
|
|
55
|
+
return ()
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def acceptance_commands_for(pack_name: str, *, rc: object = None) -> tuple[str, ...]:
|
|
59
|
+
"""Commands this workspace declares for *pack_name*.
|
|
60
|
+
|
|
61
|
+
Never raises: a malformed or missing ``.ariarc`` means "nothing declared",
|
|
62
|
+
which falls back to inference from the workspace — the behaviour before
|
|
63
|
+
any of this existed.
|
|
64
|
+
"""
|
|
65
|
+
config = rc
|
|
66
|
+
if config is None:
|
|
67
|
+
try:
|
|
68
|
+
from aria_code.ariarc import get_ariarc
|
|
69
|
+
|
|
70
|
+
config = get_ariarc()
|
|
71
|
+
except Exception:
|
|
72
|
+
logger.debug("could not load .ariarc for acceptance commands", exc_info=True)
|
|
73
|
+
return ()
|
|
74
|
+
|
|
75
|
+
table = getattr(config, "acceptance", None)
|
|
76
|
+
if not isinstance(table, dict):
|
|
77
|
+
return ()
|
|
78
|
+
return _coerce(table.get(pack_name))
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def default_acceptance_commands(*, rc: object = None) -> tuple[str, ...]:
|
|
82
|
+
"""Commands this workspace declares for every turn, pack or not."""
|
|
83
|
+
return acceptance_commands_for(DEFAULT_KEY, rc=rc)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
__all__ = [
|
|
87
|
+
"DEFAULT_KEY",
|
|
88
|
+
"acceptance_commands_for",
|
|
89
|
+
"default_acceptance_commands",
|
|
90
|
+
]
|
aria_code/plan_utils.py
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""
|
|
2
|
+
plan_utils.py — Plan parsing helpers for Aria Code CLI workflow commands.
|
|
3
|
+
|
|
4
|
+
Supports several natural input styles:
|
|
5
|
+
|
|
6
|
+
Numbered steps (most common):
|
|
7
|
+
1. Fetch AAPL quote
|
|
8
|
+
2. Generate 6-month chart
|
|
9
|
+
3. Output analysis report
|
|
10
|
+
|
|
11
|
+
Bullet list:
|
|
12
|
+
- Fetch quote
|
|
13
|
+
- Generate chart
|
|
14
|
+
- Output report
|
|
15
|
+
|
|
16
|
+
Inline arrow / semicolon chain:
|
|
17
|
+
fetch quote -> generate chart -> output report
|
|
18
|
+
fetch quote; generate chart; output report
|
|
19
|
+
|
|
20
|
+
Mixed (numbered + description):
|
|
21
|
+
Step 1: Fetch AAPL quote
|
|
22
|
+
Step 2: Generate chart with SMA20
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
import re
|
|
28
|
+
from dataclasses import dataclass, field
|
|
29
|
+
from typing import List, Optional
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# ── Data model ────────────────────────────────────────────────────────────────
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class PlanStep:
|
|
36
|
+
"""A single executable step in a plan."""
|
|
37
|
+
index: int # 1-based position
|
|
38
|
+
description: str # human-readable description
|
|
39
|
+
name: Optional[str] = None # optional short name / label
|
|
40
|
+
deps: List[int] = field(default_factory=list) # dependency indices
|
|
41
|
+
|
|
42
|
+
def __str__(self) -> str:
|
|
43
|
+
dep_str = f" [deps: {','.join(str(d) for d in self.deps)}]" if self.deps else ""
|
|
44
|
+
return f"{self.index}. {self.description}{dep_str}"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# ── Patterns ──────────────────────────────────────────────────────────────────
|
|
48
|
+
|
|
49
|
+
# "1. text", "1) text", "Step 1: text", "Step 1 — text"
|
|
50
|
+
_RE_NUMBERED = re.compile(
|
|
51
|
+
r"^(?:step\s*)?(\d+)[.):\-–—]\s*(.+)$",
|
|
52
|
+
re.IGNORECASE,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# "- text", "• text", "* text", "· text"
|
|
56
|
+
_RE_BULLET = re.compile(r"^[-•*·]\s+(.+)$")
|
|
57
|
+
|
|
58
|
+
# Metadata tags like [name: Build] or [deps: 1,3]
|
|
59
|
+
_RE_META_NAME = re.compile(r"\[name:\s*([^\]]+)\]", re.IGNORECASE)
|
|
60
|
+
_RE_META_DEPS = re.compile(r"\[deps:\s*([^\]]+)\]", re.IGNORECASE)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _strip_meta(text: str) -> tuple[str, Optional[str], List[int]]:
|
|
64
|
+
"""Extract and remove [name:...] and [deps:...] metadata from text."""
|
|
65
|
+
name: Optional[str] = None
|
|
66
|
+
deps: List[int] = []
|
|
67
|
+
|
|
68
|
+
m = _RE_META_NAME.search(text)
|
|
69
|
+
if m:
|
|
70
|
+
name = m.group(1).strip()
|
|
71
|
+
text = text[:m.start()] + text[m.end():]
|
|
72
|
+
|
|
73
|
+
m = _RE_META_DEPS.search(text)
|
|
74
|
+
if m:
|
|
75
|
+
raw = m.group(1)
|
|
76
|
+
deps = [int(x.strip()) for x in re.split(r"[,;\s]+", raw) if x.strip().isdigit()]
|
|
77
|
+
text = text[:m.start()] + text[m.end():]
|
|
78
|
+
|
|
79
|
+
return text.strip(), name, deps
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# ── Public API ────────────────────────────────────────────────────────────────
|
|
83
|
+
|
|
84
|
+
def parse_plan_steps(raw: str) -> List[str]:
|
|
85
|
+
"""
|
|
86
|
+
Parse '/plan' argument string into a list of plain step description strings.
|
|
87
|
+
|
|
88
|
+
This is the backwards-compatible API used by aria_cli.py.
|
|
89
|
+
|
|
90
|
+
Returns a list of non-empty step strings, in order.
|
|
91
|
+
"""
|
|
92
|
+
return [s.description for s in parse_plan(raw)]
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def parse_plan(raw: str) -> List[PlanStep]:
|
|
96
|
+
"""
|
|
97
|
+
Full parser — returns a list of PlanStep objects with index, description,
|
|
98
|
+
optional name, and dependency list.
|
|
99
|
+
|
|
100
|
+
Handles mixed input styles (numbered, bulleted, arrow/semicolon chained).
|
|
101
|
+
"""
|
|
102
|
+
if not raw or not raw.strip():
|
|
103
|
+
return []
|
|
104
|
+
|
|
105
|
+
text = raw.strip()
|
|
106
|
+
|
|
107
|
+
# ── Strategy 1: multiline numbered or bulleted steps ─────────────────────
|
|
108
|
+
lines = [ln.strip() for ln in text.splitlines() if ln.strip()]
|
|
109
|
+
if len(lines) >= 2:
|
|
110
|
+
steps = _parse_lines(lines)
|
|
111
|
+
if steps:
|
|
112
|
+
return steps
|
|
113
|
+
|
|
114
|
+
# ── Strategy 2: inline arrow chain fetch quote -> chart -> report ───────
|
|
115
|
+
# Also handles semicolons within arrow-separated parts:
|
|
116
|
+
# "git status -> rg TODO . ; pytest -q" → 3 steps
|
|
117
|
+
if "->" in text:
|
|
118
|
+
arrow_parts = [p.strip() for p in text.replace("→", "->").split("->") if p.strip()]
|
|
119
|
+
parts: List[str] = []
|
|
120
|
+
for ap in arrow_parts:
|
|
121
|
+
if ";" in ap:
|
|
122
|
+
parts.extend(p.strip() for p in ap.split(";") if p.strip())
|
|
123
|
+
else:
|
|
124
|
+
parts.append(ap)
|
|
125
|
+
return [PlanStep(index=i + 1, description=p) for i, p in enumerate(parts)]
|
|
126
|
+
|
|
127
|
+
# ── Strategy 3: semicolon-separated steps ────────────────────────────────
|
|
128
|
+
if ";" in text:
|
|
129
|
+
parts = [p.strip() for p in text.split(";") if p.strip()]
|
|
130
|
+
return [PlanStep(index=i + 1, description=p) for i, p in enumerate(parts)]
|
|
131
|
+
|
|
132
|
+
# ── Strategy 4: single step ───────────────────────────────────────────────
|
|
133
|
+
desc, name, deps = _strip_meta(text)
|
|
134
|
+
return [PlanStep(index=1, description=desc, name=name, deps=deps)] if desc else []
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _parse_lines(lines: List[str]) -> List[PlanStep]:
|
|
138
|
+
"""Try to extract ordered steps from a list of text lines."""
|
|
139
|
+
steps: List[PlanStep] = []
|
|
140
|
+
expected_idx = 1
|
|
141
|
+
|
|
142
|
+
for line in lines:
|
|
143
|
+
# Try numbered pattern
|
|
144
|
+
m = _RE_NUMBERED.match(line)
|
|
145
|
+
if m:
|
|
146
|
+
idx = int(m.group(1))
|
|
147
|
+
desc_raw = m.group(2).strip()
|
|
148
|
+
desc, name, deps = _strip_meta(desc_raw)
|
|
149
|
+
if desc:
|
|
150
|
+
steps.append(PlanStep(index=idx, description=desc, name=name, deps=deps))
|
|
151
|
+
expected_idx = idx + 1
|
|
152
|
+
continue
|
|
153
|
+
|
|
154
|
+
# Try bullet pattern
|
|
155
|
+
m = _RE_BULLET.match(line)
|
|
156
|
+
if m:
|
|
157
|
+
desc_raw = m.group(1).strip()
|
|
158
|
+
desc, name, deps = _strip_meta(desc_raw)
|
|
159
|
+
if desc:
|
|
160
|
+
steps.append(PlanStep(index=expected_idx, description=desc, name=name, deps=deps))
|
|
161
|
+
expected_idx += 1
|
|
162
|
+
continue
|
|
163
|
+
|
|
164
|
+
return steps
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
# ── Formatting helpers ────────────────────────────────────────────────────────
|
|
168
|
+
|
|
169
|
+
def format_plan(steps: List[PlanStep], title: str = "Plan") -> str:
|
|
170
|
+
"""Format a plan for terminal display."""
|
|
171
|
+
if not steps:
|
|
172
|
+
return f"[{title}] (empty)"
|
|
173
|
+
lines = [f"── {title} ({len(steps)} steps) ──"]
|
|
174
|
+
for s in steps:
|
|
175
|
+
dep_str = f" (after {', '.join(str(d) for d in s.deps)})" if s.deps else ""
|
|
176
|
+
label = f" [{s.name}]" if s.name else ""
|
|
177
|
+
lines.append(f" {s.index}.{label} {s.description}{dep_str}")
|
|
178
|
+
return "\n".join(lines)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def steps_to_prompt(steps: List[PlanStep], context: str = "") -> str:
|
|
182
|
+
"""
|
|
183
|
+
Convert a list of PlanStep objects to a structured prompt string
|
|
184
|
+
that the AI can execute step-by-step.
|
|
185
|
+
"""
|
|
186
|
+
intro = f"{context}\n\n" if context else ""
|
|
187
|
+
numbered = "\n".join(f"{s.index}. {s.description}" for s in steps)
|
|
188
|
+
return (
|
|
189
|
+
f"{intro}"
|
|
190
|
+
f"Execute the following plan steps in order:\n\n"
|
|
191
|
+
f"{numbered}\n\n"
|
|
192
|
+
"Complete each step fully before moving to the next. "
|
|
193
|
+
"After all steps, provide a brief summary of what was accomplished."
|
|
194
|
+
)
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
"""
|
|
2
|
+
plugin_loader.py — Auto-discovery of custom tool plugins for Aria Code.
|
|
3
|
+
|
|
4
|
+
Scans the current directory and its parents for ``aria_tools.py`` files and
|
|
5
|
+
loads any tools they export. This lets project-specific tools appear
|
|
6
|
+
automatically in the model's tool loop without modifying aria_cli.py.
|
|
7
|
+
|
|
8
|
+
Plugin contract (aria_tools.py)::
|
|
9
|
+
|
|
10
|
+
# Minimal example
|
|
11
|
+
def get_my_tools():
|
|
12
|
+
return [
|
|
13
|
+
{
|
|
14
|
+
"name": "my_custom_tool",
|
|
15
|
+
"description": "Does something useful for this project",
|
|
16
|
+
"parameters": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"properties": {
|
|
19
|
+
"input": {"type": "string", "description": "Input data"},
|
|
20
|
+
},
|
|
21
|
+
"required": ["input"],
|
|
22
|
+
},
|
|
23
|
+
"handler": lambda params: {"result": params["input"].upper()},
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
# Extended example with finance tools
|
|
28
|
+
import akshare as ak
|
|
29
|
+
|
|
30
|
+
def get_my_tools():
|
|
31
|
+
def fetch_my_positions(params):
|
|
32
|
+
# read from broker API / local file
|
|
33
|
+
return {"positions": [...]}
|
|
34
|
+
|
|
35
|
+
return [
|
|
36
|
+
{
|
|
37
|
+
"name": "get_my_positions",
|
|
38
|
+
"description": "Return current portfolio positions from local CSV",
|
|
39
|
+
"parameters": {"type": "object", "properties": {}, "required": []},
|
|
40
|
+
"handler": fetch_my_positions,
|
|
41
|
+
},
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
Discovery order
|
|
45
|
+
---------------
|
|
46
|
+
1. ``./aria_tools.py`` (current working directory)
|
|
47
|
+
2. ``../aria_tools.py`` (one level up)
|
|
48
|
+
3. …up to $HOME
|
|
49
|
+
|
|
50
|
+
The first file found is used. Set ``ARIA_TOOLS_PATH`` env var to override.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
from __future__ import annotations
|
|
54
|
+
|
|
55
|
+
import importlib.util
|
|
56
|
+
import logging
|
|
57
|
+
import os
|
|
58
|
+
import pathlib
|
|
59
|
+
import sys
|
|
60
|
+
import traceback
|
|
61
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple
|
|
62
|
+
|
|
63
|
+
logger = logging.getLogger(__name__)
|
|
64
|
+
|
|
65
|
+
# Env override
|
|
66
|
+
ARIA_TOOLS_ENV = "ARIA_TOOLS_PATH"
|
|
67
|
+
PLUGIN_FILENAME = "aria_tools.py"
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# ---------------------------------------------------------------------------
|
|
71
|
+
# Discovery
|
|
72
|
+
# ---------------------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
def find_plugin_file(start_dir: Optional[str] = None) -> Optional[pathlib.Path]:
|
|
75
|
+
"""
|
|
76
|
+
Walk upward from *start_dir* looking for aria_tools.py.
|
|
77
|
+
Returns the first match, or None.
|
|
78
|
+
"""
|
|
79
|
+
# Env var override takes priority
|
|
80
|
+
env_path = os.getenv(ARIA_TOOLS_ENV)
|
|
81
|
+
if env_path:
|
|
82
|
+
p = pathlib.Path(env_path).expanduser().resolve()
|
|
83
|
+
if p.exists():
|
|
84
|
+
return p
|
|
85
|
+
|
|
86
|
+
home = pathlib.Path.home()
|
|
87
|
+
current = pathlib.Path(start_dir or os.getcwd()).resolve()
|
|
88
|
+
|
|
89
|
+
while True:
|
|
90
|
+
candidate = current / PLUGIN_FILENAME
|
|
91
|
+
if candidate.exists() and candidate.is_file():
|
|
92
|
+
return candidate
|
|
93
|
+
if current == home or current.parent == current:
|
|
94
|
+
break
|
|
95
|
+
current = current.parent
|
|
96
|
+
return None
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# ---------------------------------------------------------------------------
|
|
100
|
+
# Loader
|
|
101
|
+
# ---------------------------------------------------------------------------
|
|
102
|
+
|
|
103
|
+
def load_plugin(plugin_path: pathlib.Path) -> List[Dict[str, Any]]:
|
|
104
|
+
"""
|
|
105
|
+
Import *plugin_path* as a module and call its ``get_my_tools()`` function.
|
|
106
|
+
|
|
107
|
+
Returns list of tool dicts with keys:
|
|
108
|
+
name, description, parameters (JSON Schema), handler (callable)
|
|
109
|
+
"""
|
|
110
|
+
try:
|
|
111
|
+
spec = importlib.util.spec_from_file_location("aria_tools_plugin", plugin_path)
|
|
112
|
+
module = importlib.util.module_from_spec(spec)
|
|
113
|
+
# Add plugin directory to sys.path so it can import local modules
|
|
114
|
+
plugin_dir = str(plugin_path.parent)
|
|
115
|
+
if plugin_dir not in sys.path:
|
|
116
|
+
sys.path.insert(0, plugin_dir)
|
|
117
|
+
spec.loader.exec_module(module)
|
|
118
|
+
except Exception as exc:
|
|
119
|
+
logger.warning("Plugin load error (%s): %s", plugin_path, exc)
|
|
120
|
+
logger.debug(traceback.format_exc())
|
|
121
|
+
return []
|
|
122
|
+
|
|
123
|
+
# Try standard function name first, then fallback names
|
|
124
|
+
for fn_name in ("get_my_tools", "get_tools", "register_tools", "tools"):
|
|
125
|
+
fn = getattr(module, fn_name, None)
|
|
126
|
+
if callable(fn):
|
|
127
|
+
try:
|
|
128
|
+
tools = fn()
|
|
129
|
+
if isinstance(tools, list):
|
|
130
|
+
logger.info("Plugin %s: loaded %d tools via %s()", plugin_path.name, len(tools), fn_name)
|
|
131
|
+
return _validate_tools(tools, plugin_path)
|
|
132
|
+
except Exception as exc:
|
|
133
|
+
logger.warning("Plugin %s: %s() raised: %s", plugin_path.name, fn_name, exc)
|
|
134
|
+
continue
|
|
135
|
+
# Also support module-level TOOLS list
|
|
136
|
+
if fn_name == "tools" and isinstance(fn, list):
|
|
137
|
+
return _validate_tools(fn, plugin_path)
|
|
138
|
+
|
|
139
|
+
logger.warning("Plugin %s: no get_my_tools() / get_tools() function found", plugin_path.name)
|
|
140
|
+
return []
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _validate_tools(raw: List[Any], plugin_path: pathlib.Path) -> List[Dict[str, Any]]:
|
|
144
|
+
"""Validate and normalise plugin tool definitions."""
|
|
145
|
+
valid = []
|
|
146
|
+
for item in raw:
|
|
147
|
+
if not isinstance(item, dict):
|
|
148
|
+
continue
|
|
149
|
+
name = item.get("name", "").strip()
|
|
150
|
+
desc = item.get("description", "")
|
|
151
|
+
handler = item.get("handler") or item.get("fn") or item.get("function")
|
|
152
|
+
params = item.get("parameters") or item.get("params") or {
|
|
153
|
+
"type": "object", "properties": {}, "required": []
|
|
154
|
+
}
|
|
155
|
+
if not name:
|
|
156
|
+
logger.debug("Plugin tool missing 'name', skipping")
|
|
157
|
+
continue
|
|
158
|
+
if not callable(handler):
|
|
159
|
+
logger.debug("Plugin tool %r has no callable handler, skipping", name)
|
|
160
|
+
continue
|
|
161
|
+
valid.append({
|
|
162
|
+
"name": name,
|
|
163
|
+
"description": desc,
|
|
164
|
+
"parameters": params,
|
|
165
|
+
"handler": handler,
|
|
166
|
+
"source": str(plugin_path),
|
|
167
|
+
})
|
|
168
|
+
return valid
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
# ---------------------------------------------------------------------------
|
|
172
|
+
# Registration
|
|
173
|
+
# ---------------------------------------------------------------------------
|
|
174
|
+
|
|
175
|
+
def register_plugin_tools(
|
|
176
|
+
tool_registry: Dict,
|
|
177
|
+
schema_registry: List,
|
|
178
|
+
start_dir: Optional[str] = None,
|
|
179
|
+
overwrite: bool = False,
|
|
180
|
+
) -> Tuple[int, Optional[pathlib.Path]]:
|
|
181
|
+
"""
|
|
182
|
+
Auto-discover and register plugin tools.
|
|
183
|
+
|
|
184
|
+
Returns (count_registered, plugin_path_or_None).
|
|
185
|
+
"""
|
|
186
|
+
plugin_path = find_plugin_file(start_dir)
|
|
187
|
+
if plugin_path is None:
|
|
188
|
+
return 0, None
|
|
189
|
+
|
|
190
|
+
tools = load_plugin(plugin_path)
|
|
191
|
+
if not tools:
|
|
192
|
+
return 0, plugin_path
|
|
193
|
+
|
|
194
|
+
added = 0
|
|
195
|
+
existing_names = set(tool_registry.keys())
|
|
196
|
+
existing_schema_names = {
|
|
197
|
+
s.get("function", {}).get("name") for s in schema_registry
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
for tool in tools:
|
|
201
|
+
name = tool["name"]
|
|
202
|
+
handler = tool["handler"]
|
|
203
|
+
desc = tool["description"]
|
|
204
|
+
params = tool["parameters"]
|
|
205
|
+
|
|
206
|
+
if name in existing_names and not overwrite:
|
|
207
|
+
logger.debug("Plugin tool %r skipped (already registered)", name)
|
|
208
|
+
continue
|
|
209
|
+
|
|
210
|
+
# Wrap handler with error guard
|
|
211
|
+
def _safe_handler(p: dict, h: Callable = handler) -> dict:
|
|
212
|
+
try:
|
|
213
|
+
result = h(p)
|
|
214
|
+
if not isinstance(result, dict):
|
|
215
|
+
result = {"result": result}
|
|
216
|
+
return result
|
|
217
|
+
except Exception as exc:
|
|
218
|
+
return {"success": False, "error": str(exc), "source": "plugin"}
|
|
219
|
+
|
|
220
|
+
tool_registry[name] = (_safe_handler, desc)
|
|
221
|
+
added += 1
|
|
222
|
+
|
|
223
|
+
if name not in existing_schema_names:
|
|
224
|
+
schema_registry.append({
|
|
225
|
+
"type": "function",
|
|
226
|
+
"function": {
|
|
227
|
+
"name": name,
|
|
228
|
+
"description": desc,
|
|
229
|
+
"parameters": params,
|
|
230
|
+
},
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
if added:
|
|
234
|
+
logger.info("Plugin %s: registered %d tools", plugin_path.name, added)
|
|
235
|
+
|
|
236
|
+
return added, plugin_path
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
# ---------------------------------------------------------------------------
|
|
240
|
+
# Hot-reload support
|
|
241
|
+
# ---------------------------------------------------------------------------
|
|
242
|
+
|
|
243
|
+
class PluginWatcher:
|
|
244
|
+
"""
|
|
245
|
+
Watch the plugin file for changes and reload tools automatically.
|
|
246
|
+
Uses simple mtime polling (no watchdog dependency needed).
|
|
247
|
+
"""
|
|
248
|
+
|
|
249
|
+
def __init__(
|
|
250
|
+
self,
|
|
251
|
+
tool_registry: Dict,
|
|
252
|
+
schema_registry: List,
|
|
253
|
+
start_dir: Optional[str] = None,
|
|
254
|
+
poll_interval: float = 3.0,
|
|
255
|
+
):
|
|
256
|
+
self._tool_registry = tool_registry
|
|
257
|
+
self._schema_registry = schema_registry
|
|
258
|
+
self._start_dir = start_dir
|
|
259
|
+
self._poll_interval = poll_interval
|
|
260
|
+
self._plugin_path: Optional[pathlib.Path] = None
|
|
261
|
+
self._last_mtime: float = 0.0
|
|
262
|
+
self._task: Optional[Any] = None # asyncio.Task
|
|
263
|
+
self._plugin_tool_names: List[str] = []
|
|
264
|
+
|
|
265
|
+
async def start(self):
|
|
266
|
+
"""Start the background polling task."""
|
|
267
|
+
import asyncio
|
|
268
|
+
# Initial load
|
|
269
|
+
n, path = register_plugin_tools(
|
|
270
|
+
self._tool_registry, self._schema_registry, self._start_dir
|
|
271
|
+
)
|
|
272
|
+
if path:
|
|
273
|
+
self._plugin_path = path
|
|
274
|
+
self._last_mtime = path.stat().st_mtime
|
|
275
|
+
self._plugin_tool_names = [
|
|
276
|
+
t["name"] for t in load_plugin(path)
|
|
277
|
+
]
|
|
278
|
+
if n:
|
|
279
|
+
logger.info("PluginWatcher: initial load %d tools from %s", n, path.name)
|
|
280
|
+
|
|
281
|
+
self._task = asyncio.create_task(self._watch_loop())
|
|
282
|
+
|
|
283
|
+
async def _watch_loop(self):
|
|
284
|
+
import asyncio
|
|
285
|
+
while True:
|
|
286
|
+
await asyncio.sleep(self._poll_interval)
|
|
287
|
+
if self._plugin_path is None:
|
|
288
|
+
# Try to find newly created plugin
|
|
289
|
+
found = find_plugin_file(self._start_dir)
|
|
290
|
+
if found:
|
|
291
|
+
self._plugin_path = found
|
|
292
|
+
self._last_mtime = 0.0
|
|
293
|
+
if self._plugin_path and self._plugin_path.exists():
|
|
294
|
+
mtime = self._plugin_path.stat().st_mtime
|
|
295
|
+
if mtime != self._last_mtime:
|
|
296
|
+
self._last_mtime = mtime
|
|
297
|
+
await self._reload()
|
|
298
|
+
|
|
299
|
+
async def _reload(self):
|
|
300
|
+
if not self._plugin_path:
|
|
301
|
+
return
|
|
302
|
+
# Remove previously registered plugin tools
|
|
303
|
+
for name in self._plugin_tool_names:
|
|
304
|
+
self._tool_registry.pop(name, None)
|
|
305
|
+
# Remove from schema registry
|
|
306
|
+
self._schema_registry[:] = [
|
|
307
|
+
s for s in self._schema_registry
|
|
308
|
+
if s.get("function", {}).get("name") not in self._plugin_tool_names
|
|
309
|
+
]
|
|
310
|
+
# Re-register
|
|
311
|
+
n, _ = register_plugin_tools(
|
|
312
|
+
self._tool_registry, self._schema_registry,
|
|
313
|
+
str(self._plugin_path.parent), overwrite=True
|
|
314
|
+
)
|
|
315
|
+
self._plugin_tool_names = [
|
|
316
|
+
t["name"] for t in load_plugin(self._plugin_path)
|
|
317
|
+
]
|
|
318
|
+
logger.info("PluginWatcher: hot-reloaded %d tools from %s", n, self._plugin_path.name)
|
|
319
|
+
|
|
320
|
+
async def stop(self):
|
|
321
|
+
if self._task:
|
|
322
|
+
self._task.cancel()
|
|
323
|
+
try:
|
|
324
|
+
import asyncio
|
|
325
|
+
await asyncio.wait_for(self._task, timeout=1.0)
|
|
326
|
+
except Exception:
|
|
327
|
+
pass
|
|
328
|
+
self._task = None
|