aria-code 0.52.0__py3-none-any.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_code/__init__.py +42 -0
- aria_code/_version.py +20 -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 +34 -0
- aria_code/agents/base.py +318 -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 +303 -0
- aria_code/agents/financial/fundamental.py +191 -0
- aria_code/agents/financial/macro.py +99 -0
- aria_code/agents/financial/news.py +207 -0
- aria_code/agents/financial/risk.py +165 -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 +258 -0
- aria_code/agents/orchestrator.py +44 -0
- aria_code/agents/portfolio_agent.py +363 -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 +158 -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 +492 -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/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 +15 -0
- aria_code/apps/channels/__init__.py +17 -0
- aria_code/apps/channels/intake.py +92 -0
- aria_code/apps/channels/registry.py +95 -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/bootstrap.py +145 -0
- aria_code/apps/cli/broker_render.py +206 -0
- aria_code/apps/cli/codegen_paths.py +29 -0
- aria_code/apps/cli/commands/__init__.py +16 -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 +369 -0
- aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
- aria_code/apps/cli/commands/auth_cmds.py +239 -0
- aria_code/apps/cli/commands/backtest_cmds.py +2543 -0
- aria_code/apps/cli/commands/broker_cmds.py +1234 -0
- aria_code/apps/cli/commands/business_workflow_cmds.py +319 -0
- aria_code/apps/cli/commands/canvas_cmds.py +77 -0
- aria_code/apps/cli/commands/catalog.py +87 -0
- aria_code/apps/cli/commands/core_cmds.py +2520 -0
- aria_code/apps/cli/commands/data_cmds.py +457 -0
- aria_code/apps/cli/commands/diagnostic_cmds.py +230 -0
- aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -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 +434 -0
- aria_code/apps/cli/commands/market_cmds.py +1381 -0
- aria_code/apps/cli/commands/market_context.py +425 -0
- aria_code/apps/cli/commands/market_render.py +7 -0
- aria_code/apps/cli/commands/model_cmds.py +2153 -0
- aria_code/apps/cli/commands/ops_cmds.py +721 -0
- aria_code/apps/cli/commands/orchestrator_cmds.py +179 -0
- aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
- aria_code/apps/cli/commands/portfolio_cmds.py +1278 -0
- aria_code/apps/cli/commands/report.py +437 -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 +669 -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 +79 -0
- aria_code/apps/cli/commands/workflow_cmds.py +480 -0
- aria_code/apps/cli/commands/workspace_cmds.py +1494 -0
- aria_code/apps/cli/config_paths.py +73 -0
- aria_code/apps/cli/config_store.py +78 -0
- aria_code/apps/cli/constants.py +88 -0
- aria_code/apps/cli/context.py +34 -0
- aria_code/apps/cli/deterministic.py +191 -0
- aria_code/apps/cli/direct.py +48 -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 +196 -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 +1309 -0
- aria_code/apps/cli/handlers/market_handlers.py +2513 -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/helpers.py +302 -0
- aria_code/apps/cli/hooks.py +180 -0
- aria_code/apps/cli/i18n.py +297 -0
- aria_code/apps/cli/intent.py +136 -0
- aria_code/apps/cli/intent_router.py +276 -0
- aria_code/apps/cli/intent_signals.py +344 -0
- aria_code/apps/cli/lifecycle_hooks.py +48 -0
- aria_code/apps/cli/local_tool_schemas.py +536 -0
- aria_code/apps/cli/main.py +29 -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/model_catalog.py +620 -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 +59 -0
- aria_code/apps/cli/prompts/__init__.py +0 -0
- aria_code/apps/cli/prompts/coding.py +53 -0
- aria_code/apps/cli/prompts/select.py +142 -0
- aria_code/apps/cli/prompts/system_prompts.py +552 -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 +521 -0
- aria_code/apps/cli/providers/chat_routing.py +128 -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 +1594 -0
- aria_code/apps/cli/providers/llm/response_cache.py +60 -0
- aria_code/apps/cli/providers/llm/sse_stream.py +257 -0
- aria_code/apps/cli/providers/runtime_bridge.py +353 -0
- aria_code/apps/cli/providers/vertexai_stream.py +316 -0
- aria_code/apps/cli/runtime_consumer.py +657 -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_store.py +112 -0
- aria_code/apps/cli/skills_catalog.py +273 -0
- aria_code/apps/cli/todo_tracker.py +190 -0
- aria_code/apps/cli/tool_executor.py +823 -0
- aria_code/apps/cli/tool_registry.py +34 -0
- aria_code/apps/cli/tool_scope.py +106 -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 +180 -0
- aria_code/apps/cli/tools/market_tools.py +620 -0
- aria_code/apps/cli/tools/notebook_tools.py +111 -0
- aria_code/apps/cli/tools/system_tools.py +726 -0
- aria_code/apps/cli/tools/write_tools.py +845 -0
- aria_code/apps/cli/tradingview_bridge.py +529 -0
- aria_code/apps/cli/turn_planning.py +137 -0
- aria_code/apps/cli/update_check.py +153 -0
- aria_code/apps/cli/utils/__init__.py +0 -0
- aria_code/apps/cli/utils/market_detect.py +1597 -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 +6743 -0
- aria_code/aria_daemon.py +1398 -0
- aria_code/aria_feishu_bot.py +1423 -0
- aria_code/aria_mcp_server.py +7 -0
- aria_code/aria_relay_client.py +4 -0
- aria_code/aria_relay_server.py +490 -0
- aria_code/aria_telegram_bot.py +202 -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 +182 -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 +1976 -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 +181 -0
- aria_code/command_safety.py +19 -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/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/demo_player.py +207 -0
- aria_code/doctor.py +813 -0
- aria_code/domain/__init__.py +0 -0
- aria_code/domain/backtest_engine.py +354 -0
- aria_code/domain/backtest_report.py +472 -0
- aria_code/domain/finance_formulas.py +389 -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/harness.py +598 -0
- aria_code/evals/runner.py +238 -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 +386 -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 +639 -0
- aria_code/memory_manager.py +246 -0
- aria_code/model_capability.py +486 -0
- aria_code/notification_tools.py +4 -0
- aria_code/openai_image_client.py +4 -0
- aria_code/packages/__init__.py +23 -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 +52 -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 +201 -0
- aria_code/packages/aria_mcp/circuit.py +82 -0
- aria_code/packages/aria_mcp/config.py +111 -0
- aria_code/packages/aria_mcp/installer.py +95 -0
- aria_code/packages/aria_mcp/server.py +1550 -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 +396 -0
- aria_code/packages/aria_sdk/providers.py +70 -0
- aria_code/packages/aria_sdk/streaming.py +79 -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 +268 -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 +57 -0
- aria_code/packages/aria_services/research_quality.py +186 -0
- aria_code/packages/aria_services/settings.py +157 -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 +8 -0
- aria_code/packages/aria_tools/financial/_paths.py +130 -0
- aria_code/packages/aria_tools/financial/compliance.py +31 -0
- aria_code/packages/aria_tools/financial/factors.py +33 -0
- aria_code/packages/aria_tools/financial/risk_tools.py +33 -0
- aria_code/packages/aria_tools/financial/strategy.py +31 -0
- aria_code/packages/aria_tools/registry.py +128 -0
- aria_code/packages/quant_engine/__init__.py +34 -0
- aria_code/packages/quant_engine/_namespace.py +62 -0
- aria_code/packages/quant_engine/backtest/__init__.py +14 -0
- aria_code/packages/quant_engine/backtest/core.py +53 -0
- aria_code/packages/quant_engine/backtest/engine.py +96 -0
- aria_code/packages/quant_engine/portfolio/__init__.py +13 -0
- aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
- aria_code/packages/quant_engine/sports/__init__.py +80 -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/ml_model.py +377 -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 +35 -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/logistics/__init__.py +169 -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/llm/__init__.py +19 -0
- aria_code/providers/llm/anthropic.py +184 -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 +129 -0
- aria_code/providers/llm/openai_compat.py +313 -0
- aria_code/providers/llm/registry.py +444 -0
- aria_code/providers/local_image_provider.py +202 -0
- aria_code/providers/local_llm_provider.py +589 -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/runtime/__init__.py +169 -0
- aria_code/runtime/acceptance.py +481 -0
- aria_code/runtime/agent_loop.py +1520 -0
- aria_code/runtime/approval.py +57 -0
- aria_code/runtime/budget.py +232 -0
- aria_code/runtime/checkpoints.py +432 -0
- aria_code/runtime/crash_report.py +174 -0
- aria_code/runtime/events.py +113 -0
- aria_code/runtime/gateway.py +150 -0
- aria_code/runtime/lsp.py +484 -0
- aria_code/runtime/orchestrator.py +55 -0
- aria_code/runtime/repo_map.py +700 -0
- aria_code/runtime/run_state.py +127 -0
- aria_code/runtime/run_store.py +450 -0
- aria_code/runtime/self_healing.py +422 -0
- aria_code/runtime/subagent.py +547 -0
- aria_code/runtime/task_ledger.py +86 -0
- aria_code/runtime/task_orchestrator.py +90 -0
- aria_code/runtime/tool_executor.py +217 -0
- aria_code/runtime/tool_policy.py +107 -0
- aria_code/runtime/worktrees.py +215 -0
- aria_code/runway_video_client.py +4 -0
- aria_code/safety/__init__.py +23 -0
- aria_code/safety/permissions.py +306 -0
- aria_code/safety/service.py +102 -0
- aria_code/setup_wizard.py +673 -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 +504 -0
- aria_code/tools/data_analysis_tools.py +809 -0
- aria_code/tools/enterprise_finance_tools.py +156 -0
- aria_code/tools/extended_tools.py +240 -0
- aria_code/tools/file_analysis_tools.py +885 -0
- aria_code/tools/image_gen_tools.py +114 -0
- aria_code/tools/local_finance_tools.py +3417 -0
- aria_code/tools/logistics_tools.py +135 -0
- aria_code/tools/macro_tools.py +369 -0
- aria_code/tools/notification_tools.py +249 -0
- aria_code/tools/project_tools.py +525 -0
- aria_code/tools/realty_data_tools.py +659 -0
- aria_code/tools/spreadsheet_tools.py +388 -0
- aria_code/tools/stripe_tools.py +115 -0
- aria_code/ui/__init__.py +105 -0
- aria_code/ui/banner.py +508 -0
- aria_code/ui/completer.py +501 -0
- aria_code/ui/console.py +281 -0
- aria_code/ui/image_render.py +243 -0
- aria_code/ui/input_box.py +488 -0
- aria_code/ui/picker.py +201 -0
- aria_code/ui/render/__init__.py +11 -0
- aria_code/ui/render/finance.py +1705 -0
- aria_code/ui/render/market.py +225 -0
- aria_code/ui/render/output.py +775 -0
- aria_code/ui/render/responsive.py +75 -0
- aria_code/ui/render/team.py +354 -0
- aria_code/ui/robot.py +235 -0
- aria_code/ui/startup_dashboard.py +109 -0
- aria_code/utils/vscode_uri.py +37 -0
- aria_code/video_analysis.py +147 -0
- aria_code/video_editor.py +271 -0
- aria_code/workspace/__init__.py +6 -0
- aria_code/workspace/files.py +193 -0
- aria_code/workspace/verify.py +113 -0
- aria_code/workspace_changes.py +199 -0
- aria_code/workspace_context.py +233 -0
- aria_code/workspace_service.py +196 -0
- aria_code/workspace_tools.py +150 -0
- aria_code-0.52.0.dist-info/METADATA +237 -0
- aria_code-0.52.0.dist-info/RECORD +478 -0
- aria_code-0.52.0.dist-info/WHEEL +5 -0
- aria_code-0.52.0.dist-info/entry_points.txt +3 -0
- aria_code-0.52.0.dist-info/licenses/LICENSE +201 -0
- aria_code-0.52.0.dist-info/licenses/NOTICE +49 -0
- aria_code-0.52.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"""Payments — Stripe objects.
|
|
2
|
+
|
|
3
|
+
The cleanest case the pack contract has. Stripe object ids carry a typed
|
|
4
|
+
prefix (``ch_`` charge, ``pi_`` payment intent, ``cus_`` customer, ``sub_``
|
|
5
|
+
subscription…) followed by a long opaque suffix, so recognising one is a
|
|
6
|
+
resolution rather than a guess: nothing else in an English or Chinese sentence
|
|
7
|
+
looks like ``pi_3PqR8s2eZvKYlo2C0aBcDeFg``.
|
|
8
|
+
|
|
9
|
+
That precision is what lets this pack stay registered permanently at no cost.
|
|
10
|
+
It cannot fire on domain vocabulary — the words "payment", "refund" and
|
|
11
|
+
"订阅" never activate it — so a payments deployment adds nothing to the latency
|
|
12
|
+
or the failure surface of a session about anything else.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import re
|
|
18
|
+
from typing import Sequence
|
|
19
|
+
|
|
20
|
+
from aria_code.packs.base import BaseDomainPack, EntityMatch, PackActivation
|
|
21
|
+
|
|
22
|
+
PACK_NAME = "payments"
|
|
23
|
+
|
|
24
|
+
PAYMENT_TOOLS = (
|
|
25
|
+
"analyze_stripe_data",
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
_RESOLVED = 0.95
|
|
29
|
+
|
|
30
|
+
# prefix → what the object is. Kept explicit rather than matching a generic
|
|
31
|
+
# `\w+_[A-Za-z0-9]{14,}` because an unknown prefix is far more likely to be
|
|
32
|
+
# someone's own snake_case identifier than a Stripe object.
|
|
33
|
+
_OBJECT_PREFIXES: dict[str, str] = {
|
|
34
|
+
"ch": "charge",
|
|
35
|
+
"pi": "payment_intent",
|
|
36
|
+
"cus": "customer",
|
|
37
|
+
"sub": "subscription",
|
|
38
|
+
"in": "invoice",
|
|
39
|
+
"il": "invoice_item",
|
|
40
|
+
"price": "price",
|
|
41
|
+
"prod": "product",
|
|
42
|
+
"acct": "account",
|
|
43
|
+
"evt": "event",
|
|
44
|
+
"re": "refund",
|
|
45
|
+
"txn": "balance_transaction",
|
|
46
|
+
"po": "payout",
|
|
47
|
+
"seti": "setup_intent",
|
|
48
|
+
"pm": "payment_method",
|
|
49
|
+
"cs": "checkout_session",
|
|
50
|
+
"dp": "dispute",
|
|
51
|
+
"sk": "secret_key",
|
|
52
|
+
"rk": "restricted_key",
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# Stripe ids are prefix + '_' + at least 14 base62 characters, optionally with
|
|
56
|
+
# a `test_` segment in live-vs-test form (`sk_test_…`, `ch_test_…`).
|
|
57
|
+
_OBJECT_ID = re.compile(
|
|
58
|
+
r"\b(" + "|".join(sorted(_OBJECT_PREFIXES, key=len, reverse=True)) + r")_"
|
|
59
|
+
r"(?:test_|live_)?([A-Za-z0-9]{14,})\b"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class PaymentsPack(BaseDomainPack):
|
|
64
|
+
"""Recognises Stripe object ids and owns the payments workflows."""
|
|
65
|
+
|
|
66
|
+
name = PACK_NAME
|
|
67
|
+
|
|
68
|
+
def resolve_entities(self, message: str) -> Sequence[EntityMatch]:
|
|
69
|
+
text = message or ""
|
|
70
|
+
if "_" not in text:
|
|
71
|
+
# Every id this pack knows contains an underscore, so this one
|
|
72
|
+
# check skips the regex entirely for the overwhelming majority of
|
|
73
|
+
# messages — the resolver runs on every message, for every pack.
|
|
74
|
+
return ()
|
|
75
|
+
|
|
76
|
+
seen: set[str] = set()
|
|
77
|
+
entities: list[EntityMatch] = []
|
|
78
|
+
for match in _OBJECT_ID.finditer(text):
|
|
79
|
+
value = match.group(0)
|
|
80
|
+
if value in seen:
|
|
81
|
+
continue
|
|
82
|
+
seen.add(value)
|
|
83
|
+
entities.append(EntityMatch(
|
|
84
|
+
pack=PACK_NAME,
|
|
85
|
+
kind=_OBJECT_PREFIXES[match.group(1)],
|
|
86
|
+
value=value,
|
|
87
|
+
surface=value,
|
|
88
|
+
position=match.start(),
|
|
89
|
+
confidence=_RESOLVED,
|
|
90
|
+
))
|
|
91
|
+
return tuple(entities)
|
|
92
|
+
|
|
93
|
+
def tool_names(self) -> Sequence[str]:
|
|
94
|
+
return PAYMENT_TOOLS
|
|
95
|
+
|
|
96
|
+
def prompt_fragment(self, activation: PackActivation) -> str:
|
|
97
|
+
kinds = ", ".join(sorted({e.kind for e in activation.entities}))
|
|
98
|
+
has_key = any(e.kind.endswith("_key") for e in activation.entities)
|
|
99
|
+
text = (
|
|
100
|
+
f"Stripe 对象已识别({kinds})。\n"
|
|
101
|
+
"用工具取回的账务数据回答,不要凭记忆推断金额、状态或结算周期;"
|
|
102
|
+
"涉及退款、扣款、订阅变更等写操作时,先说明将要发生什么并等待确认。"
|
|
103
|
+
)
|
|
104
|
+
if has_key:
|
|
105
|
+
# The one case where the right move is to stop rather than help.
|
|
106
|
+
text += (
|
|
107
|
+
"\n⚠ 消息中疑似包含 Stripe 密钥。不要复述它、不要写入文件、"
|
|
108
|
+
"不要用它发起请求;提醒用户立即在 Stripe 后台轮换该密钥。"
|
|
109
|
+
)
|
|
110
|
+
return text
|
|
111
|
+
|
|
112
|
+
def acceptance_commands(self, activation: PackActivation) -> Sequence[str]:
|
|
113
|
+
# Looked up through the module rather than a name bound at import, so
|
|
114
|
+
# what this workspace declares is read when the turn runs — a .ariarc
|
|
115
|
+
# edited mid-session takes effect on the next message, not the next
|
|
116
|
+
# process.
|
|
117
|
+
from aria_code.packs import rules
|
|
118
|
+
|
|
119
|
+
return rules.acceptance_commands_for(PACK_NAME)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
PAYMENTS_PACK = PaymentsPack()
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def register() -> PaymentsPack:
|
|
126
|
+
"""Register the payments pack. Idempotent."""
|
|
127
|
+
from aria_code.packs.registry import register_pack
|
|
128
|
+
|
|
129
|
+
register_pack(PAYMENTS_PACK)
|
|
130
|
+
return PAYMENTS_PACK
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
__all__ = [
|
|
134
|
+
"PACK_NAME",
|
|
135
|
+
"PAYMENTS_PACK",
|
|
136
|
+
"PAYMENT_TOOLS",
|
|
137
|
+
"PaymentsPack",
|
|
138
|
+
"register",
|
|
139
|
+
]
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"""Real estate — a city's housing market.
|
|
2
|
+
|
|
3
|
+
This pack is the contract's hard case, and worth reading as one. Its domain
|
|
4
|
+
has no ``AAPL`` and no ``ch_3Pq…``: the thing a housing question is *about* is
|
|
5
|
+
a city, and a city name on its own is a perfectly ordinary word. "北京" appears
|
|
6
|
+
in travel plans, in address parsing, in a comment about a datacenter region.
|
|
7
|
+
|
|
8
|
+
So the entity this pack resolves is not the city. It is **this city's housing
|
|
9
|
+
market**, which takes two parts to name: a city from a real table, and a
|
|
10
|
+
housing term in the same message. A city alone resolves at a confidence below
|
|
11
|
+
the activation threshold — reported, so the UI can ask, but never enough to
|
|
12
|
+
answer a code question with a house-price index on its own initiative.
|
|
13
|
+
|
|
14
|
+
That is the same rule finance applies to a bare uppercase run, arrived at from
|
|
15
|
+
the opposite direction: finance has to *demote* a shape that looks like an
|
|
16
|
+
identifier, and realty has to *combine* two things neither of which is one.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
from typing import Sequence
|
|
22
|
+
|
|
23
|
+
from aria_code.packs.base import BaseDomainPack, EntityMatch, PackActivation
|
|
24
|
+
|
|
25
|
+
PACK_NAME = "realty"
|
|
26
|
+
|
|
27
|
+
# Empty on purpose. get_house_price_index/get_re_investment exist as functions
|
|
28
|
+
# in realty_data_tools but have no register_* wrapper, so they are not in
|
|
29
|
+
# LOCAL_TOOLS. Naming them here told the model about a capability it does not
|
|
30
|
+
# have, which costs a wasted round and a confusing "unknown tool" error.
|
|
31
|
+
# The pack still contributes its handler and its prompt guidance.
|
|
32
|
+
REALTY_TOOLS: tuple[str, ...] = ()
|
|
33
|
+
|
|
34
|
+
_RESOLVED = 0.95
|
|
35
|
+
_CITY_ONLY = 0.3
|
|
36
|
+
|
|
37
|
+
# Terms that name a housing market by themselves, with no city attached.
|
|
38
|
+
# "全国房价走势" is a real question about a real market, and refusing it would
|
|
39
|
+
# lose behaviour the ungated chain used to provide.
|
|
40
|
+
#
|
|
41
|
+
# The line drawn here is narrower than the handler's keyword list on purpose.
|
|
42
|
+
# "房价" and "楼市" name a market; "房产", "地产" and "物业" name a *topic*, and
|
|
43
|
+
# they appear in the source of any property-management codebase — which is
|
|
44
|
+
# exactly the kind of message that must not come back as a price index.
|
|
45
|
+
_NATIONAL_MARKET_TERMS = (
|
|
46
|
+
"房价", "楼市", "楼价", "二手房", "新房",
|
|
47
|
+
"house price", "home price", "housing market", "property price",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _tables() -> tuple[tuple[str, ...], tuple[str, ...], tuple[str, ...]]:
|
|
52
|
+
"""City and keyword tables, borrowed rather than duplicated.
|
|
53
|
+
|
|
54
|
+
They live in ``market_detect`` because the legacy chain used them; a copy
|
|
55
|
+
here would drift, and the failure that drift produces (a city Aria stopped
|
|
56
|
+
recognising after someone edited one list) is silent.
|
|
57
|
+
"""
|
|
58
|
+
try:
|
|
59
|
+
from aria_code.apps.cli.utils.market_detect import (
|
|
60
|
+
_CN_CITIES,
|
|
61
|
+
_INTL_CITIES,
|
|
62
|
+
_REALTY_QUERY_KEYWORDS,
|
|
63
|
+
)
|
|
64
|
+
except Exception:
|
|
65
|
+
return (), (), ()
|
|
66
|
+
return tuple(_CN_CITIES), tuple(_INTL_CITIES), tuple(_REALTY_QUERY_KEYWORDS)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class RealtyPack(BaseDomainPack):
|
|
70
|
+
"""Recognises a named city's housing market."""
|
|
71
|
+
|
|
72
|
+
name = PACK_NAME
|
|
73
|
+
|
|
74
|
+
def resolve_entities(self, message: str) -> Sequence[EntityMatch]:
|
|
75
|
+
text = message or ""
|
|
76
|
+
if not text.strip():
|
|
77
|
+
return ()
|
|
78
|
+
|
|
79
|
+
cn_cities, intl_cities, keywords = _tables()
|
|
80
|
+
if not cn_cities and not intl_cities:
|
|
81
|
+
return ()
|
|
82
|
+
|
|
83
|
+
lowered = text.lower()
|
|
84
|
+
has_housing_term = any(keyword in lowered for keyword in keywords)
|
|
85
|
+
|
|
86
|
+
found: list[tuple[str, int]] = []
|
|
87
|
+
for city in cn_cities:
|
|
88
|
+
position = text.find(city)
|
|
89
|
+
if position >= 0:
|
|
90
|
+
found.append((city, position))
|
|
91
|
+
for city in intl_cities:
|
|
92
|
+
position = lowered.find(city)
|
|
93
|
+
if position >= 0:
|
|
94
|
+
found.append((city, position))
|
|
95
|
+
|
|
96
|
+
if not found:
|
|
97
|
+
# No city named, but the message may still name the national
|
|
98
|
+
# market outright.
|
|
99
|
+
for term in _NATIONAL_MARKET_TERMS:
|
|
100
|
+
position = lowered.find(term)
|
|
101
|
+
if position >= 0:
|
|
102
|
+
return (EntityMatch(
|
|
103
|
+
pack=PACK_NAME, kind="housing_market", value="全国",
|
|
104
|
+
surface=term, position=position, confidence=_RESOLVED,
|
|
105
|
+
),)
|
|
106
|
+
return ()
|
|
107
|
+
|
|
108
|
+
# Earliest mention first, and cap it: a message listing fifteen cities
|
|
109
|
+
# is a table, not a question about a housing market.
|
|
110
|
+
found.sort(key=lambda item: item[1])
|
|
111
|
+
confidence = _RESOLVED if has_housing_term else _CITY_ONLY
|
|
112
|
+
|
|
113
|
+
seen: set[str] = set()
|
|
114
|
+
entities: list[EntityMatch] = []
|
|
115
|
+
for city, position in found[:6]:
|
|
116
|
+
if city in seen:
|
|
117
|
+
continue
|
|
118
|
+
seen.add(city)
|
|
119
|
+
entities.append(EntityMatch(
|
|
120
|
+
pack=PACK_NAME, kind="housing_market", value=city,
|
|
121
|
+
surface=city, position=position, confidence=confidence,
|
|
122
|
+
))
|
|
123
|
+
return tuple(entities)
|
|
124
|
+
|
|
125
|
+
def handlers(self) -> Sequence[object]:
|
|
126
|
+
"""The realty handler, now reachable only when a market is named."""
|
|
127
|
+
try:
|
|
128
|
+
from aria_code.apps.cli.handlers.realty_handlers import handle_realty_query
|
|
129
|
+
from aria_code.apps.cli.utils.market_detect import (
|
|
130
|
+
_CN_CITIES,
|
|
131
|
+
_INTL_CITIES,
|
|
132
|
+
_is_realty_query,
|
|
133
|
+
)
|
|
134
|
+
except Exception:
|
|
135
|
+
return ()
|
|
136
|
+
|
|
137
|
+
def _handle(message: str) -> dict:
|
|
138
|
+
return handle_realty_query(
|
|
139
|
+
message,
|
|
140
|
+
is_realty_query=_is_realty_query,
|
|
141
|
+
cn_cities=_CN_CITIES,
|
|
142
|
+
intl_cities=_INTL_CITIES,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
return (_handle,)
|
|
146
|
+
|
|
147
|
+
def tool_names(self) -> Sequence[str]:
|
|
148
|
+
return REALTY_TOOLS
|
|
149
|
+
|
|
150
|
+
def prompt_fragment(self, activation: PackActivation) -> str:
|
|
151
|
+
cities = ", ".join(sorted({e.value for e in activation.entities}))
|
|
152
|
+
# No tool instruction here: this pack exposes none. The price index is
|
|
153
|
+
# fetched by the deterministic handler above, so if the model is the one
|
|
154
|
+
# answering, it has no data source and must say so rather than produce
|
|
155
|
+
# a plausible number.
|
|
156
|
+
return (
|
|
157
|
+
f"房地产市场已识别:{cities}。\n"
|
|
158
|
+
"你没有房价数据工具。除非上文已给出取回的数据,否则不要给出具体房价、"
|
|
159
|
+
"涨跌幅或指数值——说明数据不可得,并建议用 /realty 命令获取;"
|
|
160
|
+
"标注统计口径(新房/二手房、环比/同比)与数据时间;输出不构成投资建议。"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
def acceptance_commands(self, activation: PackActivation) -> Sequence[str]:
|
|
164
|
+
# Looked up through the module rather than a name bound at import, so
|
|
165
|
+
# what this workspace declares is read when the turn runs — a .ariarc
|
|
166
|
+
# edited mid-session takes effect on the next message, not the next
|
|
167
|
+
# process.
|
|
168
|
+
from aria_code.packs import rules
|
|
169
|
+
|
|
170
|
+
return rules.acceptance_commands_for(PACK_NAME)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
REALTY_PACK = RealtyPack()
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def register() -> RealtyPack:
|
|
177
|
+
"""Register the realty pack. Idempotent."""
|
|
178
|
+
from aria_code.packs.registry import register_pack
|
|
179
|
+
|
|
180
|
+
register_pack(REALTY_PACK)
|
|
181
|
+
return REALTY_PACK
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
__all__ = [
|
|
185
|
+
"PACK_NAME",
|
|
186
|
+
"REALTY_PACK",
|
|
187
|
+
"REALTY_TOOLS",
|
|
188
|
+
"RealtyPack",
|
|
189
|
+
"register",
|
|
190
|
+
]
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"""Domain pack registration and entity-gated activation.
|
|
2
|
+
|
|
3
|
+
Activation is the whole point of this module. A pack is switched on for a
|
|
4
|
+
message only when it resolves a concrete entity *from that message*, at or
|
|
5
|
+
above a confidence threshold. Three consequences follow, each of which fixes a
|
|
6
|
+
failure this codebase actually shipped:
|
|
7
|
+
|
|
8
|
+
- **Domain vocabulary cannot activate a pack.** "根据以上分析和建议开始完善"
|
|
9
|
+
contains 分析 but names nothing; no pack claims it, so no market handler,
|
|
10
|
+
no quote, no ticker.
|
|
11
|
+
- **Conversation history cannot activate a pack.** Only the user's current
|
|
12
|
+
message is offered to resolvers. An assistant reply that mentioned
|
|
13
|
+
"Cassandra/MongoDB" can no longer donate the ticker MDB to the next turn.
|
|
14
|
+
- **An inactive pack costs nothing.** It contributes no handlers, no tools
|
|
15
|
+
and no prompt text, so adding a clinical or logistics pack does not slow
|
|
16
|
+
down or perturb a finance user, and vice versa.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import logging
|
|
22
|
+
from typing import Iterable, Sequence
|
|
23
|
+
|
|
24
|
+
from aria_code.packs.base import (
|
|
25
|
+
DEFAULT_ACTIVATION_THRESHOLD,
|
|
26
|
+
DomainPack,
|
|
27
|
+
EntityMatch,
|
|
28
|
+
PackActivation,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
logger = logging.getLogger(__name__)
|
|
32
|
+
|
|
33
|
+
_REGISTRY: dict[str, DomainPack] = {}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def register_pack(pack: DomainPack) -> None:
|
|
37
|
+
"""Register *pack* under its name, replacing any earlier registration."""
|
|
38
|
+
name = getattr(pack, "name", "")
|
|
39
|
+
if not name:
|
|
40
|
+
raise ValueError("a domain pack must declare a non-empty name")
|
|
41
|
+
if not hasattr(pack, "resolve_entities"):
|
|
42
|
+
raise TypeError(f"pack {name!r} does not implement resolve_entities()")
|
|
43
|
+
_REGISTRY[name] = pack
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def unregister_pack(name: str) -> None:
|
|
47
|
+
_REGISTRY.pop(name, None)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def registered_packs() -> tuple[DomainPack, ...]:
|
|
51
|
+
return tuple(_REGISTRY.values())
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def get_pack(name: str) -> DomainPack | None:
|
|
55
|
+
return _REGISTRY.get(name)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def clear_registry() -> None:
|
|
59
|
+
"""Drop every registration (tests)."""
|
|
60
|
+
_REGISTRY.clear()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _entities_from(pack: DomainPack, message: str) -> list[EntityMatch]:
|
|
64
|
+
"""Ask one pack what it recognises, never letting it break the request.
|
|
65
|
+
|
|
66
|
+
A resolver runs on every message; a pack that raises, or that returns
|
|
67
|
+
something malformed, must degrade to "recognises nothing" rather than take
|
|
68
|
+
the CLI down with it.
|
|
69
|
+
"""
|
|
70
|
+
try:
|
|
71
|
+
found = pack.resolve_entities(message) or ()
|
|
72
|
+
except Exception:
|
|
73
|
+
logger.debug("pack %r failed to resolve entities", getattr(pack, "name", "?"),
|
|
74
|
+
exc_info=True)
|
|
75
|
+
return []
|
|
76
|
+
out: list[EntityMatch] = []
|
|
77
|
+
for entity in found:
|
|
78
|
+
if isinstance(entity, EntityMatch):
|
|
79
|
+
out.append(entity)
|
|
80
|
+
return out
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def activate_packs(
|
|
84
|
+
message: str,
|
|
85
|
+
*,
|
|
86
|
+
packs: Iterable[DomainPack] | None = None,
|
|
87
|
+
threshold: float = DEFAULT_ACTIVATION_THRESHOLD,
|
|
88
|
+
) -> tuple[PackActivation, ...]:
|
|
89
|
+
"""Return the packs that claim *message*, most confident first.
|
|
90
|
+
|
|
91
|
+
Only the current user message is considered. Callers must not pass
|
|
92
|
+
conversation history here: inheriting an entity across turns is what
|
|
93
|
+
produced a stock quote in reply to "根据以上分析和建议开始完善".
|
|
94
|
+
"""
|
|
95
|
+
if not (message or "").strip():
|
|
96
|
+
return ()
|
|
97
|
+
|
|
98
|
+
candidates = tuple(packs) if packs is not None else registered_packs()
|
|
99
|
+
activations: list[PackActivation] = []
|
|
100
|
+
for pack in candidates:
|
|
101
|
+
entities = [
|
|
102
|
+
e for e in _entities_from(pack, message) if e.confidence >= threshold
|
|
103
|
+
]
|
|
104
|
+
if entities:
|
|
105
|
+
activations.append(
|
|
106
|
+
PackActivation(
|
|
107
|
+
pack=getattr(pack, "name", ""),
|
|
108
|
+
entities=tuple(entities),
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
activations.sort(key=lambda a: -a.confidence)
|
|
112
|
+
return tuple(activations)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def active_handlers(activations: Sequence[PackActivation]) -> tuple[object, ...]:
|
|
116
|
+
"""Deterministic handlers contributed by the active packs, in order."""
|
|
117
|
+
handlers: list[object] = []
|
|
118
|
+
for activation in activations:
|
|
119
|
+
pack = get_pack(activation.pack)
|
|
120
|
+
if pack is None:
|
|
121
|
+
continue
|
|
122
|
+
try:
|
|
123
|
+
handlers.extend(pack.handlers() or ())
|
|
124
|
+
except Exception:
|
|
125
|
+
logger.debug("pack %r failed to provide handlers", activation.pack,
|
|
126
|
+
exc_info=True)
|
|
127
|
+
return tuple(handlers)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def active_tool_names(activations: Sequence[PackActivation]) -> tuple[str, ...]:
|
|
131
|
+
"""Tool names to expose to the model for this message."""
|
|
132
|
+
names: list[str] = []
|
|
133
|
+
for activation in activations:
|
|
134
|
+
pack = get_pack(activation.pack)
|
|
135
|
+
if pack is None:
|
|
136
|
+
continue
|
|
137
|
+
try:
|
|
138
|
+
for name in pack.tool_names() or ():
|
|
139
|
+
if name and name not in names:
|
|
140
|
+
names.append(str(name))
|
|
141
|
+
except Exception:
|
|
142
|
+
logger.debug("pack %r failed to provide tool names", activation.pack,
|
|
143
|
+
exc_info=True)
|
|
144
|
+
return tuple(names)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def active_prompt_fragments(activations: Sequence[PackActivation]) -> tuple[str, ...]:
|
|
148
|
+
"""Domain guidance to append to the system prompt for this message."""
|
|
149
|
+
fragments: list[str] = []
|
|
150
|
+
for activation in activations:
|
|
151
|
+
pack = get_pack(activation.pack)
|
|
152
|
+
if pack is None:
|
|
153
|
+
continue
|
|
154
|
+
try:
|
|
155
|
+
fragment = pack.prompt_fragment(activation) or ""
|
|
156
|
+
except Exception:
|
|
157
|
+
logger.debug("pack %r failed to provide a prompt fragment", activation.pack,
|
|
158
|
+
exc_info=True)
|
|
159
|
+
continue
|
|
160
|
+
if fragment.strip():
|
|
161
|
+
fragments.append(fragment.strip())
|
|
162
|
+
return tuple(fragments)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def active_acceptance_commands(activations: Sequence[PackActivation]) -> tuple[str, ...]:
|
|
166
|
+
"""Verification commands contributed by the active packs, deduplicated.
|
|
167
|
+
|
|
168
|
+
Order follows activation confidence, so the pack that most clearly owns
|
|
169
|
+
the message gets its check run first — and the acceptance gate stops at
|
|
170
|
+
the first red, which makes that ordering the difference between a useful
|
|
171
|
+
failure and a confusing one.
|
|
172
|
+
"""
|
|
173
|
+
commands: list[str] = []
|
|
174
|
+
for activation in activations:
|
|
175
|
+
pack = get_pack(activation.pack)
|
|
176
|
+
if pack is None:
|
|
177
|
+
continue
|
|
178
|
+
try:
|
|
179
|
+
found = pack.acceptance_commands(activation) or ()
|
|
180
|
+
except Exception:
|
|
181
|
+
logger.debug("pack %r failed to provide acceptance commands", activation.pack,
|
|
182
|
+
exc_info=True)
|
|
183
|
+
continue
|
|
184
|
+
for command in found:
|
|
185
|
+
text = str(command or "").strip()
|
|
186
|
+
if text and text not in commands:
|
|
187
|
+
commands.append(text)
|
|
188
|
+
return tuple(commands)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
__all__ = [
|
|
192
|
+
"activate_packs",
|
|
193
|
+
"active_acceptance_commands",
|
|
194
|
+
"active_handlers",
|
|
195
|
+
"active_prompt_fragments",
|
|
196
|
+
"active_tool_names",
|
|
197
|
+
"clear_registry",
|
|
198
|
+
"get_pack",
|
|
199
|
+
"register_pack",
|
|
200
|
+
"registered_packs",
|
|
201
|
+
"unregister_pack",
|
|
202
|
+
]
|
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
|
+
]
|