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,278 @@
|
|
|
1
|
+
"""Safe, read-only review of user-supplied source archives.
|
|
2
|
+
|
|
3
|
+
The reviewer never executes project code, installs dependencies, follows
|
|
4
|
+
symlinks, or reads files outside the extraction root. It produces a bounded
|
|
5
|
+
deterministic baseline that an optional LLM layer can enrich later.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import io
|
|
11
|
+
import json
|
|
12
|
+
import tarfile
|
|
13
|
+
import zipfile
|
|
14
|
+
from collections import Counter
|
|
15
|
+
from dataclasses import dataclass
|
|
16
|
+
from pathlib import Path, PurePosixPath
|
|
17
|
+
from typing import Any, Iterable
|
|
18
|
+
|
|
19
|
+
from aria_code.agents.code_review import CodeReviewAgent
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
MAX_ARCHIVE_BYTES = 25 * 1024 * 1024
|
|
23
|
+
MAX_EXTRACTED_BYTES = 80 * 1024 * 1024
|
|
24
|
+
MAX_FILES = 2_000
|
|
25
|
+
MAX_REVIEW_FILES = 300
|
|
26
|
+
MAX_FILE_BYTES = 512 * 1024
|
|
27
|
+
|
|
28
|
+
_IGNORED_PARTS = {
|
|
29
|
+
".git", ".hg", ".svn", "node_modules", "vendor", "dist", "build",
|
|
30
|
+
".next", ".venv", "venv", "__pycache__", "coverage", "Pods",
|
|
31
|
+
}
|
|
32
|
+
_SENSITIVE_NAMES = {
|
|
33
|
+
".env", ".npmrc", ".pypirc", "credentials.json", "service-account.json",
|
|
34
|
+
"id_rsa", "id_dsa",
|
|
35
|
+
}
|
|
36
|
+
_TEXT_EXTENSIONS = {
|
|
37
|
+
".py", ".pyi", ".js", ".jsx", ".ts", ".tsx", ".swift", ".kt", ".kts",
|
|
38
|
+
".java", ".go", ".rs", ".rb", ".php", ".cs", ".c", ".h", ".cpp",
|
|
39
|
+
".hpp", ".m", ".mm", ".sh", ".bash", ".zsh", ".sql", ".graphql",
|
|
40
|
+
".json", ".yaml", ".yml", ".toml", ".xml", ".html", ".css", ".scss",
|
|
41
|
+
".md", ".txt",
|
|
42
|
+
}
|
|
43
|
+
_LANGUAGE_BY_EXTENSION = {
|
|
44
|
+
".py": "Python", ".pyi": "Python", ".js": "JavaScript", ".jsx": "JavaScript",
|
|
45
|
+
".ts": "TypeScript", ".tsx": "TypeScript", ".swift": "Swift", ".kt": "Kotlin",
|
|
46
|
+
".kts": "Kotlin", ".java": "Java", ".go": "Go", ".rs": "Rust", ".rb": "Ruby",
|
|
47
|
+
".php": "PHP", ".cs": "C#", ".c": "C", ".h": "C/C++", ".cpp": "C++",
|
|
48
|
+
".hpp": "C++", ".sql": "SQL", ".sh": "Shell", ".bash": "Shell", ".zsh": "Shell",
|
|
49
|
+
}
|
|
50
|
+
_TEST_MARKERS = ("test", "tests", "spec", "__tests__")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class ProjectReviewError(ValueError):
|
|
54
|
+
"""Raised when an uploaded project violates the review boundary."""
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass(frozen=True)
|
|
58
|
+
class ReviewFile:
|
|
59
|
+
path: str
|
|
60
|
+
content: str
|
|
61
|
+
language: str
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _safe_member_path(raw: str) -> PurePosixPath:
|
|
65
|
+
normalized = raw.replace("\\", "/")
|
|
66
|
+
path = PurePosixPath(normalized)
|
|
67
|
+
if path.is_absolute() or ".." in path.parts or not path.parts:
|
|
68
|
+
raise ProjectReviewError("Archive contains an unsafe path.")
|
|
69
|
+
return path
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _should_ignore(path: PurePosixPath) -> bool:
|
|
73
|
+
return any(part in _IGNORED_PARTS for part in path.parts)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _is_sensitive(path: PurePosixPath) -> bool:
|
|
77
|
+
name = path.name.lower()
|
|
78
|
+
return name in _SENSITIVE_NAMES or name.startswith(".env.") or path.suffix.lower() in {".pem", ".key", ".p12", ".pfx"}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _decode_text(data: bytes) -> str | None:
|
|
82
|
+
if b"\x00" in data[:8192]:
|
|
83
|
+
return None
|
|
84
|
+
try:
|
|
85
|
+
return data.decode("utf-8")
|
|
86
|
+
except UnicodeDecodeError:
|
|
87
|
+
return data.decode("utf-8", errors="replace")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _archive_entries(payload: bytes, filename: str) -> Iterable[tuple[str, bytes]]:
|
|
91
|
+
lowered = filename.lower()
|
|
92
|
+
stream = io.BytesIO(payload)
|
|
93
|
+
if lowered.endswith(".zip"):
|
|
94
|
+
try:
|
|
95
|
+
with zipfile.ZipFile(stream) as archive:
|
|
96
|
+
declared = [item for item in archive.infolist() if not item.is_dir()]
|
|
97
|
+
if len(declared) > MAX_FILES or sum(max(item.file_size, 0) for item in declared) > MAX_EXTRACTED_BYTES:
|
|
98
|
+
raise ProjectReviewError("Expanded project exceeds the file-count or size limit.")
|
|
99
|
+
for info in declared:
|
|
100
|
+
if info.is_dir():
|
|
101
|
+
continue
|
|
102
|
+
if info.file_size > MAX_FILE_BYTES or info.file_size < 0:
|
|
103
|
+
continue
|
|
104
|
+
# Unix symlink bit; links are never materialized or followed.
|
|
105
|
+
if (info.external_attr >> 16) & 0o170000 == 0o120000:
|
|
106
|
+
continue
|
|
107
|
+
yield info.filename, archive.read(info)
|
|
108
|
+
except (zipfile.BadZipFile, RuntimeError) as exc:
|
|
109
|
+
raise ProjectReviewError("Invalid or encrypted ZIP archive.") from exc
|
|
110
|
+
return
|
|
111
|
+
if lowered.endswith((".tar.gz", ".tgz", ".tar")):
|
|
112
|
+
mode = "r:gz" if lowered.endswith((".tar.gz", ".tgz")) else "r:"
|
|
113
|
+
try:
|
|
114
|
+
with tarfile.open(fileobj=stream, mode=mode) as archive:
|
|
115
|
+
declared = [item for item in archive.getmembers() if item.isfile()]
|
|
116
|
+
if len(declared) > MAX_FILES or sum(max(item.size, 0) for item in declared) > MAX_EXTRACTED_BYTES:
|
|
117
|
+
raise ProjectReviewError("Expanded project exceeds the file-count or size limit.")
|
|
118
|
+
for member in declared:
|
|
119
|
+
if not member.isfile() or member.issym() or member.islnk():
|
|
120
|
+
continue
|
|
121
|
+
if member.size > MAX_FILE_BYTES or member.size < 0:
|
|
122
|
+
continue
|
|
123
|
+
source = archive.extractfile(member)
|
|
124
|
+
if source is not None:
|
|
125
|
+
yield member.name, source.read()
|
|
126
|
+
except tarfile.TarError as exc:
|
|
127
|
+
raise ProjectReviewError("Invalid TAR archive.") from exc
|
|
128
|
+
return
|
|
129
|
+
raise ProjectReviewError("Only .zip, .tar, .tar.gz, and .tgz projects are supported.")
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _collect_files(payload: bytes, filename: str) -> tuple[list[ReviewFile], dict[str, Any]]:
|
|
133
|
+
if not payload or len(payload) > MAX_ARCHIVE_BYTES:
|
|
134
|
+
raise ProjectReviewError(f"Project archive must be between 1 byte and {MAX_ARCHIVE_BYTES} bytes.")
|
|
135
|
+
files: list[ReviewFile] = []
|
|
136
|
+
total_files = total_bytes = skipped_sensitive = skipped_binary = 0
|
|
137
|
+
languages: Counter[str] = Counter()
|
|
138
|
+
for raw_path, data in _archive_entries(payload, filename):
|
|
139
|
+
path = _safe_member_path(raw_path)
|
|
140
|
+
if _should_ignore(path):
|
|
141
|
+
continue
|
|
142
|
+
total_files += 1
|
|
143
|
+
total_bytes += len(data)
|
|
144
|
+
if total_files > MAX_FILES or total_bytes > MAX_EXTRACTED_BYTES:
|
|
145
|
+
raise ProjectReviewError("Expanded project exceeds the file-count or size limit.")
|
|
146
|
+
if _is_sensitive(path):
|
|
147
|
+
skipped_sensitive += 1
|
|
148
|
+
continue
|
|
149
|
+
if len(data) > MAX_FILE_BYTES or path.suffix.lower() not in _TEXT_EXTENSIONS:
|
|
150
|
+
skipped_binary += 1
|
|
151
|
+
continue
|
|
152
|
+
text = _decode_text(data)
|
|
153
|
+
if text is None:
|
|
154
|
+
skipped_binary += 1
|
|
155
|
+
continue
|
|
156
|
+
language = _LANGUAGE_BY_EXTENSION.get(path.suffix.lower(), "Text")
|
|
157
|
+
languages[language] += max(text.count("\n") + 1, 1)
|
|
158
|
+
if len(files) < MAX_REVIEW_FILES:
|
|
159
|
+
files.append(ReviewFile(str(path), text, language))
|
|
160
|
+
if not files:
|
|
161
|
+
raise ProjectReviewError("No reviewable source or text files were found.")
|
|
162
|
+
return files, {
|
|
163
|
+
"archive_name": PurePosixPath(filename).name[:180],
|
|
164
|
+
"total_files": total_files,
|
|
165
|
+
"reviewed_files": len(files),
|
|
166
|
+
"total_uncompressed_bytes": total_bytes,
|
|
167
|
+
"skipped_sensitive_files": skipped_sensitive,
|
|
168
|
+
"skipped_binary_or_large_files": skipped_binary,
|
|
169
|
+
"languages": [{"name": name, "lines": lines} for name, lines in languages.most_common(8)],
|
|
170
|
+
"truncated": len(files) >= MAX_REVIEW_FILES or total_files > len(files) + skipped_sensitive + skipped_binary,
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def _project_recommendations(files: list[ReviewFile], summary: dict[str, Any]) -> list[dict[str, str]]:
|
|
175
|
+
paths = [item.path.lower() for item in files]
|
|
176
|
+
names = {PurePosixPath(path).name for path in paths}
|
|
177
|
+
recommendations: list[dict[str, str]] = []
|
|
178
|
+
has_tests = any(any(marker in PurePosixPath(path).parts or marker in PurePosixPath(path).name for marker in _TEST_MARKERS) for path in paths)
|
|
179
|
+
has_ci = any(path.startswith(".github/workflows/") or path.startswith(".gitlab-ci") for path in paths)
|
|
180
|
+
has_readme = any(name.startswith("readme") for name in names)
|
|
181
|
+
has_lockfile = bool(names & {"package-lock.json", "pnpm-lock.yaml", "yarn.lock", "poetry.lock", "uv.lock", "cargo.lock", "go.sum"})
|
|
182
|
+
if not has_tests:
|
|
183
|
+
recommendations.append({"priority": "high", "category": "testing", "message": "未发现测试目录或测试文件;先为核心业务路径补充可重复执行的单元与集成测试。"})
|
|
184
|
+
if not has_ci:
|
|
185
|
+
recommendations.append({"priority": "medium", "category": "delivery", "message": "未发现 CI 工作流;建议在合并前自动运行格式、静态检查、测试和依赖审计。"})
|
|
186
|
+
if not has_readme:
|
|
187
|
+
recommendations.append({"priority": "medium", "category": "documentation", "message": "未发现 README;补充本地启动、配置、测试、部署与安全边界说明。"})
|
|
188
|
+
if not has_lockfile and any(name in names for name in {"package.json", "pyproject.toml", "cargo.toml", "go.mod"}):
|
|
189
|
+
recommendations.append({"priority": "medium", "category": "dependencies", "message": "检测到依赖清单但未发现锁文件;应用项目应锁定可复现依赖版本。"})
|
|
190
|
+
if summary.get("skipped_sensitive_files"):
|
|
191
|
+
recommendations.append({"priority": "high", "category": "secrets", "message": "上传包包含敏感配置文件,审核时已跳过;确认这些文件未进入版本库并轮换可能暴露的凭据。"})
|
|
192
|
+
if summary.get("truncated"):
|
|
193
|
+
recommendations.append({"priority": "medium", "category": "coverage", "message": "项目超过单次审核覆盖上限;建议按服务、包或提交拆分后继续审核。"})
|
|
194
|
+
return recommendations
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def _product_assessment(files: list[ReviewFile]) -> dict[str, Any]:
|
|
198
|
+
"""Infer product shape from repository evidence, without executing it."""
|
|
199
|
+
paths = [item.path.lower() for item in files]
|
|
200
|
+
names = {PurePosixPath(path).name for path in paths}
|
|
201
|
+
joined = "\n".join(item.content[:8_000] for item in files[:80]).lower()
|
|
202
|
+
product_types: list[str] = []
|
|
203
|
+
frameworks: list[str] = []
|
|
204
|
+
|
|
205
|
+
evidence_map = {
|
|
206
|
+
"web": ("package.json", "vite.config", "next.config", "src/app", "src/pages"),
|
|
207
|
+
"mobile": ("project.pbxproj", "package.swift", "androidmanifest.xml", "pubspec.yaml"),
|
|
208
|
+
"backend_api": ("fastapi", "django", "flask", "express(", "@restcontroller", "gin.default"),
|
|
209
|
+
"cli": ("[project.scripts]", "console_scripts", "commander(", "argparse", "click.command"),
|
|
210
|
+
"library": ("setup.py", "pyproject.toml", "package.json", "cargo.toml", "go.mod"),
|
|
211
|
+
}
|
|
212
|
+
for kind, markers in evidence_map.items():
|
|
213
|
+
if any(marker in joined or any(marker in path for path in paths) or marker in names for marker in markers):
|
|
214
|
+
product_types.append(kind)
|
|
215
|
+
|
|
216
|
+
framework_markers = {
|
|
217
|
+
"React": ("react", "react-dom"), "Next.js": ("next", "next.config"),
|
|
218
|
+
"Vue": ("vue", "nuxt"), "SwiftUI": ("swiftui",), "FastAPI": ("fastapi",),
|
|
219
|
+
"Django": ("django",), "Flask": ("flask",), "Express": ("express",),
|
|
220
|
+
"Spring": ("springframework",), "Flutter": ("flutter", "pubspec.yaml"),
|
|
221
|
+
}
|
|
222
|
+
for framework, markers in framework_markers.items():
|
|
223
|
+
if any(marker in joined or any(marker in path for path in paths) for marker in markers):
|
|
224
|
+
frameworks.append(framework)
|
|
225
|
+
|
|
226
|
+
dimensions = {
|
|
227
|
+
"user_experience": any(Path(path).suffix in {".tsx", ".jsx", ".swift", ".html", ".vue"} for path in paths),
|
|
228
|
+
"api_and_data": any(marker in joined for marker in ("fastapi", "express", "router", "@app.", "@router.", "graphql")),
|
|
229
|
+
"authentication": any(marker in joined for marker in ("oauth", "jwt", "firebaseauth", "authentication", "authorization")),
|
|
230
|
+
"testing": any(any(marker in path for marker in _TEST_MARKERS) for path in paths),
|
|
231
|
+
"continuous_delivery": any(path.startswith(".github/workflows/") or ".gitlab-ci" in path for path in paths),
|
|
232
|
+
"documentation": any(PurePosixPath(path).name.startswith("readme") for path in paths),
|
|
233
|
+
"containerization": any(PurePosixPath(path).name in {"dockerfile", "docker-compose.yml", "compose.yaml"} for path in paths),
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
"product_types": product_types or ["software_project"],
|
|
237
|
+
"frameworks": frameworks,
|
|
238
|
+
"review_dimensions": dimensions,
|
|
239
|
+
"evidence_basis": "manifest names, source imports, and repository paths",
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def review_project_archive(payload: bytes, filename: str) -> dict[str, Any]:
|
|
244
|
+
"""Return a bounded project report without executing any uploaded code."""
|
|
245
|
+
files, summary = _collect_files(payload, filename)
|
|
246
|
+
findings: list[dict[str, Any]] = []
|
|
247
|
+
for item in files:
|
|
248
|
+
source = item.content[: CodeReviewAgent.MAX_SOURCE_CHARS]
|
|
249
|
+
for finding in CodeReviewAgent.review_source(
|
|
250
|
+
source,
|
|
251
|
+
filename=item.path,
|
|
252
|
+
language=item.language,
|
|
253
|
+
):
|
|
254
|
+
row = finding.to_dict()
|
|
255
|
+
row["file"] = item.path
|
|
256
|
+
findings.append(row)
|
|
257
|
+
severity_order = {"critical": 0, "high": 1, "medium": 2, "low": 3}
|
|
258
|
+
findings.sort(key=lambda row: (severity_order.get(str(row.get("severity")), 9), str(row.get("file")), row.get("line") or 0))
|
|
259
|
+
counts = Counter(str(row["severity"]) for row in findings)
|
|
260
|
+
recommendations = _project_recommendations(files, summary)
|
|
261
|
+
product_assessment = _product_assessment(files)
|
|
262
|
+
score = max(0, 100 - counts["critical"] * 25 - counts["high"] * 12 - counts["medium"] * 4 - counts["low"])
|
|
263
|
+
return {
|
|
264
|
+
"schema_version": "aria.project-review.v1",
|
|
265
|
+
"status": "completed",
|
|
266
|
+
"summary": {**summary, "score": score, "finding_counts": {level: counts[level] for level in ("critical", "high", "medium", "low")}},
|
|
267
|
+
"product_assessment": product_assessment,
|
|
268
|
+
"findings": findings[:500],
|
|
269
|
+
"recommendations": recommendations,
|
|
270
|
+
"limitations": [
|
|
271
|
+
"只进行了只读静态审核;没有执行代码、安装依赖、访问网络或运行测试。",
|
|
272
|
+
"自动审核不能替代人工安全审计、运行时验证或渗透测试。",
|
|
273
|
+
],
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def report_as_json(payload: bytes, filename: str) -> str:
|
|
278
|
+
return json.dumps(review_project_archive(payload, filename), ensure_ascii=False, indent=2)
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"""Internal HTTP surface for Arthera to request Aria Code project reviews."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hmac
|
|
6
|
+
import os
|
|
7
|
+
|
|
8
|
+
from fastapi import APIRouter, File, Form, Header, HTTPException, Query, UploadFile
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
|
|
11
|
+
from aria_code.project_review import MAX_ARCHIVE_BYTES, ProjectReviewError, review_project_archive
|
|
12
|
+
from aria_code.workspace_service import WorkspaceService, WorkspaceServiceError
|
|
13
|
+
from aria_code.workspace_changes import WorkspaceChangeError, WorkspaceChangeService
|
|
14
|
+
from aria_code.workspace_tools import build_workspace_read_tools
|
|
15
|
+
|
|
16
|
+
router = APIRouter(prefix="/v1", tags=["Project Review"])
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _workspaces() -> WorkspaceService:
|
|
20
|
+
try:
|
|
21
|
+
ttl_hours = int(os.getenv("ARIA_CODE_WORKSPACE_TTL_HOURS", "24"))
|
|
22
|
+
except ValueError:
|
|
23
|
+
ttl_hours = 24
|
|
24
|
+
return WorkspaceService(ttl_hours=ttl_hours)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ChangeProposalRequest(BaseModel):
|
|
28
|
+
owner_id: str = Field(min_length=1, max_length=512)
|
|
29
|
+
path: str = Field(min_length=1, max_length=1000)
|
|
30
|
+
content: str = Field(max_length=1_048_576)
|
|
31
|
+
expected_sha256: str | None = Field(default=None, min_length=64, max_length=64)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class WorkspaceOwnerRequest(BaseModel):
|
|
35
|
+
owner_id: str = Field(min_length=1, max_length=512)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class WorkspaceReadRequest(WorkspaceOwnerRequest):
|
|
39
|
+
path: str = Field(min_length=1, max_length=1000)
|
|
40
|
+
offset: int = Field(default=0, ge=0)
|
|
41
|
+
limit: int = Field(default=400, ge=1, le=2000)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class WorkspaceListRequest(WorkspaceOwnerRequest):
|
|
45
|
+
path: str = Field(default=".", min_length=1, max_length=1000)
|
|
46
|
+
pattern: str = Field(default="*", min_length=1, max_length=200)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class WorkspaceSearchRequest(WorkspaceOwnerRequest):
|
|
50
|
+
pattern: str = Field(min_length=1, max_length=500)
|
|
51
|
+
path: str = Field(default=".", min_length=1, max_length=1000)
|
|
52
|
+
file_glob: str = Field(default="**/*", min_length=1, max_length=200)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _authorize(value: str | None) -> None:
|
|
56
|
+
expected = os.getenv("ARIA_CODE_REVIEW_TOKEN", "").strip()
|
|
57
|
+
if not expected:
|
|
58
|
+
raise HTTPException(status_code=503, detail="Project review service authentication is not configured.")
|
|
59
|
+
supplied = (value or "").removeprefix("Bearer ").strip()
|
|
60
|
+
if not supplied or not hmac.compare_digest(supplied, expected):
|
|
61
|
+
raise HTTPException(status_code=401, detail="Invalid project review service token.")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@router.post("/project-reviews")
|
|
65
|
+
async def create_project_review(
|
|
66
|
+
project: UploadFile = File(...),
|
|
67
|
+
authorization: str | None = Header(default=None),
|
|
68
|
+
):
|
|
69
|
+
_authorize(authorization)
|
|
70
|
+
payload = await project.read(MAX_ARCHIVE_BYTES + 1)
|
|
71
|
+
if len(payload) > MAX_ARCHIVE_BYTES:
|
|
72
|
+
raise HTTPException(status_code=413, detail="Project archive exceeds the upload limit.")
|
|
73
|
+
try:
|
|
74
|
+
return review_project_archive(payload, project.filename or "project.zip")
|
|
75
|
+
except ProjectReviewError as exc:
|
|
76
|
+
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@router.post("/workspaces", status_code=201)
|
|
80
|
+
async def create_workspace(
|
|
81
|
+
project: UploadFile = File(...),
|
|
82
|
+
owner_id: str = Form(...),
|
|
83
|
+
run_id: str = Form(...),
|
|
84
|
+
authorization: str | None = Header(default=None),
|
|
85
|
+
):
|
|
86
|
+
_authorize(authorization)
|
|
87
|
+
payload = await project.read(MAX_ARCHIVE_BYTES + 1)
|
|
88
|
+
try:
|
|
89
|
+
manifest = _workspaces().create_from_archive(
|
|
90
|
+
payload,
|
|
91
|
+
project.filename or "project.zip",
|
|
92
|
+
owner_id=owner_id,
|
|
93
|
+
run_id=run_id,
|
|
94
|
+
)
|
|
95
|
+
return manifest.public_dict()
|
|
96
|
+
except WorkspaceServiceError as exc:
|
|
97
|
+
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@router.get("/workspaces/{workspace_id}")
|
|
101
|
+
async def get_workspace(
|
|
102
|
+
workspace_id: str,
|
|
103
|
+
owner_id: str = Query(...),
|
|
104
|
+
authorization: str | None = Header(default=None),
|
|
105
|
+
):
|
|
106
|
+
_authorize(authorization)
|
|
107
|
+
try:
|
|
108
|
+
return _workspaces().get(workspace_id, owner_id=owner_id).public_dict()
|
|
109
|
+
except WorkspaceServiceError as exc:
|
|
110
|
+
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@router.delete("/workspaces/{workspace_id}", status_code=204)
|
|
114
|
+
async def delete_workspace(
|
|
115
|
+
workspace_id: str,
|
|
116
|
+
owner_id: str = Query(...),
|
|
117
|
+
authorization: str | None = Header(default=None),
|
|
118
|
+
):
|
|
119
|
+
_authorize(authorization)
|
|
120
|
+
try:
|
|
121
|
+
_workspaces().delete(workspace_id, owner_id=owner_id)
|
|
122
|
+
except WorkspaceServiceError as exc:
|
|
123
|
+
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _run_workspace_read_tool(workspace_id: str, owner_id: str, name: str, params: dict):
|
|
127
|
+
tools, _ = build_workspace_read_tools(_workspaces(), workspace_id, owner_id)
|
|
128
|
+
result = tools[name][0](params)
|
|
129
|
+
if not result.get("success"):
|
|
130
|
+
raise HTTPException(status_code=400, detail=result.get("error") or "Workspace operation failed.")
|
|
131
|
+
return result
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
@router.post("/workspaces/{workspace_id}/files/read")
|
|
135
|
+
async def read_workspace_file(
|
|
136
|
+
workspace_id: str,
|
|
137
|
+
payload: WorkspaceReadRequest,
|
|
138
|
+
authorization: str | None = Header(default=None),
|
|
139
|
+
):
|
|
140
|
+
_authorize(authorization)
|
|
141
|
+
return _run_workspace_read_tool(
|
|
142
|
+
workspace_id, payload.owner_id, "workspace_read_file", payload.model_dump(exclude={"owner_id"})
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
@router.post("/workspaces/{workspace_id}/files/list")
|
|
147
|
+
async def list_workspace_files(
|
|
148
|
+
workspace_id: str,
|
|
149
|
+
payload: WorkspaceListRequest,
|
|
150
|
+
authorization: str | None = Header(default=None),
|
|
151
|
+
):
|
|
152
|
+
_authorize(authorization)
|
|
153
|
+
return _run_workspace_read_tool(
|
|
154
|
+
workspace_id, payload.owner_id, "workspace_list_files", payload.model_dump(exclude={"owner_id"})
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@router.post("/workspaces/{workspace_id}/search")
|
|
159
|
+
async def search_workspace_code(
|
|
160
|
+
workspace_id: str,
|
|
161
|
+
payload: WorkspaceSearchRequest,
|
|
162
|
+
authorization: str | None = Header(default=None),
|
|
163
|
+
):
|
|
164
|
+
_authorize(authorization)
|
|
165
|
+
return _run_workspace_read_tool(
|
|
166
|
+
workspace_id, payload.owner_id, "workspace_search_code", payload.model_dump(exclude={"owner_id"})
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
@router.post("/workspaces/{workspace_id}/changes", status_code=201)
|
|
171
|
+
async def propose_workspace_change(
|
|
172
|
+
workspace_id: str,
|
|
173
|
+
payload: ChangeProposalRequest,
|
|
174
|
+
authorization: str | None = Header(default=None),
|
|
175
|
+
):
|
|
176
|
+
_authorize(authorization)
|
|
177
|
+
try:
|
|
178
|
+
change = WorkspaceChangeService(_workspaces()).propose(
|
|
179
|
+
workspace_id,
|
|
180
|
+
owner_id=payload.owner_id,
|
|
181
|
+
path=payload.path,
|
|
182
|
+
content=payload.content,
|
|
183
|
+
expected_sha256=payload.expected_sha256,
|
|
184
|
+
)
|
|
185
|
+
return change.public_dict()
|
|
186
|
+
except WorkspaceChangeError as exc:
|
|
187
|
+
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
@router.get("/workspaces/{workspace_id}/changes/{change_id}")
|
|
191
|
+
async def get_workspace_change(
|
|
192
|
+
workspace_id: str,
|
|
193
|
+
change_id: str,
|
|
194
|
+
owner_id: str = Query(...),
|
|
195
|
+
authorization: str | None = Header(default=None),
|
|
196
|
+
):
|
|
197
|
+
_authorize(authorization)
|
|
198
|
+
try:
|
|
199
|
+
return WorkspaceChangeService(_workspaces()).get(
|
|
200
|
+
workspace_id, change_id, owner_id=owner_id
|
|
201
|
+
).public_dict()
|
|
202
|
+
except WorkspaceChangeError as exc:
|
|
203
|
+
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
@router.post("/workspaces/{workspace_id}/changes/{change_id}/apply")
|
|
207
|
+
async def apply_workspace_change(
|
|
208
|
+
workspace_id: str,
|
|
209
|
+
change_id: str,
|
|
210
|
+
payload: WorkspaceOwnerRequest,
|
|
211
|
+
authorization: str | None = Header(default=None),
|
|
212
|
+
):
|
|
213
|
+
_authorize(authorization)
|
|
214
|
+
try:
|
|
215
|
+
return WorkspaceChangeService(_workspaces()).apply(
|
|
216
|
+
workspace_id, change_id, owner_id=payload.owner_id
|
|
217
|
+
).public_dict()
|
|
218
|
+
except WorkspaceChangeError as exc:
|
|
219
|
+
raise HTTPException(status_code=409, detail=str(exc)) from exc
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
@router.post("/workspaces/{workspace_id}/changes/{change_id}/rollback")
|
|
223
|
+
async def rollback_workspace_change(
|
|
224
|
+
workspace_id: str,
|
|
225
|
+
change_id: str,
|
|
226
|
+
payload: WorkspaceOwnerRequest,
|
|
227
|
+
authorization: str | None = Header(default=None),
|
|
228
|
+
):
|
|
229
|
+
_authorize(authorization)
|
|
230
|
+
try:
|
|
231
|
+
return WorkspaceChangeService(_workspaces()).rollback(
|
|
232
|
+
workspace_id, change_id, owner_id=payload.owner_id
|
|
233
|
+
).public_dict()
|
|
234
|
+
except WorkspaceChangeError as exc:
|
|
235
|
+
raise HTTPException(status_code=409, detail=str(exc)) from exc
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Deployable FastAPI application for the internal project-review service."""
|
|
2
|
+
|
|
3
|
+
from fastapi import FastAPI
|
|
4
|
+
|
|
5
|
+
from aria_code.project_review_api import router
|
|
6
|
+
|
|
7
|
+
app = FastAPI(
|
|
8
|
+
title="Aria Code Project Review",
|
|
9
|
+
description="Internal, read-only source archive reviewer.",
|
|
10
|
+
version="1.0.0",
|
|
11
|
+
)
|
|
12
|
+
app.include_router(router)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@app.get("/health")
|
|
16
|
+
async def health() -> dict[str, str]:
|
|
17
|
+
return {"status": "ok", "service": "aria-code-project-review"}
|
|
18
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""
|
|
2
|
+
providers/ — Aria Code 统一 LLM Provider 层
|
|
3
|
+
============================================
|
|
4
|
+
用户在 ~/.aria/providers.yaml 等用户级文件里声明提供商(项目文件不能声明),
|
|
5
|
+
CLI 自动按优先级路由,任何一级失败自动降级到下一级。
|
|
6
|
+
|
|
7
|
+
支持的提供商:
|
|
8
|
+
本地: ollama, lmstudio, vllm, llamacpp, jan
|
|
9
|
+
云端: deepseek, openai, anthropic, groq, together, dashscope
|
|
10
|
+
|
|
11
|
+
快速使用:
|
|
12
|
+
from providers.llm.registry import get_provider, stream_cloud_fallback
|
|
13
|
+
provider = get_provider("deepseek")
|
|
14
|
+
async for chunk in provider.stream(messages):
|
|
15
|
+
print(chunk["text"], end="", flush=True)
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from .llm.registry import (
|
|
19
|
+
get_provider,
|
|
20
|
+
list_available_providers,
|
|
21
|
+
stream_cloud_fallback,
|
|
22
|
+
register_provider,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"get_provider",
|
|
27
|
+
"list_available_providers",
|
|
28
|
+
"stream_cloud_fallback",
|
|
29
|
+
"register_provider",
|
|
30
|
+
]
|