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
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""Static research evidence inventory. Integrity and scope are not scientific truth."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import hashlib
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
from .task_verification import _read_file, _json_object, _json_float, _json_constant
|
|
9
|
+
|
|
10
|
+
KINDS = {'design', 'public_data', 'synthetic_data', 'analysis', 'code', 'simulation'}
|
|
11
|
+
SCOPES = {
|
|
12
|
+
'proposal': KINDS,
|
|
13
|
+
'analytical': {'analysis'},
|
|
14
|
+
'software': {'code'},
|
|
15
|
+
'simulation': {'simulation'},
|
|
16
|
+
'real_world': set(),
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _text(value, limit=4096):
|
|
21
|
+
if not isinstance(value, str) or not value.strip() or len(value) > limit:
|
|
22
|
+
raise ValueError('Missing or oversized research field')
|
|
23
|
+
return value
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def audit_bundle(workspace: str, manifest_path: str) -> dict:
|
|
27
|
+
"""Read bounded workspace artifacts without executing code or opening URLs.
|
|
28
|
+
|
|
29
|
+
All provenance kinds are declarations, not authenticated source attestations.
|
|
30
|
+
This no-hardware inventory never establishes a real-world result.
|
|
31
|
+
"""
|
|
32
|
+
manifest = json.loads(_read_file(workspace, manifest_path), object_pairs_hook=_json_object,
|
|
33
|
+
parse_float=_json_float, parse_constant=_json_constant)
|
|
34
|
+
if not isinstance(manifest, dict) or type(manifest.get('version')) is not int or manifest['version'] != 1:
|
|
35
|
+
raise ValueError('Unsupported research bundle version')
|
|
36
|
+
_text(manifest.get('question'))
|
|
37
|
+
_text(manifest.get('hypothesis'))
|
|
38
|
+
limitations = manifest.get('limitations')
|
|
39
|
+
if not isinstance(limitations, list) or not 1 <= len(limitations) <= 32:
|
|
40
|
+
raise ValueError('Explicit research limitations are required')
|
|
41
|
+
for item in limitations:
|
|
42
|
+
_text(item)
|
|
43
|
+
artifacts = manifest.get('artifacts')
|
|
44
|
+
claims = manifest.get('claims')
|
|
45
|
+
if not isinstance(artifacts, list) or not 1 <= len(artifacts) <= 16:
|
|
46
|
+
raise ValueError('Expected 1..16 artifacts')
|
|
47
|
+
if not isinstance(claims, list) or not 1 <= len(claims) <= 32:
|
|
48
|
+
raise ValueError('Expected 1..32 claims')
|
|
49
|
+
inventory = {}
|
|
50
|
+
reports = []
|
|
51
|
+
for item in artifacts:
|
|
52
|
+
if not isinstance(item, dict):
|
|
53
|
+
raise ValueError('Invalid artifact declaration')
|
|
54
|
+
ident = _text(item.get('id'), 128)
|
|
55
|
+
if ident in inventory or not isinstance(item.get('kind'), str) or item['kind'] not in KINDS:
|
|
56
|
+
raise ValueError('Duplicate artifact ID or unsupported evidence kind')
|
|
57
|
+
digest = item.get('sha256')
|
|
58
|
+
if not isinstance(digest, str) or len(digest) != 64 or any(c not in '0123456789abcdef' for c in digest):
|
|
59
|
+
raise ValueError('Artifact requires a SHA-256 digest')
|
|
60
|
+
data = _read_file(workspace, item.get('path'))
|
|
61
|
+
matched = hashlib.sha256(data).hexdigest() == digest
|
|
62
|
+
inventory[ident] = item['kind']
|
|
63
|
+
reports.append({'id': ident, 'kind': item['kind'], 'digest_matches': matched})
|
|
64
|
+
claim_ids = set()
|
|
65
|
+
dispositions = []
|
|
66
|
+
for claim in claims:
|
|
67
|
+
if not isinstance(claim, dict):
|
|
68
|
+
raise ValueError('Invalid claim declaration')
|
|
69
|
+
ident = _text(claim.get('id'), 128)
|
|
70
|
+
_text(claim.get('text'))
|
|
71
|
+
scope = claim.get('scope')
|
|
72
|
+
refs = claim.get('evidence')
|
|
73
|
+
if ident in claim_ids or not isinstance(scope, str) or scope not in SCOPES:
|
|
74
|
+
raise ValueError('Duplicate claim ID or unsupported claim scope')
|
|
75
|
+
claim_ids.add(ident)
|
|
76
|
+
if (not isinstance(refs, list) or not 1 <= len(refs) <= 16
|
|
77
|
+
or any(not isinstance(ref, str) or ref not in inventory for ref in refs)):
|
|
78
|
+
raise ValueError('Claim requires known evidence IDs')
|
|
79
|
+
compatible = any(inventory[ref] in SCOPES[scope] for ref in refs)
|
|
80
|
+
dispositions.append({'id': ident, 'scope': scope,
|
|
81
|
+
'scope_supported': compatible, 'scientifically_verified': None})
|
|
82
|
+
integrity = all(report['digest_matches'] for report in reports)
|
|
83
|
+
return {'version': 1, 'success': integrity and all(c['scope_supported'] for c in dispositions),
|
|
84
|
+
'integrity_verified': integrity, 'scientifically_verified': None,
|
|
85
|
+
'real_world_validation': 'not_established', 'semantic_review_required': True,
|
|
86
|
+
'coverage': 'artifact_hashes_and_declared_evidence_scope_only',
|
|
87
|
+
'artifacts': reports, 'claims': dispositions}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def main():
|
|
91
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
92
|
+
parser.add_argument('workspace')
|
|
93
|
+
parser.add_argument('manifest')
|
|
94
|
+
args = parser.parse_args()
|
|
95
|
+
try:
|
|
96
|
+
report = audit_bundle(args.workspace, args.manifest)
|
|
97
|
+
except (OSError, ValueError, TypeError, RecursionError):
|
|
98
|
+
report = {'success': False, 'error': 'Missing, unsafe or invalid research bundle',
|
|
99
|
+
'scientifically_verified': None, 'real_world_validation': 'not_established'}
|
|
100
|
+
print(json.dumps(report, indent=2))
|
|
101
|
+
return 0 if report['success'] else 1
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
if __name__ == '__main__':
|
|
105
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"""The review gate — an independent reviewer reads the change before "done".
|
|
2
|
+
|
|
3
|
+
Asking the model that wrote a change whether it is right gets the same
|
|
4
|
+
reasoning that produced it, mistakes included. The reviewer here is a separate
|
|
5
|
+
model call with a fresh context and no tools. It sees only what an outside
|
|
6
|
+
reviewer would: the user's goal, the change contract, the checks that ran and
|
|
7
|
+
their results, and the diff. Not the builder's reasoning, not the transcript.
|
|
8
|
+
|
|
9
|
+
It answers in JSON — a verdict and findings, each ``blocking`` or
|
|
10
|
+
``suggestion``. Blocking means the change is wrong or unsafe for the goal: a
|
|
11
|
+
bug, a broken edge case, a security hole, a contract breach. Style never is.
|
|
12
|
+
When it blocks and an attempt is left, the findings go back to the builder as
|
|
13
|
+
the next message, the same way red checks do; otherwise they go into the
|
|
14
|
+
delivery report's *Review* section.
|
|
15
|
+
|
|
16
|
+
A reviewer that fails — no answer, no JSON — never blocks: the report says the
|
|
17
|
+
review did not complete, and the turn ends on its other evidence.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import dataclasses
|
|
23
|
+
import inspect
|
|
24
|
+
import json
|
|
25
|
+
import re
|
|
26
|
+
from dataclasses import dataclass, field
|
|
27
|
+
from typing import Any, Awaitable, Callable, Optional, Sequence, Union
|
|
28
|
+
|
|
29
|
+
REVIEWER_SYSTEM = (
|
|
30
|
+
"You are an independent code reviewer. You did not write the change in front "
|
|
31
|
+
"of you, and you cannot run or edit anything: you read and judge. Do not call "
|
|
32
|
+
"tools. Answer with one JSON object and nothing else."
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
_INSTRUCTIONS = """\
|
|
36
|
+
Review the change below against the goal.
|
|
37
|
+
|
|
38
|
+
Report as BLOCKING only what makes the change wrong or unsafe for the goal:
|
|
39
|
+
incorrect behaviour, a missed requirement, a broken edge case the goal implies,
|
|
40
|
+
a security problem, data loss, or a breach of the change contract. Everything
|
|
41
|
+
else — naming, style, structure, extra tests you would like — is a SUGGESTION.
|
|
42
|
+
Do not report problems in code the change did not touch. If you are unsure
|
|
43
|
+
whether something is a bug, it is a suggestion.
|
|
44
|
+
|
|
45
|
+
Answer with exactly this JSON shape:
|
|
46
|
+
{"verdict": "pass" | "blocking",
|
|
47
|
+
"summary": "<one sentence>",
|
|
48
|
+
"findings": [{"severity": "blocking" | "suggestion",
|
|
49
|
+
"file": "<path>", "line": <number or null>,
|
|
50
|
+
"issue": "<what is wrong and why, one or two sentences>"}],
|
|
51
|
+
"behaviour": {"before": "<what the code did before, one sentence>",
|
|
52
|
+
"after": "<what it does now>",
|
|
53
|
+
"why": "<why the change was needed, from the goal>",
|
|
54
|
+
"impact": "<callers, modules or users affected>"}}
|
|
55
|
+
"verdict" is "blocking" exactly when a finding is blocking. "behaviour" describes
|
|
56
|
+
the change in terms of behaviour, not lines; leave a field empty if the diff does
|
|
57
|
+
not say."""
|
|
58
|
+
|
|
59
|
+
Reviewer = Callable[[str], Union[str, Awaitable[str]]]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass(frozen=True)
|
|
63
|
+
class ReviewFinding:
|
|
64
|
+
severity: str
|
|
65
|
+
issue: str
|
|
66
|
+
file: str = ""
|
|
67
|
+
line: Optional[int] = None
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def blocking(self) -> bool:
|
|
71
|
+
return self.severity == "blocking"
|
|
72
|
+
|
|
73
|
+
def where(self) -> str:
|
|
74
|
+
if not self.file:
|
|
75
|
+
return ""
|
|
76
|
+
return f"{self.file}:{self.line}" if self.line else self.file
|
|
77
|
+
|
|
78
|
+
def as_dict(self) -> dict:
|
|
79
|
+
return {"severity": self.severity, "file": self.file, "line": self.line, "issue": self.issue}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@dataclass(frozen=True)
|
|
83
|
+
class ReviewReport:
|
|
84
|
+
verdict: str # "pass" | "blocking" | "error"
|
|
85
|
+
summary: str = ""
|
|
86
|
+
findings: tuple = ()
|
|
87
|
+
attempt: int = 1
|
|
88
|
+
error: str = ""
|
|
89
|
+
behaviour: Optional[dict] = None
|
|
90
|
+
# The model that read the diff, when it is not the one that wrote it
|
|
91
|
+
# (`review_model`); empty for a same-model review.
|
|
92
|
+
reviewer: str = ""
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def blocking(self) -> tuple:
|
|
96
|
+
return tuple(f for f in self.findings if f.blocking)
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def suggestions(self) -> tuple:
|
|
100
|
+
return tuple(f for f in self.findings if not f.blocking)
|
|
101
|
+
|
|
102
|
+
def headline(self) -> str:
|
|
103
|
+
if self.verdict == "error":
|
|
104
|
+
return f"Review did not complete: {self.error}"
|
|
105
|
+
if self.blocking:
|
|
106
|
+
count = len(self.blocking)
|
|
107
|
+
return f"Review: {count} blocking finding{'s' if count != 1 else ''}"
|
|
108
|
+
tail = f" · {len(self.suggestions)} suggestion{'s' if len(self.suggestions) != 1 else ''}" \
|
|
109
|
+
if self.suggestions else ""
|
|
110
|
+
return f"Review: no blocking findings{tail}"
|
|
111
|
+
|
|
112
|
+
def lines(self, limit: int = 5) -> list[str]:
|
|
113
|
+
"""The Review section of the delivery report."""
|
|
114
|
+
if self.verdict == "error":
|
|
115
|
+
return [f"⚠ did not complete: {self.error}"]
|
|
116
|
+
by = f" (reviewed by {self.reviewer})" if self.reviewer else ""
|
|
117
|
+
out = [("✗ " if self.blocking else "✓ ") + self.headline().removeprefix("Review: ") + by]
|
|
118
|
+
for finding in (self.blocking + self.suggestions)[:limit]:
|
|
119
|
+
mark = "✗" if finding.blocking else "·"
|
|
120
|
+
where = f"{finding.where()} — " if finding.where() else ""
|
|
121
|
+
out.append(f" {mark} {where}{finding.issue}")
|
|
122
|
+
hidden = len(self.findings) - limit
|
|
123
|
+
if hidden > 0:
|
|
124
|
+
out.append(f" … +{hidden} more")
|
|
125
|
+
return out
|
|
126
|
+
|
|
127
|
+
def repair_directive(self) -> str:
|
|
128
|
+
items = "\n".join(
|
|
129
|
+
f"- {finding.where() + ': ' if finding.where() else ''}{finding.issue}" for finding in self.blocking
|
|
130
|
+
)
|
|
131
|
+
return (
|
|
132
|
+
"[Independent review]\n"
|
|
133
|
+
"A reviewer who saw only the goal, the contract, the checks and your diff "
|
|
134
|
+
f"found {len(self.blocking)} blocking problem{'s' if len(self.blocking) != 1 else ''}:\n"
|
|
135
|
+
f"{items}\n\n"
|
|
136
|
+
"Fix them, or — if a finding is wrong — say why in your final message. "
|
|
137
|
+
"The checks will run again after you change files."
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
def as_dict(self) -> dict:
|
|
141
|
+
data = {
|
|
142
|
+
"verdict": self.verdict,
|
|
143
|
+
"summary": self.summary,
|
|
144
|
+
"findings": [finding.as_dict() for finding in self.findings],
|
|
145
|
+
"attempt": self.attempt,
|
|
146
|
+
"error": self.error,
|
|
147
|
+
"headline": self.headline(),
|
|
148
|
+
"lines": self.lines(),
|
|
149
|
+
"behaviour": dict(self.behaviour) if self.behaviour else None,
|
|
150
|
+
}
|
|
151
|
+
# Only when another model reviewed: the Go runtime's report has no such field,
|
|
152
|
+
# and tests/test_native_go_review.py compares the two field by field.
|
|
153
|
+
if self.reviewer:
|
|
154
|
+
data["reviewer"] = self.reviewer
|
|
155
|
+
return data
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def parse_review(text: str, *, attempt: int = 1) -> ReviewReport:
|
|
159
|
+
"""The reviewer's answer as a report. Never raises; unparseable is an error."""
|
|
160
|
+
raw = str(text or "").strip()
|
|
161
|
+
if not raw:
|
|
162
|
+
return ReviewReport("error", attempt=attempt, error="the reviewer gave no answer")
|
|
163
|
+
fenced = re.search(r"```(?:json)?\s*(\{.*?\})\s*```", raw, re.DOTALL)
|
|
164
|
+
candidate = fenced.group(1) if fenced else raw[raw.find("{"): raw.rfind("}") + 1]
|
|
165
|
+
try:
|
|
166
|
+
data = json.loads(candidate)
|
|
167
|
+
except (ValueError, TypeError):
|
|
168
|
+
return ReviewReport("error", attempt=attempt, error="the reviewer's answer was not JSON")
|
|
169
|
+
if not isinstance(data, dict):
|
|
170
|
+
return ReviewReport("error", attempt=attempt, error="the reviewer's answer was not a JSON object")
|
|
171
|
+
findings = []
|
|
172
|
+
for item in data.get("findings") or []:
|
|
173
|
+
if not isinstance(item, dict) or not str(item.get("issue") or "").strip():
|
|
174
|
+
continue
|
|
175
|
+
severity = "blocking" if str(item.get("severity", "")).lower() == "blocking" else "suggestion"
|
|
176
|
+
line = item.get("line")
|
|
177
|
+
findings.append(ReviewFinding(
|
|
178
|
+
severity=severity,
|
|
179
|
+
issue=" ".join(str(item["issue"]).split()),
|
|
180
|
+
file=str(item.get("file") or "").strip(),
|
|
181
|
+
line=line if isinstance(line, int) and line > 0 else None,
|
|
182
|
+
))
|
|
183
|
+
# The verdict follows the findings: a "blocking" verdict with no blocking
|
|
184
|
+
# finding gives the builder nothing to fix, and a "pass" over one would
|
|
185
|
+
# hide it.
|
|
186
|
+
verdict = "blocking" if any(f.blocking for f in findings) else "pass"
|
|
187
|
+
raw_behaviour = data.get("behaviour") or data.get("behavior")
|
|
188
|
+
behaviour = None
|
|
189
|
+
if isinstance(raw_behaviour, dict):
|
|
190
|
+
behaviour = {key: " ".join(str(raw_behaviour.get(key) or "").split())[:240]
|
|
191
|
+
for key in ("before", "after", "why", "impact")}
|
|
192
|
+
behaviour = {k: v for k, v in behaviour.items() if v} or None
|
|
193
|
+
return ReviewReport(verdict, summary=str(data.get("summary") or "").strip(),
|
|
194
|
+
findings=tuple(findings), attempt=attempt, behaviour=behaviour)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def build_review_prompt(*, goal: str, diff: str, checks: Sequence[dict] = (), contract: str = "",
|
|
198
|
+
max_diff_chars: int = 24_000) -> str:
|
|
199
|
+
if len(diff) > max_diff_chars:
|
|
200
|
+
omitted = len(diff) - max_diff_chars
|
|
201
|
+
diff = diff[:max_diff_chars] + f"\n… [{omitted:,} characters of diff omitted]"
|
|
202
|
+
check_lines = "\n".join(
|
|
203
|
+
f"{'PASS' if c.get('passed') else 'FAIL'} {c.get('command', '')}" for c in checks
|
|
204
|
+
) or "(no checks ran)"
|
|
205
|
+
parts = [_INSTRUCTIONS, "", "GOAL", goal.strip() or "(not stated)"]
|
|
206
|
+
if contract:
|
|
207
|
+
parts += ["", "CONTRACT", contract.strip()]
|
|
208
|
+
parts += ["", "CHECKS", check_lines, "", "DIFF", diff.strip() or "(empty)"]
|
|
209
|
+
return "\n".join(parts)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
@dataclass
|
|
213
|
+
class ReviewGate:
|
|
214
|
+
"""Arms when a turn has changed files; reviews when the turn says it is done."""
|
|
215
|
+
|
|
216
|
+
reviewer: Reviewer
|
|
217
|
+
max_attempts: int = 1
|
|
218
|
+
max_diff_chars: int = 24_000
|
|
219
|
+
# Which model reviews, shown in the report; set when it differs from the builder.
|
|
220
|
+
reviewer_name: str = ""
|
|
221
|
+
reports: list = field(default_factory=list)
|
|
222
|
+
|
|
223
|
+
@property
|
|
224
|
+
def attempts(self) -> int:
|
|
225
|
+
return len(self.reports)
|
|
226
|
+
|
|
227
|
+
@property
|
|
228
|
+
def last(self) -> Optional[ReviewReport]:
|
|
229
|
+
return self.reports[-1] if self.reports else None
|
|
230
|
+
|
|
231
|
+
def should_run(self, *, changed: bool, reviewed_diff: str, diff: str) -> bool:
|
|
232
|
+
"""Review a change once per distinct diff, up to max_attempts + 1 times."""
|
|
233
|
+
if not changed or not diff.strip():
|
|
234
|
+
return False
|
|
235
|
+
if self.reports and diff == reviewed_diff:
|
|
236
|
+
return False
|
|
237
|
+
return self.attempts <= self.max_attempts
|
|
238
|
+
|
|
239
|
+
def can_repair(self) -> bool:
|
|
240
|
+
return self.attempts <= self.max_attempts
|
|
241
|
+
|
|
242
|
+
async def run(self, *, goal: str, diff: str, checks: Sequence[dict] = (), contract: str = "") -> ReviewReport:
|
|
243
|
+
prompt = build_review_prompt(goal=goal, diff=diff, checks=checks, contract=contract,
|
|
244
|
+
max_diff_chars=self.max_diff_chars)
|
|
245
|
+
try:
|
|
246
|
+
answer = self.reviewer(prompt)
|
|
247
|
+
if inspect.isawaitable(answer):
|
|
248
|
+
answer = await answer
|
|
249
|
+
report = parse_review(str(answer or ""), attempt=self.attempts + 1)
|
|
250
|
+
if self.reviewer_name:
|
|
251
|
+
report = dataclasses.replace(report, reviewer=self.reviewer_name)
|
|
252
|
+
except Exception as exc:
|
|
253
|
+
report = ReviewReport("error", attempt=self.attempts + 1, error=f"{type(exc).__name__}: {exc}",
|
|
254
|
+
reviewer=self.reviewer_name)
|
|
255
|
+
self.reports.append(report)
|
|
256
|
+
return report
|
|
257
|
+
|
|
258
|
+
def summary(self) -> Optional[dict]:
|
|
259
|
+
return self.last.as_dict() if self.last else None
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
__all__ = [
|
|
263
|
+
"REVIEWER_SYSTEM",
|
|
264
|
+
"ReviewFinding",
|
|
265
|
+
"ReviewGate",
|
|
266
|
+
"ReviewReport",
|
|
267
|
+
"build_review_prompt",
|
|
268
|
+
"parse_review",
|
|
269
|
+
]
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"""State machine for durable agent runs.
|
|
2
|
+
|
|
3
|
+
The model may suggest what to do next, but the runtime owns lifecycle state.
|
|
4
|
+
Keeping transitions explicit prevents a failed or interrupted turn from being
|
|
5
|
+
reported as successful merely because the generated text says it is done.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from enum import Enum
|
|
11
|
+
from typing import Dict, FrozenSet
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class RunStatus(str, Enum):
|
|
15
|
+
QUEUED = "queued"
|
|
16
|
+
PLANNING = "planning"
|
|
17
|
+
RUNNING = "running"
|
|
18
|
+
WAITING_APPROVAL = "waiting_approval"
|
|
19
|
+
WAITING_USER = "waiting_user"
|
|
20
|
+
VERIFYING = "verifying"
|
|
21
|
+
SUCCEEDED = "succeeded"
|
|
22
|
+
FAILED = "failed"
|
|
23
|
+
CANCELLED = "cancelled"
|
|
24
|
+
INTERRUPTED = "interrupted"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
TERMINAL_RUN_STATUSES: FrozenSet[RunStatus] = frozenset({
|
|
28
|
+
RunStatus.SUCCEEDED,
|
|
29
|
+
RunStatus.FAILED,
|
|
30
|
+
RunStatus.CANCELLED,
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
ACTIVE_RUN_STATUSES: FrozenSet[RunStatus] = frozenset({
|
|
34
|
+
RunStatus.QUEUED,
|
|
35
|
+
RunStatus.PLANNING,
|
|
36
|
+
RunStatus.RUNNING,
|
|
37
|
+
RunStatus.WAITING_APPROVAL,
|
|
38
|
+
RunStatus.WAITING_USER,
|
|
39
|
+
RunStatus.VERIFYING,
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
_TRANSITIONS: Dict[RunStatus, FrozenSet[RunStatus]] = {
|
|
43
|
+
RunStatus.QUEUED: frozenset({
|
|
44
|
+
RunStatus.PLANNING,
|
|
45
|
+
RunStatus.RUNNING,
|
|
46
|
+
RunStatus.FAILED,
|
|
47
|
+
RunStatus.CANCELLED,
|
|
48
|
+
RunStatus.INTERRUPTED,
|
|
49
|
+
}),
|
|
50
|
+
RunStatus.PLANNING: frozenset({
|
|
51
|
+
RunStatus.RUNNING,
|
|
52
|
+
RunStatus.WAITING_APPROVAL,
|
|
53
|
+
RunStatus.WAITING_USER,
|
|
54
|
+
RunStatus.FAILED,
|
|
55
|
+
RunStatus.CANCELLED,
|
|
56
|
+
RunStatus.INTERRUPTED,
|
|
57
|
+
}),
|
|
58
|
+
RunStatus.RUNNING: frozenset({
|
|
59
|
+
RunStatus.WAITING_APPROVAL,
|
|
60
|
+
RunStatus.WAITING_USER,
|
|
61
|
+
RunStatus.VERIFYING,
|
|
62
|
+
RunStatus.FAILED,
|
|
63
|
+
RunStatus.CANCELLED,
|
|
64
|
+
RunStatus.INTERRUPTED,
|
|
65
|
+
}),
|
|
66
|
+
RunStatus.WAITING_APPROVAL: frozenset({
|
|
67
|
+
RunStatus.RUNNING,
|
|
68
|
+
RunStatus.FAILED,
|
|
69
|
+
RunStatus.CANCELLED,
|
|
70
|
+
RunStatus.INTERRUPTED,
|
|
71
|
+
}),
|
|
72
|
+
RunStatus.WAITING_USER: frozenset({
|
|
73
|
+
RunStatus.RUNNING,
|
|
74
|
+
RunStatus.FAILED,
|
|
75
|
+
RunStatus.CANCELLED,
|
|
76
|
+
RunStatus.INTERRUPTED,
|
|
77
|
+
}),
|
|
78
|
+
RunStatus.VERIFYING: frozenset({
|
|
79
|
+
RunStatus.RUNNING,
|
|
80
|
+
RunStatus.SUCCEEDED,
|
|
81
|
+
RunStatus.FAILED,
|
|
82
|
+
RunStatus.CANCELLED,
|
|
83
|
+
RunStatus.INTERRUPTED,
|
|
84
|
+
}),
|
|
85
|
+
RunStatus.INTERRUPTED: frozenset({
|
|
86
|
+
RunStatus.PLANNING,
|
|
87
|
+
RunStatus.RUNNING,
|
|
88
|
+
RunStatus.FAILED,
|
|
89
|
+
RunStatus.CANCELLED,
|
|
90
|
+
}),
|
|
91
|
+
RunStatus.SUCCEEDED: frozenset(),
|
|
92
|
+
RunStatus.FAILED: frozenset(),
|
|
93
|
+
RunStatus.CANCELLED: frozenset(),
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class InvalidRunTransition(ValueError):
|
|
98
|
+
"""Raised when code attempts an unsupported lifecycle transition."""
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def normalize_run_status(status: RunStatus | str) -> RunStatus:
|
|
102
|
+
if isinstance(status, RunStatus):
|
|
103
|
+
return status
|
|
104
|
+
try:
|
|
105
|
+
return RunStatus(str(status))
|
|
106
|
+
except ValueError as exc:
|
|
107
|
+
raise InvalidRunTransition(f"Unknown run status: {status!r}") from exc
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def can_transition(current: RunStatus | str, target: RunStatus | str) -> bool:
|
|
111
|
+
source = normalize_run_status(current)
|
|
112
|
+
destination = normalize_run_status(target)
|
|
113
|
+
return source == destination or destination in _TRANSITIONS[source]
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def require_transition(current: RunStatus | str, target: RunStatus | str) -> None:
|
|
117
|
+
source = normalize_run_status(current)
|
|
118
|
+
destination = normalize_run_status(target)
|
|
119
|
+
if not can_transition(source, destination):
|
|
120
|
+
raise InvalidRunTransition(
|
|
121
|
+
f"Invalid run transition: {source.value} -> {destination.value}"
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def is_terminal(status: RunStatus | str) -> bool:
|
|
126
|
+
return normalize_run_status(status) in TERMINAL_RUN_STATUSES
|
|
127
|
+
|