aria-code 0.52.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aria_code/__init__.py +42 -0
- aria_code/_version.py +20 -0
- aria_code/adk_apps/__init__.py +1 -0
- aria_code/adk_apps/aria_code_review/__init__.py +1 -0
- aria_code/adk_apps/aria_code_review/agent.py +32 -0
- aria_code/adk_apps/aria_research/__init__.py +1 -0
- aria_code/adk_apps/aria_research/agent.py +31 -0
- aria_code/agents/__init__.py +34 -0
- aria_code/agents/base.py +318 -0
- aria_code/agents/code_review.py +200 -0
- aria_code/agents/deep/__init__.py +37 -0
- aria_code/agents/deep/calibration_loop.py +144 -0
- aria_code/agents/deep/critic.py +125 -0
- aria_code/agents/deep/deepen.py +193 -0
- aria_code/agents/deep/models.py +149 -0
- aria_code/agents/deep/pipeline.py +164 -0
- aria_code/agents/deep/quant_fusion.py +192 -0
- aria_code/agents/deep/themes.py +95 -0
- aria_code/agents/deep/tiers.py +106 -0
- aria_code/agents/engineering/__init__.py +14 -0
- aria_code/agents/engineering/coder.py +222 -0
- aria_code/agents/engineering/tester.py +145 -0
- aria_code/agents/financial/__init__.py +21 -0
- aria_code/agents/financial/cashflow_burn.py +119 -0
- aria_code/agents/financial/catalyst.py +279 -0
- aria_code/agents/financial/corporate_finance.py +175 -0
- aria_code/agents/financial/debate.py +224 -0
- aria_code/agents/financial/earnings.py +303 -0
- aria_code/agents/financial/fundamental.py +191 -0
- aria_code/agents/financial/macro.py +99 -0
- aria_code/agents/financial/news.py +207 -0
- aria_code/agents/financial/risk.py +165 -0
- aria_code/agents/financial/sector.py +279 -0
- aria_code/agents/financial/strategist.py +121 -0
- aria_code/agents/financial/stripe_revenue.py +127 -0
- aria_code/agents/financial/synthesis.py +274 -0
- aria_code/agents/financial/technical.py +258 -0
- aria_code/agents/orchestrator.py +44 -0
- aria_code/agents/portfolio_agent.py +363 -0
- aria_code/agents/realty/__init__.py +62 -0
- aria_code/agents/realty/asset_diagnosis.py +152 -0
- aria_code/agents/realty/business_match.py +166 -0
- aria_code/agents/realty/cashflow_verify.py +209 -0
- aria_code/agents/realty/contract_rules.py +210 -0
- aria_code/agents/realty/energy_anomaly.py +189 -0
- aria_code/agents/realty/exit_settlement.py +208 -0
- aria_code/agents/realty/fulfillment_risk.py +206 -0
- aria_code/agents/realty/ops_optimize.py +160 -0
- aria_code/agents/realty/revenue_share.py +215 -0
- aria_code/agents/registry.py +158 -0
- aria_code/agents/signal_scheme.py +111 -0
- aria_code/agents/sports/__init__.py +0 -0
- aria_code/agents/sports/football_agent.py +197 -0
- aria_code/agents/supervisor.py +113 -0
- aria_code/agents/team.py +492 -0
- aria_code/agents/warehouse/__init__.py +25 -0
- aria_code/agents/warehouse/contracts.py +26 -0
- aria_code/agents/warehouse/dashboard.py +155 -0
- aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
- aria_code/agents/warehouse/inbound_exceptions.py +25 -0
- aria_code/agents/warehouse/inventory_health.py +24 -0
- aria_code/agents/warehouse/local_run.py +71 -0
- aria_code/agents/warehouse/local_snapshot.py +132 -0
- aria_code/agents/warehouse/logistics_cost.py +84 -0
- aria_code/agents/warehouse/logistics_sync.py +21 -0
- aria_code/agents/warehouse/workflow.py +31 -0
- aria_code/aliyun_data_client.py +4 -0
- aria_code/apps/README.md +12 -0
- aria_code/apps/__init__.py +2 -0
- aria_code/apps/channels/README.md +15 -0
- aria_code/apps/channels/__init__.py +17 -0
- aria_code/apps/channels/intake.py +92 -0
- aria_code/apps/channels/registry.py +95 -0
- aria_code/apps/channels/tradingview.py +94 -0
- aria_code/apps/cli/README.md +13 -0
- aria_code/apps/cli/__init__.py +2 -0
- aria_code/apps/cli/_optional.py +120 -0
- aria_code/apps/cli/bootstrap.py +145 -0
- aria_code/apps/cli/broker_render.py +206 -0
- aria_code/apps/cli/codegen_paths.py +29 -0
- aria_code/apps/cli/commands/__init__.py +16 -0
- aria_code/apps/cli/commands/_business_render.py +78 -0
- aria_code/apps/cli/commands/_ui.py +71 -0
- aria_code/apps/cli/commands/analysis_cmds.py +369 -0
- aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
- aria_code/apps/cli/commands/auth_cmds.py +239 -0
- aria_code/apps/cli/commands/backtest_cmds.py +2543 -0
- aria_code/apps/cli/commands/broker_cmds.py +1234 -0
- aria_code/apps/cli/commands/business_workflow_cmds.py +319 -0
- aria_code/apps/cli/commands/canvas_cmds.py +77 -0
- aria_code/apps/cli/commands/catalog.py +87 -0
- aria_code/apps/cli/commands/core_cmds.py +2520 -0
- aria_code/apps/cli/commands/data_cmds.py +457 -0
- aria_code/apps/cli/commands/diagnostic_cmds.py +230 -0
- aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
- aria_code/apps/cli/commands/file_cmds.py +312 -0
- aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
- aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
- aria_code/apps/cli/commands/market.py +434 -0
- aria_code/apps/cli/commands/market_cmds.py +1381 -0
- aria_code/apps/cli/commands/market_context.py +425 -0
- aria_code/apps/cli/commands/market_render.py +7 -0
- aria_code/apps/cli/commands/model_cmds.py +2153 -0
- aria_code/apps/cli/commands/ops_cmds.py +721 -0
- aria_code/apps/cli/commands/orchestrator_cmds.py +179 -0
- aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
- aria_code/apps/cli/commands/portfolio_cmds.py +1278 -0
- aria_code/apps/cli/commands/report.py +437 -0
- aria_code/apps/cli/commands/scaffold_templates.py +617 -0
- aria_code/apps/cli/commands/session_cmds.py +236 -0
- aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
- aria_code/apps/cli/commands/team.py +669 -0
- aria_code/apps/cli/commands/team_render.py +8 -0
- aria_code/apps/cli/commands/ui_cmds.py +401 -0
- aria_code/apps/cli/commands/warehouse_cmds.py +79 -0
- aria_code/apps/cli/commands/workflow_cmds.py +480 -0
- aria_code/apps/cli/commands/workspace_cmds.py +1494 -0
- aria_code/apps/cli/config_paths.py +73 -0
- aria_code/apps/cli/config_store.py +78 -0
- aria_code/apps/cli/constants.py +88 -0
- aria_code/apps/cli/context.py +34 -0
- aria_code/apps/cli/deterministic.py +191 -0
- aria_code/apps/cli/direct.py +48 -0
- aria_code/apps/cli/finance_service_catalog.py +111 -0
- aria_code/apps/cli/football_reports.py +231 -0
- aria_code/apps/cli/github_app_auth.py +135 -0
- aria_code/apps/cli/google_login.py +196 -0
- aria_code/apps/cli/handlers/__init__.py +11 -0
- aria_code/apps/cli/handlers/broker_handlers.py +122 -0
- aria_code/apps/cli/handlers/chart_handlers.py +1309 -0
- aria_code/apps/cli/handlers/market_handlers.py +2513 -0
- aria_code/apps/cli/handlers/realty_handlers.py +114 -0
- aria_code/apps/cli/handlers/sports_handlers.py +22 -0
- aria_code/apps/cli/handlers/strategy_advice.py +82 -0
- aria_code/apps/cli/helpers.py +302 -0
- aria_code/apps/cli/hooks.py +180 -0
- aria_code/apps/cli/i18n.py +297 -0
- aria_code/apps/cli/intent.py +136 -0
- aria_code/apps/cli/intent_router.py +276 -0
- aria_code/apps/cli/intent_signals.py +344 -0
- aria_code/apps/cli/lifecycle_hooks.py +48 -0
- aria_code/apps/cli/local_tool_schemas.py +536 -0
- aria_code/apps/cli/main.py +29 -0
- aria_code/apps/cli/market_metadata.py +135 -0
- aria_code/apps/cli/market_universe.py +487 -0
- aria_code/apps/cli/message_processing.py +310 -0
- aria_code/apps/cli/model_catalog.py +620 -0
- aria_code/apps/cli/pdf_report.py +977 -0
- aria_code/apps/cli/plan_mode.py +139 -0
- aria_code/apps/cli/plotly_html.py +15 -0
- aria_code/apps/cli/prediction_feedback.py +202 -0
- aria_code/apps/cli/preflight.py +502 -0
- aria_code/apps/cli/project_aria.py +60 -0
- aria_code/apps/cli/prompt_assembly.py +59 -0
- aria_code/apps/cli/prompts/__init__.py +0 -0
- aria_code/apps/cli/prompts/coding.py +53 -0
- aria_code/apps/cli/prompts/select.py +142 -0
- aria_code/apps/cli/prompts/system_prompts.py +552 -0
- aria_code/apps/cli/prompts/ui.py +436 -0
- aria_code/apps/cli/provider_endpoints.py +237 -0
- aria_code/apps/cli/provider_keys.py +73 -0
- aria_code/apps/cli/providers/__init__.py +1 -0
- aria_code/apps/cli/providers/base.py +521 -0
- aria_code/apps/cli/providers/chat_routing.py +128 -0
- aria_code/apps/cli/providers/collaboration.py +98 -0
- aria_code/apps/cli/providers/llm/__init__.py +1 -0
- aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
- aria_code/apps/cli/providers/llm/ollama_stream.py +1594 -0
- aria_code/apps/cli/providers/llm/response_cache.py +60 -0
- aria_code/apps/cli/providers/llm/sse_stream.py +257 -0
- aria_code/apps/cli/providers/runtime_bridge.py +353 -0
- aria_code/apps/cli/providers/vertexai_stream.py +316 -0
- aria_code/apps/cli/runtime_consumer.py +657 -0
- aria_code/apps/cli/sandbox.py +32 -0
- aria_code/apps/cli/session_export.py +120 -0
- aria_code/apps/cli/session_jsonl.py +208 -0
- aria_code/apps/cli/session_store.py +112 -0
- aria_code/apps/cli/skills_catalog.py +273 -0
- aria_code/apps/cli/todo_tracker.py +190 -0
- aria_code/apps/cli/tool_executor.py +823 -0
- aria_code/apps/cli/tool_registry.py +34 -0
- aria_code/apps/cli/tool_scope.py +106 -0
- aria_code/apps/cli/tools/__init__.py +40 -0
- aria_code/apps/cli/tools/context.py +46 -0
- aria_code/apps/cli/tools/file_tools.py +180 -0
- aria_code/apps/cli/tools/market_tools.py +620 -0
- aria_code/apps/cli/tools/notebook_tools.py +111 -0
- aria_code/apps/cli/tools/system_tools.py +726 -0
- aria_code/apps/cli/tools/write_tools.py +845 -0
- aria_code/apps/cli/tradingview_bridge.py +529 -0
- aria_code/apps/cli/turn_planning.py +137 -0
- aria_code/apps/cli/update_check.py +153 -0
- aria_code/apps/cli/utils/__init__.py +0 -0
- aria_code/apps/cli/utils/market_detect.py +1597 -0
- aria_code/apps/daemon/README.md +14 -0
- aria_code/apps/vscode/README.md +115 -0
- aria_code/apps/vscode/package.json +70 -0
- aria_code/aria_cli.py +6743 -0
- aria_code/aria_daemon.py +1398 -0
- aria_code/aria_feishu_bot.py +1423 -0
- aria_code/aria_mcp_server.py +7 -0
- aria_code/aria_relay_client.py +4 -0
- aria_code/aria_relay_server.py +490 -0
- aria_code/aria_telegram_bot.py +202 -0
- aria_code/ariarc.py +385 -0
- aria_code/artifacts.py +581 -0
- aria_code/backtest_engine.py +4 -0
- aria_code/backtest_report.py +4 -0
- aria_code/brokers/__init__.py +78 -0
- aria_code/brokers/automation.py +193 -0
- aria_code/brokers/base.py +231 -0
- aria_code/brokers/capabilities.py +264 -0
- aria_code/brokers/cn/__init__.py +10 -0
- aria_code/brokers/cn/easytrader_broker.py +193 -0
- aria_code/brokers/cn/futu_broker.py +194 -0
- aria_code/brokers/cn/longbridge_broker.py +190 -0
- aria_code/brokers/cn/tiger_broker.py +196 -0
- aria_code/brokers/cn/xtquant_broker.py +225 -0
- aria_code/brokers/config.py +414 -0
- aria_code/brokers/intl/__init__.py +5 -0
- aria_code/brokers/intl/alpaca_broker.py +183 -0
- aria_code/brokers/intl/ibkr_broker.py +215 -0
- aria_code/brokers/intl/trading212_broker.py +183 -0
- aria_code/brokers/intl/webull_broker.py +156 -0
- aria_code/brokers/paper_broker.py +266 -0
- aria_code/brokers/planning.py +296 -0
- aria_code/brokers/registry.py +213 -0
- aria_code/brokers/trading.py +267 -0
- aria_code/canva_client.py +4 -0
- aria_code/change_store.py +127 -0
- aria_code/clients/__init__.py +0 -0
- aria_code/clients/aliyun_data_client.py +660 -0
- aria_code/clients/aria_relay_client.py +182 -0
- aria_code/clients/canva_client.py +284 -0
- aria_code/clients/figma_client.py +100 -0
- aria_code/clients/football_data_client.py +1671 -0
- aria_code/clients/kling_video_client.py +182 -0
- aria_code/clients/market_data_client.py +1976 -0
- aria_code/clients/openai_image_client.py +242 -0
- aria_code/clients/runway_video_client.py +157 -0
- aria_code/clients/warehouse_erp_client.py +105 -0
- aria_code/cloud_memory.py +181 -0
- aria_code/command_safety.py +19 -0
- aria_code/computer_use_tools.py +4 -0
- aria_code/dashboard_generator.py +579 -0
- aria_code/data_analysis_tools.py +4 -0
- aria_code/data_cleaner.py +483 -0
- aria_code/data_service.py +513 -0
- aria_code/datasources/__init__.py +23 -0
- aria_code/datasources/base.py +166 -0
- aria_code/datasources/router.py +253 -0
- aria_code/datasources/sources/__init__.py +15 -0
- aria_code/datasources/sources/akshare_source.py +269 -0
- aria_code/datasources/sources/alpha_vantage_source.py +203 -0
- aria_code/datasources/sources/edgar_source.py +219 -0
- aria_code/datasources/sources/finnhub_source.py +198 -0
- aria_code/datasources/sources/fred_source.py +223 -0
- aria_code/datasources/sources/tushare_source.py +143 -0
- aria_code/datasources/sources/web_scraper_source.py +278 -0
- aria_code/datasources/sources/world_bank_source.py +206 -0
- aria_code/datasources/sources/yfinance_source.py +152 -0
- aria_code/demo_player.py +207 -0
- aria_code/doctor.py +813 -0
- aria_code/domain/__init__.py +0 -0
- aria_code/domain/backtest_engine.py +354 -0
- aria_code/domain/backtest_report.py +472 -0
- aria_code/domain/finance_formulas.py +389 -0
- aria_code/domain/portfolio_ledger.py +307 -0
- aria_code/domain/strategy_vault.py +421 -0
- aria_code/evals/__init__.py +37 -0
- aria_code/evals/harness.py +598 -0
- aria_code/evals/runner.py +238 -0
- aria_code/external_agent_runner.py +115 -0
- aria_code/figma_client.py +4 -0
- aria_code/file_analysis_tools.py +4 -0
- aria_code/finance_formulas.py +4 -0
- aria_code/football_data_client.py +4 -0
- aria_code/image_gen_tools.py +4 -0
- aria_code/intent_classifier.py +386 -0
- aria_code/kling_video_client.py +4 -0
- aria_code/licensing.py +151 -0
- aria_code/local_finance_tools.py +4 -0
- aria_code/local_image_provider.py +4 -0
- aria_code/local_llm_provider.py +4 -0
- aria_code/macro_tools.py +4 -0
- aria_code/markdown_pdf.py +289 -0
- aria_code/market_data_client.py +4 -0
- aria_code/mcp_client.py +639 -0
- aria_code/memory_manager.py +246 -0
- aria_code/model_capability.py +486 -0
- aria_code/notification_tools.py +4 -0
- aria_code/openai_image_client.py +4 -0
- aria_code/packages/__init__.py +23 -0
- aria_code/packages/adk_bridge/__init__.py +11 -0
- aria_code/packages/adk_bridge/code_review_tools.py +49 -0
- aria_code/packages/adk_bridge/market_tools.py +125 -0
- aria_code/packages/aria_agents/__init__.py +5 -0
- aria_code/packages/aria_agents/manifest.py +78 -0
- aria_code/packages/aria_core/__init__.py +34 -0
- aria_code/packages/aria_core/architecture.py +269 -0
- aria_code/packages/aria_core/export.py +147 -0
- aria_code/packages/aria_core/manifest.py +65 -0
- aria_code/packages/aria_core/paths.py +57 -0
- aria_code/packages/aria_core/secure_file.py +68 -0
- aria_code/packages/aria_infra/__init__.py +15 -0
- aria_code/packages/aria_infra/arthera.py +52 -0
- aria_code/packages/aria_infra/doctor.py +246 -0
- aria_code/packages/aria_infra/product.py +40 -0
- aria_code/packages/aria_mcp/__init__.py +25 -0
- aria_code/packages/aria_mcp/bridge.py +201 -0
- aria_code/packages/aria_mcp/circuit.py +82 -0
- aria_code/packages/aria_mcp/config.py +111 -0
- aria_code/packages/aria_mcp/installer.py +95 -0
- aria_code/packages/aria_mcp/server.py +1550 -0
- aria_code/packages/aria_mcp/tools.py +81 -0
- aria_code/packages/aria_sdk/__init__.py +19 -0
- aria_code/packages/aria_sdk/client.py +396 -0
- aria_code/packages/aria_sdk/providers.py +70 -0
- aria_code/packages/aria_sdk/streaming.py +79 -0
- aria_code/packages/aria_sdk/types.py +86 -0
- aria_code/packages/aria_services/__init__.py +92 -0
- aria_code/packages/aria_services/cache.py +60 -0
- aria_code/packages/aria_services/context.py +356 -0
- aria_code/packages/aria_services/context_checkpoints.py +157 -0
- aria_code/packages/aria_services/data.py +11 -0
- aria_code/packages/aria_services/provider_health.py +268 -0
- aria_code/packages/aria_services/references.py +247 -0
- aria_code/packages/aria_services/registry.py +249 -0
- aria_code/packages/aria_services/research_protocol.py +57 -0
- aria_code/packages/aria_services/research_quality.py +186 -0
- aria_code/packages/aria_services/settings.py +157 -0
- aria_code/packages/aria_services/usage.py +151 -0
- aria_code/packages/aria_skills/__init__.py +46 -0
- aria_code/packages/aria_skills/catalog.py +149 -0
- aria_code/packages/aria_skills/loader.py +455 -0
- aria_code/packages/aria_skills/registry.py +84 -0
- aria_code/packages/aria_tools/__init__.py +5 -0
- aria_code/packages/aria_tools/financial/__init__.py +8 -0
- aria_code/packages/aria_tools/financial/_paths.py +130 -0
- aria_code/packages/aria_tools/financial/compliance.py +31 -0
- aria_code/packages/aria_tools/financial/factors.py +33 -0
- aria_code/packages/aria_tools/financial/risk_tools.py +33 -0
- aria_code/packages/aria_tools/financial/strategy.py +31 -0
- aria_code/packages/aria_tools/registry.py +128 -0
- aria_code/packages/quant_engine/__init__.py +34 -0
- aria_code/packages/quant_engine/_namespace.py +62 -0
- aria_code/packages/quant_engine/backtest/__init__.py +14 -0
- aria_code/packages/quant_engine/backtest/core.py +53 -0
- aria_code/packages/quant_engine/backtest/engine.py +96 -0
- aria_code/packages/quant_engine/portfolio/__init__.py +13 -0
- aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
- aria_code/packages/quant_engine/sports/__init__.py +80 -0
- aria_code/packages/quant_engine/sports/calibrator.py +354 -0
- aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
- aria_code/packages/quant_engine/sports/elo.py +300 -0
- aria_code/packages/quant_engine/sports/form.py +188 -0
- aria_code/packages/quant_engine/sports/h2h.py +195 -0
- aria_code/packages/quant_engine/sports/ml_model.py +377 -0
- aria_code/packages/quant_engine/sports/predictor.py +312 -0
- aria_code/packages/quant_engine/sports/tracker.py +665 -0
- aria_code/packages/quant_engine/stochastic/__init__.py +35 -0
- aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
- aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
- aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
- aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
- aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
- aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
- aria_code/packs/__init__.py +85 -0
- aria_code/packs/base.py +168 -0
- aria_code/packs/finance/__init__.py +250 -0
- aria_code/packs/logistics/__init__.py +169 -0
- aria_code/packs/payments/__init__.py +139 -0
- aria_code/packs/realty/__init__.py +190 -0
- aria_code/packs/registry.py +202 -0
- aria_code/packs/rules.py +90 -0
- aria_code/plan_utils.py +194 -0
- aria_code/plugin_loader.py +328 -0
- aria_code/portfolio_ledger.py +4 -0
- aria_code/preview_server.py +449 -0
- aria_code/privacy/__init__.py +5 -0
- aria_code/privacy/feedback.py +123 -0
- aria_code/project_review.py +278 -0
- aria_code/project_review_api.py +235 -0
- aria_code/project_review_server.py +18 -0
- aria_code/project_tools.py +4 -0
- aria_code/providers/__init__.py +30 -0
- aria_code/providers/llm/__init__.py +19 -0
- aria_code/providers/llm/anthropic.py +184 -0
- aria_code/providers/llm/autoconfig.py +213 -0
- aria_code/providers/llm/base.py +139 -0
- aria_code/providers/llm/custom.py +158 -0
- aria_code/providers/llm/ollama.py +129 -0
- aria_code/providers/llm/openai_compat.py +313 -0
- aria_code/providers/llm/registry.py +444 -0
- aria_code/providers/local_image_provider.py +202 -0
- aria_code/providers/local_llm_provider.py +589 -0
- aria_code/realty_data_tools.py +4 -0
- aria_code/report_exporters.py +150 -0
- aria_code/report_generator.py +1764 -0
- aria_code/runtime/__init__.py +169 -0
- aria_code/runtime/acceptance.py +481 -0
- aria_code/runtime/agent_loop.py +1520 -0
- aria_code/runtime/approval.py +57 -0
- aria_code/runtime/budget.py +232 -0
- aria_code/runtime/checkpoints.py +432 -0
- aria_code/runtime/crash_report.py +174 -0
- aria_code/runtime/events.py +113 -0
- aria_code/runtime/gateway.py +150 -0
- aria_code/runtime/lsp.py +484 -0
- aria_code/runtime/orchestrator.py +55 -0
- aria_code/runtime/repo_map.py +700 -0
- aria_code/runtime/run_state.py +127 -0
- aria_code/runtime/run_store.py +450 -0
- aria_code/runtime/self_healing.py +422 -0
- aria_code/runtime/subagent.py +547 -0
- aria_code/runtime/task_ledger.py +86 -0
- aria_code/runtime/task_orchestrator.py +90 -0
- aria_code/runtime/tool_executor.py +217 -0
- aria_code/runtime/tool_policy.py +107 -0
- aria_code/runtime/worktrees.py +215 -0
- aria_code/runway_video_client.py +4 -0
- aria_code/safety/__init__.py +23 -0
- aria_code/safety/permissions.py +306 -0
- aria_code/safety/service.py +102 -0
- aria_code/setup_wizard.py +673 -0
- aria_code/spreadsheet_tools.py +4 -0
- aria_code/strategy_vault.py +4 -0
- aria_code/tools/__init__.py +0 -0
- aria_code/tools/artifact_tools.py +252 -0
- aria_code/tools/broker_tools.py +92 -0
- aria_code/tools/build_quant_engine.py +97 -0
- aria_code/tools/code_audit_tools.py +192 -0
- aria_code/tools/computer_use_tools.py +504 -0
- aria_code/tools/data_analysis_tools.py +809 -0
- aria_code/tools/enterprise_finance_tools.py +156 -0
- aria_code/tools/extended_tools.py +240 -0
- aria_code/tools/file_analysis_tools.py +885 -0
- aria_code/tools/image_gen_tools.py +114 -0
- aria_code/tools/local_finance_tools.py +3417 -0
- aria_code/tools/logistics_tools.py +135 -0
- aria_code/tools/macro_tools.py +369 -0
- aria_code/tools/notification_tools.py +249 -0
- aria_code/tools/project_tools.py +525 -0
- aria_code/tools/realty_data_tools.py +659 -0
- aria_code/tools/spreadsheet_tools.py +388 -0
- aria_code/tools/stripe_tools.py +115 -0
- aria_code/ui/__init__.py +105 -0
- aria_code/ui/banner.py +508 -0
- aria_code/ui/completer.py +501 -0
- aria_code/ui/console.py +281 -0
- aria_code/ui/image_render.py +243 -0
- aria_code/ui/input_box.py +488 -0
- aria_code/ui/picker.py +201 -0
- aria_code/ui/render/__init__.py +11 -0
- aria_code/ui/render/finance.py +1705 -0
- aria_code/ui/render/market.py +225 -0
- aria_code/ui/render/output.py +775 -0
- aria_code/ui/render/responsive.py +75 -0
- aria_code/ui/render/team.py +354 -0
- aria_code/ui/robot.py +235 -0
- aria_code/ui/startup_dashboard.py +109 -0
- aria_code/utils/vscode_uri.py +37 -0
- aria_code/video_analysis.py +147 -0
- aria_code/video_editor.py +271 -0
- aria_code/workspace/__init__.py +6 -0
- aria_code/workspace/files.py +193 -0
- aria_code/workspace/verify.py +113 -0
- aria_code/workspace_changes.py +199 -0
- aria_code/workspace_context.py +233 -0
- aria_code/workspace_service.py +196 -0
- aria_code/workspace_tools.py +150 -0
- aria_code-0.52.0.dist-info/METADATA +237 -0
- aria_code-0.52.0.dist-info/RECORD +478 -0
- aria_code-0.52.0.dist-info/WHEEL +5 -0
- aria_code-0.52.0.dist-info/entry_points.txt +3 -0
- aria_code-0.52.0.dist-info/licenses/LICENSE +201 -0
- aria_code-0.52.0.dist-info/licenses/NOTICE +49 -0
- aria_code-0.52.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
"""UiCommandsMixin — vision, browser, screenshot, input, and context commands."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from ._ui import Panel, print_error, rich_box
|
|
6
|
+
|
|
7
|
+
import base64
|
|
8
|
+
import io
|
|
9
|
+
import pathlib
|
|
10
|
+
from urllib.parse import urlsplit
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
import json
|
|
14
|
+
import asyncio
|
|
15
|
+
import datetime
|
|
16
|
+
import time
|
|
17
|
+
import shlex
|
|
18
|
+
import sys
|
|
19
|
+
import os
|
|
20
|
+
from typing import Dict, Any, Optional
|
|
21
|
+
|
|
22
|
+
def get_model_capability(*args, **kwargs):
|
|
23
|
+
from aria_code.apps.cli._optional import get_model_capability as fn
|
|
24
|
+
return fn(*args, **kwargs)
|
|
25
|
+
def _get__HAS_COMPUTER_USE():
|
|
26
|
+
from aria_cli import _HAS_COMPUTER_USE as val
|
|
27
|
+
return val
|
|
28
|
+
def _get__PROJECT_CONTEXT():
|
|
29
|
+
from aria_cli import _PROJECT_CONTEXT as val
|
|
30
|
+
return val
|
|
31
|
+
def _get__HAS_MODEL_CAP():
|
|
32
|
+
from aria_code.apps.cli._optional import HAS_MODEL_CAP as val
|
|
33
|
+
return val
|
|
34
|
+
def _get_rich_box():
|
|
35
|
+
# Resolved locally now — see ._ui; no aria_cli round-trip.
|
|
36
|
+
return rich_box
|
|
37
|
+
def get_model_cfg(*args, **kwargs):
|
|
38
|
+
from ..model_catalog import get_model_cfg as fn
|
|
39
|
+
return fn(*args, **kwargs)
|
|
40
|
+
def _get_Panel():
|
|
41
|
+
# Resolved locally now — see ._ui; no aria_cli round-trip.
|
|
42
|
+
return Panel
|
|
43
|
+
|
|
44
|
+
import json
|
|
45
|
+
import asyncio
|
|
46
|
+
import datetime
|
|
47
|
+
import time
|
|
48
|
+
import shlex
|
|
49
|
+
import sys
|
|
50
|
+
import os
|
|
51
|
+
from typing import Dict, Any, Optional
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class UiCommandsMixin:
|
|
55
|
+
"""Mixin: visual input and terminal UI commands."""
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def _short_url_label(url: str) -> str:
|
|
59
|
+
try:
|
|
60
|
+
from urllib.parse import urlsplit
|
|
61
|
+
parsed = urlsplit(url if url.startswith(("http://", "https://")) else f"https://{url}")
|
|
62
|
+
host = parsed.netloc or parsed.path
|
|
63
|
+
path = parsed.path.rstrip("/")
|
|
64
|
+
if len(path) > 32:
|
|
65
|
+
path = path[:29] + "..."
|
|
66
|
+
return f"{host}{path}" if path and path != "/" else host
|
|
67
|
+
except Exception:
|
|
68
|
+
return url[:48]
|
|
69
|
+
|
|
70
|
+
@staticmethod
|
|
71
|
+
def _load_image_source(path_or_url: str) -> dict:
|
|
72
|
+
"""Load an image from a local path, URL, or clipboard."""
|
|
73
|
+
raw = (path_or_url or "").strip().strip("\"'")
|
|
74
|
+
if not raw:
|
|
75
|
+
raise ValueError("Missing image source")
|
|
76
|
+
|
|
77
|
+
mime_map = {
|
|
78
|
+
"png": "image/png",
|
|
79
|
+
"jpg": "image/jpeg",
|
|
80
|
+
"jpeg": "image/jpeg",
|
|
81
|
+
"gif": "image/gif",
|
|
82
|
+
"webp": "image/webp",
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
def _from_bytes(data: bytes, mime: str, label: str) -> dict:
|
|
86
|
+
if not data:
|
|
87
|
+
raise ValueError("Empty image data")
|
|
88
|
+
return {
|
|
89
|
+
"label": label,
|
|
90
|
+
"mime": mime,
|
|
91
|
+
"b64": base64.b64encode(data).decode(),
|
|
92
|
+
"size_kb": max(1, len(data) // 1024),
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if raw.lower() in {"clipboard", "clip", "paste"}:
|
|
96
|
+
try:
|
|
97
|
+
from PIL import ImageGrab
|
|
98
|
+
img = ImageGrab.grabclipboard()
|
|
99
|
+
if img is None:
|
|
100
|
+
raise ValueError("Clipboard does not contain an image")
|
|
101
|
+
if isinstance(img, list):
|
|
102
|
+
for item in img:
|
|
103
|
+
p = pathlib.Path(str(item))
|
|
104
|
+
if p.is_file() and p.suffix.lstrip(".").lower() in mime_map:
|
|
105
|
+
return UiCommandsMixin._load_image_source(str(p))
|
|
106
|
+
raise ValueError("Clipboard does not contain a supported image file")
|
|
107
|
+
if hasattr(img, "save"):
|
|
108
|
+
buf = io.BytesIO()
|
|
109
|
+
img.save(buf, format="PNG")
|
|
110
|
+
return _from_bytes(buf.getvalue(), "image/png", "clipboard")
|
|
111
|
+
raise ValueError("Clipboard image format not supported")
|
|
112
|
+
except Exception as exc:
|
|
113
|
+
raise ValueError(str(exc)) from exc
|
|
114
|
+
|
|
115
|
+
if raw.startswith(("http://", "https://", "www.")):
|
|
116
|
+
try:
|
|
117
|
+
import requests
|
|
118
|
+
url = raw if raw.startswith(("http://", "https://")) else f"https://{raw}"
|
|
119
|
+
resp = requests.get(url, timeout=20, headers={"User-Agent": "Mozilla/5.0"})
|
|
120
|
+
resp.raise_for_status()
|
|
121
|
+
content_type = (resp.headers.get("content-type") or "").split(";", 1)[0].strip().lower()
|
|
122
|
+
mime = content_type if content_type.startswith("image/") else "image/png"
|
|
123
|
+
if mime == "application/octet-stream":
|
|
124
|
+
mime = "image/png"
|
|
125
|
+
return _from_bytes(resp.content, mime, UiCommandsMixin._short_url_label(url))
|
|
126
|
+
except Exception as exc:
|
|
127
|
+
raise ValueError(f"Cannot download image: {exc}") from exc
|
|
128
|
+
|
|
129
|
+
path = pathlib.Path(raw).expanduser().resolve()
|
|
130
|
+
if not path.exists():
|
|
131
|
+
raise FileNotFoundError(f"File not found: {path}")
|
|
132
|
+
suffix = path.suffix.lstrip(".").lower()
|
|
133
|
+
mime = mime_map.get(suffix)
|
|
134
|
+
if not mime:
|
|
135
|
+
raise ValueError(f"Unsupported image type: .{suffix}")
|
|
136
|
+
return _from_bytes(path.read_bytes(), mime, path.name)
|
|
137
|
+
|
|
138
|
+
def cmd_vision(self, args: str):
|
|
139
|
+
_curr_model = self.terminal.config.get("model", "")
|
|
140
|
+
if _curr_model and _get__HAS_MODEL_CAP():
|
|
141
|
+
_vcap = get_model_capability(_curr_model)
|
|
142
|
+
if not _vcap.vision:
|
|
143
|
+
_warn = (
|
|
144
|
+
f"[yellow]⚠[/yellow] 当前模型 [bold]{_curr_model}[/bold] 不支持图片输入。\n"
|
|
145
|
+
f"[dim]支持视觉的模型:llama3.2:11b · gemma3 · llava · qwen2-vl · moondream[/dim]"
|
|
146
|
+
)
|
|
147
|
+
if self.context.has_rich:
|
|
148
|
+
self.context.console.print(_get_Panel()(_warn, border_style="yellow", box=_get_rich_box().ROUNDED, padding=(0, 1)))
|
|
149
|
+
else:
|
|
150
|
+
print(f"Warning: model {_curr_model} does not support vision input.")
|
|
151
|
+
return
|
|
152
|
+
|
|
153
|
+
path_str = args.strip().strip("\"'")
|
|
154
|
+
if not path_str:
|
|
155
|
+
msg = "Usage: /vision <image_path|image_url|clipboard> (e.g. /vision ~/Pictures/chart.png)"
|
|
156
|
+
self.context.console.print(f"[dim]{msg}[/dim]" if self.context.has_rich else msg)
|
|
157
|
+
return
|
|
158
|
+
|
|
159
|
+
try:
|
|
160
|
+
payload = self._load_image_source(path_str)
|
|
161
|
+
except Exception as e:
|
|
162
|
+
print_error(self.context, str(e), "vision")
|
|
163
|
+
return
|
|
164
|
+
|
|
165
|
+
self.terminal._pending_image = {
|
|
166
|
+
"type": "image_url",
|
|
167
|
+
"image_url": {"url": f"data:{payload['mime']};base64,{payload['b64']}"},
|
|
168
|
+
}
|
|
169
|
+
size_kb = payload["size_kb"]
|
|
170
|
+
if self.context.has_rich:
|
|
171
|
+
self.context.console.print(_get_Panel()(
|
|
172
|
+
f"[green]✓[/green] [dim]{payload['label']}[/dim] [dim]{size_kb} KB · {payload['mime']}[/dim]\n"
|
|
173
|
+
f"[dim]Image queued — ask your question now[/dim]",
|
|
174
|
+
border_style="dim",
|
|
175
|
+
box=_get_rich_box().ROUNDED,
|
|
176
|
+
padding=(0, 1),
|
|
177
|
+
))
|
|
178
|
+
else:
|
|
179
|
+
print(f"Image loaded: {payload['label']} ({size_kb} KB) — send your question now")
|
|
180
|
+
|
|
181
|
+
async def cmd_browser(self, args: str):
|
|
182
|
+
"""Open a URL in a headless browser."""
|
|
183
|
+
if not _get__HAS_COMPUTER_USE():
|
|
184
|
+
print_error(self.context,
|
|
185
|
+
"computer_use_tools not available.",
|
|
186
|
+
"Install: pip install playwright mss pyautogui pillow && playwright install chromium",
|
|
187
|
+
)
|
|
188
|
+
return
|
|
189
|
+
from computer_use_tools import _tool_browser_navigate, _tool_browser_screenshot
|
|
190
|
+
|
|
191
|
+
parts = args.strip().split(maxsplit=1)
|
|
192
|
+
if not parts:
|
|
193
|
+
if self.context.has_rich:
|
|
194
|
+
self.context.console.print("[dim]Usage: /browser <url> or /browser screenshot <url>[/dim]")
|
|
195
|
+
return
|
|
196
|
+
|
|
197
|
+
if parts[0].lower() == "screenshot" and len(parts) > 1:
|
|
198
|
+
url = parts[1].strip()
|
|
199
|
+
if self.context.has_rich:
|
|
200
|
+
with self.context.console.status(f"[dim]Screenshotting {self._short_url_label(url)}…[/dim]", spinner="dots"):
|
|
201
|
+
result = _tool_browser_screenshot({"url": url})
|
|
202
|
+
else:
|
|
203
|
+
result = _tool_browser_screenshot({"url": url})
|
|
204
|
+
if result.get("success"):
|
|
205
|
+
d = result["data"]
|
|
206
|
+
from computer_use_tools import pop_pending_vision_image
|
|
207
|
+
b64 = pop_pending_vision_image()
|
|
208
|
+
if b64:
|
|
209
|
+
self.terminal._pending_image = {
|
|
210
|
+
"type": "image_url",
|
|
211
|
+
"image_url": {"url": f"data:image/png;base64,{b64}"},
|
|
212
|
+
}
|
|
213
|
+
if self.context.has_rich:
|
|
214
|
+
self.context.console.print(_get_Panel()(
|
|
215
|
+
f"[green]✓[/green] [bold]{d.get('title','')[:60]}[/bold]\n"
|
|
216
|
+
f"[dim]{self._short_url_label(url)} · {d.get('size_kb', 0)} KB[/dim]\n"
|
|
217
|
+
f"[dim]Screenshot queued — ask your question now[/dim]",
|
|
218
|
+
border_style="dim", box=_get_rich_box().ROUNDED, padding=(0, 1),
|
|
219
|
+
))
|
|
220
|
+
else:
|
|
221
|
+
print(f"Screenshot ready ({d.get('size_kb', 0)} KB) — send your question")
|
|
222
|
+
else:
|
|
223
|
+
print_error(self.context, result.get("error", "Screenshot failed"), "browser screenshot")
|
|
224
|
+
else:
|
|
225
|
+
url = parts[0].strip()
|
|
226
|
+
if self.context.has_rich:
|
|
227
|
+
with self.context.console.status(f"[dim]Opening {self._short_url_label(url)}…[/dim]", spinner="dots"):
|
|
228
|
+
result = _tool_browser_navigate({"url": url})
|
|
229
|
+
else:
|
|
230
|
+
result = _tool_browser_navigate({"url": url})
|
|
231
|
+
if result.get("success"):
|
|
232
|
+
d = result["data"]
|
|
233
|
+
title = d.get("title", "")
|
|
234
|
+
text = d.get("text", "")[:2000]
|
|
235
|
+
links = d.get("links", [])[:5]
|
|
236
|
+
engine = d.get("engine", "")
|
|
237
|
+
if self.context.has_rich:
|
|
238
|
+
link_str = "\n".join(f" {l}" for l in links) if links else " (none)"
|
|
239
|
+
self.context.console.print(_get_Panel()(
|
|
240
|
+
f"[bold]{title[:80]}[/bold] [dim]({engine})[/dim]\n\n"
|
|
241
|
+
f"{text}\n\n[dim]Links:[/dim]\n{link_str}",
|
|
242
|
+
border_style="dim", box=_get_rich_box().ROUNDED, padding=(0, 1),
|
|
243
|
+
title=f"[dim]{self._short_url_label(url)}[/dim]", title_align="left",
|
|
244
|
+
))
|
|
245
|
+
else:
|
|
246
|
+
print(f"Title: {title}\n{text[:500]}")
|
|
247
|
+
else:
|
|
248
|
+
print_error(self.context, result.get("error", "Navigation failed"), "browser")
|
|
249
|
+
|
|
250
|
+
async def cmd_screenshot(self, args: str):
|
|
251
|
+
if not _get__HAS_COMPUTER_USE():
|
|
252
|
+
print_error(self.context,
|
|
253
|
+
"computer_use_tools not available.",
|
|
254
|
+
"Install: pip install mss pillow",
|
|
255
|
+
)
|
|
256
|
+
return
|
|
257
|
+
from computer_use_tools import _tool_computer_screenshot, pop_pending_vision_image
|
|
258
|
+
|
|
259
|
+
monitor = int(args.strip()) if args.strip().isdigit() else 1
|
|
260
|
+
if self.context.has_rich:
|
|
261
|
+
with self.context.console.status("[dim]Capturing screen…[/dim]", spinner="dots"):
|
|
262
|
+
result = _tool_computer_screenshot({"monitor": monitor})
|
|
263
|
+
else:
|
|
264
|
+
result = _tool_computer_screenshot({"monitor": monitor})
|
|
265
|
+
|
|
266
|
+
if result.get("success"):
|
|
267
|
+
d = result["data"]
|
|
268
|
+
b64 = pop_pending_vision_image()
|
|
269
|
+
if b64:
|
|
270
|
+
self.terminal._pending_image = {
|
|
271
|
+
"type": "image_url",
|
|
272
|
+
"image_url": {"url": f"data:image/png;base64,{b64}"},
|
|
273
|
+
}
|
|
274
|
+
if self.context.has_rich:
|
|
275
|
+
self.context.console.print(_get_Panel()(
|
|
276
|
+
f"[green]✓[/green] [dim]{d['width']}×{d['height']} · {d['size_kb']} KB[/dim]\n"
|
|
277
|
+
f"[dim]Screenshot queued — ask your question now[/dim]",
|
|
278
|
+
border_style="dim", box=_get_rich_box().ROUNDED, padding=(0, 1),
|
|
279
|
+
))
|
|
280
|
+
else:
|
|
281
|
+
print(f"Screenshot {d['width']}×{d['height']} ({d['size_kb']} KB) — send your question")
|
|
282
|
+
else:
|
|
283
|
+
print_error(self.context, result.get("error", "Screenshot failed"), "screenshot")
|
|
284
|
+
|
|
285
|
+
def cmd_input(self, args: str):
|
|
286
|
+
raw = args.strip().lower()
|
|
287
|
+
cfg = self.terminal.config
|
|
288
|
+
valid_styles = {"panel", "box", "plain"}
|
|
289
|
+
valid_themes = {"auto", "dark", "light"}
|
|
290
|
+
|
|
291
|
+
def _save_and_show(message: str) -> None:
|
|
292
|
+
self.context.save_config(cfg)
|
|
293
|
+
if self.context.has_rich:
|
|
294
|
+
self.context.console.print(f"[green]✓[/green] {message}")
|
|
295
|
+
self.context.console.print(
|
|
296
|
+
f" [dim]style[/dim] {cfg.get('input_style', 'panel')} "
|
|
297
|
+
f"[dim]theme[/dim] {cfg.get('input_theme', 'auto')}"
|
|
298
|
+
)
|
|
299
|
+
else:
|
|
300
|
+
print(message)
|
|
301
|
+
print(f" style {cfg.get('input_style', 'panel')} theme {cfg.get('input_theme', 'auto')}")
|
|
302
|
+
|
|
303
|
+
if not raw or raw in {"status", "show"}:
|
|
304
|
+
style = cfg.get("input_style", "panel")
|
|
305
|
+
theme = cfg.get("input_theme", "auto")
|
|
306
|
+
if self.context.has_rich:
|
|
307
|
+
self.context.console.print(_get_Panel()(
|
|
308
|
+
f"[bold]style[/bold] {style}\n"
|
|
309
|
+
f"[bold]theme[/bold] {theme}\n\n"
|
|
310
|
+
"[dim]Use[/dim] /input panel [dim]for the Codex-style input block[/dim]\n"
|
|
311
|
+
"[dim]Use[/dim] /input theme auto [dim]to follow the terminal/system theme[/dim]",
|
|
312
|
+
title="Input UI",
|
|
313
|
+
border_style="dim",
|
|
314
|
+
box=_get_rich_box().ROUNDED,
|
|
315
|
+
padding=(0, 1),
|
|
316
|
+
))
|
|
317
|
+
else:
|
|
318
|
+
print(f"input style: {style}")
|
|
319
|
+
print(f"input theme: {theme}")
|
|
320
|
+
print("Usage: /input panel|box|plain | /input theme auto|dark|light")
|
|
321
|
+
return
|
|
322
|
+
|
|
323
|
+
if raw == "reset":
|
|
324
|
+
cfg["input_style"] = "panel"
|
|
325
|
+
cfg["input_theme"] = "auto"
|
|
326
|
+
_save_and_show("input UI reset to panel · auto")
|
|
327
|
+
return
|
|
328
|
+
|
|
329
|
+
parts = raw.split()
|
|
330
|
+
if parts[0] == "theme":
|
|
331
|
+
if len(parts) != 2 or parts[1] not in valid_themes:
|
|
332
|
+
msg = "Usage: /input theme auto|dark|light"
|
|
333
|
+
self.context.console.print(f"[red]{msg}[/red]" if self.context.has_rich else msg)
|
|
334
|
+
return
|
|
335
|
+
cfg["input_theme"] = parts[1]
|
|
336
|
+
_save_and_show(f"input theme set to {parts[1]}")
|
|
337
|
+
return
|
|
338
|
+
|
|
339
|
+
if parts[0] in valid_themes and len(parts) == 1:
|
|
340
|
+
cfg["input_theme"] = parts[0]
|
|
341
|
+
_save_and_show(f"input theme set to {parts[0]}")
|
|
342
|
+
return
|
|
343
|
+
|
|
344
|
+
if parts[0] in valid_styles and len(parts) == 1:
|
|
345
|
+
cfg["input_style"] = parts[0]
|
|
346
|
+
_save_and_show(f"input style set to {parts[0]}")
|
|
347
|
+
return
|
|
348
|
+
|
|
349
|
+
msg = "Usage: /input panel|box|plain | /input theme auto|dark|light | /input reset"
|
|
350
|
+
self.context.console.print(f"[red]{msg}[/red]" if self.context.has_rich else msg)
|
|
351
|
+
|
|
352
|
+
def cmd_context(self, args: str):
|
|
353
|
+
cfg = self.terminal.config
|
|
354
|
+
conv = self.terminal.conversation
|
|
355
|
+
conv_len = len(conv)
|
|
356
|
+
model_id = cfg.get("model", "qwen2.5:7b")
|
|
357
|
+
thinking = cfg.get("thinking_mode", "auto")
|
|
358
|
+
has_auth = bool(cfg.get("auth_token"))
|
|
359
|
+
local_mode = cfg.get("local_mode", False)
|
|
360
|
+
auto_compact = bool(cfg.get("auto_compact_context", True))
|
|
361
|
+
try:
|
|
362
|
+
auto_compact_threshold = float(cfg.get("auto_compact_threshold", 0.78))
|
|
363
|
+
except Exception:
|
|
364
|
+
auto_compact_threshold = 0.78
|
|
365
|
+
auto_compact_count = int(getattr(self.terminal, "_auto_compact_count", 0) or 0)
|
|
366
|
+
|
|
367
|
+
total_chars = sum(len(m.get("content", "")) for m in conv)
|
|
368
|
+
est_tokens = total_chars // 3
|
|
369
|
+
max_ctx = get_model_cfg(model_id).get("num_ctx", 16384)
|
|
370
|
+
ctx_pct = min(100, int(est_tokens / max_ctx * 100))
|
|
371
|
+
ctx_color = "green" if ctx_pct < 60 else ("yellow" if ctx_pct < 85 else "red")
|
|
372
|
+
|
|
373
|
+
if self.context.has_rich:
|
|
374
|
+
self.context.console.print()
|
|
375
|
+
self.context.console.print("[bold]Current Context[/bold]")
|
|
376
|
+
self.context.console.print()
|
|
377
|
+
self.context.console.print(f" [dim]{'Model':<20s}[/dim]{model_id}")
|
|
378
|
+
self.context.console.print(f" [dim]{'Provider':<20s}[/dim]{'[green]Local (Ollama)[/green]' if local_mode else 'AWS → Ollama fallback'}")
|
|
379
|
+
self.context.console.print(f" [dim]{'Thinking':<20s}[/dim]{thinking}")
|
|
380
|
+
self.context.console.print(f" [dim]{'Messages':<20s}[/dim]{conv_len}")
|
|
381
|
+
self.context.console.print(f" [dim]{'Est. tokens':<20s}[/dim][{ctx_color}]{est_tokens:,} / {max_ctx:,} ({ctx_pct}%)[/{ctx_color}]")
|
|
382
|
+
self.context.console.print(f" [dim]{'Authenticated':<20s}[/dim]{'yes' if has_auth else 'no'}")
|
|
383
|
+
self.context.console.print(
|
|
384
|
+
f" [dim]{'Auto compact':<20s}[/dim]"
|
|
385
|
+
f"{'on' if auto_compact else 'off'}"
|
|
386
|
+
f" · threshold {int(auto_compact_threshold * 100)}%"
|
|
387
|
+
f" · runs {auto_compact_count}"
|
|
388
|
+
)
|
|
389
|
+
self.context.console.print(f" [dim]{'Session':<20s}[/dim]{self.terminal.session_id}")
|
|
390
|
+
self.context.console.print(f" [dim]{'Project context':<20s}[/dim]{'loaded' if _get__PROJECT_CONTEXT() else 'none'}")
|
|
391
|
+
wl = cfg.get("watchlist", [])
|
|
392
|
+
if wl:
|
|
393
|
+
self.context.console.print(f" [dim]{'Watchlist':<20s}[/dim]{', '.join(wl)}")
|
|
394
|
+
if ctx_pct >= 80:
|
|
395
|
+
self.context.console.print(f"\n [yellow]⚠ Context {ctx_pct}% full — use /compact to free space[/yellow]")
|
|
396
|
+
self.context.console.print()
|
|
397
|
+
else:
|
|
398
|
+
print(f" Model: {model_id} ({'local' if local_mode else 'aws'})")
|
|
399
|
+
print(f" Messages: {conv_len} Tokens: ~{est_tokens:,}/{max_ctx:,} ({ctx_pct}%)")
|
|
400
|
+
print(f" Auto compact: {'on' if auto_compact else 'off'} threshold={int(auto_compact_threshold * 100)}% runs={auto_compact_count}")
|
|
401
|
+
print(f" Session: {self.terminal.session_id}")
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""Warehouse ERP command; globals are rebound by the legacy CLI bridge."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import asyncio
|
|
10
|
+
import datetime
|
|
11
|
+
import time
|
|
12
|
+
import shlex
|
|
13
|
+
from typing import Dict, Any, Optional
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
import json
|
|
17
|
+
import asyncio
|
|
18
|
+
import datetime
|
|
19
|
+
import time
|
|
20
|
+
import shlex
|
|
21
|
+
import sys
|
|
22
|
+
import os
|
|
23
|
+
from typing import Dict, Any, Optional
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
import json
|
|
27
|
+
import asyncio
|
|
28
|
+
import datetime
|
|
29
|
+
import time
|
|
30
|
+
import shlex
|
|
31
|
+
import sys
|
|
32
|
+
import os
|
|
33
|
+
from typing import Dict, Any, Optional
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class WarehouseCommandsMixin:
|
|
37
|
+
"""Read-only warehouse ERP analysis commands."""
|
|
38
|
+
|
|
39
|
+
async def cmd_warehouse(self, args: str):
|
|
40
|
+
"""Run `/warehouse <warehouse_id> [--json]` against the configured ERP."""
|
|
41
|
+
parts = args.strip().split()
|
|
42
|
+
as_json = "--json" in parts
|
|
43
|
+
identifiers = [part for part in parts if not part.startswith("--")]
|
|
44
|
+
if len(identifiers) != 1:
|
|
45
|
+
message = "用法: /warehouse <仓库编号> [--json],例如 /warehouse WH-CN-01"
|
|
46
|
+
self.context.console.print(f"[yellow]{message}[/yellow]") if self.context.has_rich else print(message)
|
|
47
|
+
return
|
|
48
|
+
|
|
49
|
+
from agents.warehouse.workflow import run_warehouse_analysis
|
|
50
|
+
from clients.warehouse_erp_client import WarehouseERPConfigurationError, WarehouseERPRequestError
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
result, snapshot = await run_warehouse_analysis(identifiers[0])
|
|
54
|
+
except (WarehouseERPConfigurationError, WarehouseERPRequestError) as exc:
|
|
55
|
+
message = str(exc)
|
|
56
|
+
self.context.console.print(f"[red]{message}[/red]") if self.context.has_rich else print(message)
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
payload = {
|
|
60
|
+
"warehouse_id": identifiers[0],
|
|
61
|
+
"signal": result.final_signal,
|
|
62
|
+
"confidence": result.confidence,
|
|
63
|
+
"agents": [item.to_dict() for item in result.results],
|
|
64
|
+
"snapshot_counts": {key: len(snapshot.get(key, [])) for key in ("connectors", "inbounds", "skus", "locations")},
|
|
65
|
+
}
|
|
66
|
+
if as_json:
|
|
67
|
+
print(json.dumps(payload, ensure_ascii=False, indent=2))
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
lines = [
|
|
71
|
+
f"仓库 {identifiers[0]} · {result.final_signal} · 置信度 {result.confidence:.0%}",
|
|
72
|
+
f"货代 {payload['snapshot_counts']['connectors']} · 入库单 {payload['snapshot_counts']['inbounds']} · "
|
|
73
|
+
f"SKU {payload['snapshot_counts']['skus']} · 库位 {payload['snapshot_counts']['locations']}",
|
|
74
|
+
]
|
|
75
|
+
for item in result.results:
|
|
76
|
+
summary = item.key_points[0] if item.key_points else item.analysis
|
|
77
|
+
lines.append(f"- {item.agent}: {item.signal} — {summary}")
|
|
78
|
+
output = "\n".join(lines)
|
|
79
|
+
self.context.console.print(output) if self.context.has_rich else print(output)
|