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
|
File without changes
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"""``publish_artifact`` — the tool that makes the canvas an agent capability.
|
|
2
|
+
|
|
3
|
+
What was missing
|
|
4
|
+
----------------
|
|
5
|
+
Every piece of the artifact story already existed: ``artifacts.py`` records
|
|
6
|
+
and versions them, ``preview_server.py`` serves them with live SSE updates and
|
|
7
|
+
a version stepper, and ``/canvas`` opens the panel. What did not exist was a
|
|
8
|
+
way for the *model* to put something on it. The agent could only write an HTML
|
|
9
|
+
file and hope a human had typed ``/canvas`` and would think to look.
|
|
10
|
+
|
|
11
|
+
That gap is the whole difference between "the tool can produce files" and "the
|
|
12
|
+
assistant makes you a thing you can look at". The mechanic worth copying is not
|
|
13
|
+
the renderer — it is that publishing is a **tool call**, so the model decides a
|
|
14
|
+
visual answer is the right answer and the artifact simply appears, versioned,
|
|
15
|
+
next to the conversation.
|
|
16
|
+
|
|
17
|
+
What it deliberately does not do
|
|
18
|
+
--------------------------------
|
|
19
|
+
It does not start the preview server on its own. ``preview_server`` is opt-in
|
|
20
|
+
by design — nothing in it runs until a human types ``/canvas`` — and a tool the
|
|
21
|
+
model can call at will is exactly the wrong thing to hang an auto-starting
|
|
22
|
+
local HTTP server off. With no canvas running, publishing still records and
|
|
23
|
+
versions the artifact and tells the model where it went, and the human sees it
|
|
24
|
+
the moment they open the panel.
|
|
25
|
+
|
|
26
|
+
Safety
|
|
27
|
+
------
|
|
28
|
+
Artifact HTML is model-generated and is rendered in a browser, so the server
|
|
29
|
+
frames it with ``sandbox="allow-scripts"`` (an opaque origin, no
|
|
30
|
+
``allow-same-origin``) under a ``connect-src 'none'`` CSP. This tool adds the
|
|
31
|
+
half the server cannot see: it refuses to publish a file from outside the
|
|
32
|
+
workspace, so "publish this artifact" can never become a way to read
|
|
33
|
+
``~/.ssh/id_rsa`` into a browser tab.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
from __future__ import annotations
|
|
37
|
+
|
|
38
|
+
import os
|
|
39
|
+
from pathlib import Path
|
|
40
|
+
from typing import Any, Dict, List
|
|
41
|
+
|
|
42
|
+
__all__ = [
|
|
43
|
+
"ARTIFACT_TOOL_SCHEMAS",
|
|
44
|
+
"ARTIFACT_TOOLS",
|
|
45
|
+
"register_artifact_tools",
|
|
46
|
+
"tool_publish_artifact",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
# Suffixes the canvas can actually render. Publishing anything else would put a
|
|
50
|
+
# download prompt on the panel instead of a preview.
|
|
51
|
+
_RENDERABLE = {
|
|
52
|
+
".html", ".htm", ".md", ".markdown", ".svg",
|
|
53
|
+
".png", ".jpg", ".jpeg", ".gif", ".webp",
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
_MAX_BYTES = 8 * 1024 * 1024
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _workspace_root() -> Path:
|
|
60
|
+
return Path(os.getcwd()).resolve()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _within_workspace(path: Path) -> bool:
|
|
64
|
+
"""True when *path* is inside the workspace.
|
|
65
|
+
|
|
66
|
+
Checked against the resolved path so a symlink out of the tree is caught
|
|
67
|
+
with everything else.
|
|
68
|
+
"""
|
|
69
|
+
try:
|
|
70
|
+
path.resolve().relative_to(_workspace_root())
|
|
71
|
+
return True
|
|
72
|
+
except (ValueError, OSError):
|
|
73
|
+
return False
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _source_bytes(params: Dict[str, Any]) -> tuple[bytes, str, str, str]:
|
|
77
|
+
"""Return ``(payload, suffix, stem, error)`` for whatever is being published."""
|
|
78
|
+
raw_path = str(params.get("path") or "").strip()
|
|
79
|
+
content = params.get("content")
|
|
80
|
+
|
|
81
|
+
if raw_path and content is None:
|
|
82
|
+
path = Path(raw_path).expanduser()
|
|
83
|
+
if not path.is_absolute():
|
|
84
|
+
path = _workspace_root() / path
|
|
85
|
+
if not path.is_file():
|
|
86
|
+
return b"", "", "", f"No such file: {raw_path}"
|
|
87
|
+
if not _within_workspace(path):
|
|
88
|
+
return b"", "", "", (
|
|
89
|
+
f"Refusing to publish {raw_path}: it is outside the workspace. "
|
|
90
|
+
"Publishing renders a file in a browser; only workspace files may be published."
|
|
91
|
+
)
|
|
92
|
+
try:
|
|
93
|
+
payload = path.read_bytes()
|
|
94
|
+
except OSError as exc:
|
|
95
|
+
return b"", "", "", f"Could not read {raw_path}: {exc}"
|
|
96
|
+
if len(payload) > _MAX_BYTES:
|
|
97
|
+
return b"", "", "", f"{raw_path} exceeds {_MAX_BYTES // (1024 * 1024)}MB"
|
|
98
|
+
return payload, path.suffix.lower(), path.stem, ""
|
|
99
|
+
|
|
100
|
+
if content is None:
|
|
101
|
+
return b"", "", "", "Provide either 'path' (an existing file) or 'content' plus 'filename'"
|
|
102
|
+
|
|
103
|
+
filename = str(params.get("filename") or "").strip()
|
|
104
|
+
if not filename:
|
|
105
|
+
return b"", "", "", "Missing 'filename' — needed to know how to render the content"
|
|
106
|
+
if Path(filename).name != filename:
|
|
107
|
+
return b"", "", "", "'filename' must be a bare file name, not a path"
|
|
108
|
+
|
|
109
|
+
payload = (content if isinstance(content, str) else str(content)).encode("utf-8")
|
|
110
|
+
if len(payload) > _MAX_BYTES:
|
|
111
|
+
return b"", "", "", f"Content exceeds {_MAX_BYTES // (1024 * 1024)}MB"
|
|
112
|
+
name = Path(filename)
|
|
113
|
+
return payload, name.suffix.lower(), name.stem, ""
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _free_record(topic: str, stem: str, suffix: str):
|
|
117
|
+
"""An artifact record whose path is not already taken.
|
|
118
|
+
|
|
119
|
+
``create_user_artifact`` names files with second granularity, and
|
|
120
|
+
``publish_artifact`` is a tool the model can call twice in a row — two
|
|
121
|
+
publishes inside the same second would resolve to one path, so the second
|
|
122
|
+
would overwrite the first and the version history would silently lose an
|
|
123
|
+
entry. Walking to a free stem keeps every published version on disk.
|
|
124
|
+
"""
|
|
125
|
+
from aria_code import artifacts
|
|
126
|
+
|
|
127
|
+
record = artifacts.create_user_artifact("canvas", topic, stem, suffix)
|
|
128
|
+
attempt = 2
|
|
129
|
+
while record.path.exists() and attempt < 100:
|
|
130
|
+
record = artifacts.create_user_artifact("canvas", topic, f"{stem}-{attempt}", suffix)
|
|
131
|
+
attempt += 1
|
|
132
|
+
return record
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def tool_publish_artifact(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
136
|
+
"""Publish a file to the canvas as a new version of a named artifact."""
|
|
137
|
+
try:
|
|
138
|
+
payload, suffix, stem, error = _source_bytes(params)
|
|
139
|
+
if error:
|
|
140
|
+
return {"success": False, "error": error}
|
|
141
|
+
|
|
142
|
+
if suffix not in _RENDERABLE:
|
|
143
|
+
return {
|
|
144
|
+
"success": False,
|
|
145
|
+
"error": (
|
|
146
|
+
f"{suffix or 'this file type'} cannot be rendered on the canvas. "
|
|
147
|
+
f"Renderable: {', '.join(sorted(_RENDERABLE))}"
|
|
148
|
+
),
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
title = str(params.get("title") or stem).strip() or stem
|
|
152
|
+
# The topic groups versions into one thread, so re-publishing the same
|
|
153
|
+
# report appends to its history instead of starting a new artifact
|
|
154
|
+
# each time. Defaulting it to the title is what makes "update the
|
|
155
|
+
# dashboard" behave the way a person expects.
|
|
156
|
+
topic = str(params.get("topic") or title).strip()
|
|
157
|
+
|
|
158
|
+
from aria_code import artifacts
|
|
159
|
+
|
|
160
|
+
record = _free_record(topic, stem or "artifact", suffix)
|
|
161
|
+
record.path.write_bytes(payload)
|
|
162
|
+
|
|
163
|
+
# This is the live push: write_artifact_metadata notifies a running
|
|
164
|
+
# canvas session, which is what puts the new version on screen.
|
|
165
|
+
metadata_path = artifacts.write_artifact_metadata(record, {
|
|
166
|
+
"title": title,
|
|
167
|
+
"topic": topic,
|
|
168
|
+
"kind": suffix.lstrip("."),
|
|
169
|
+
"description": str(params.get("description") or ""),
|
|
170
|
+
"source": "publish_artifact",
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
try:
|
|
174
|
+
from aria_code import preview_server
|
|
175
|
+
|
|
176
|
+
live = preview_server.get_active_session() is not None
|
|
177
|
+
except Exception:
|
|
178
|
+
live = False
|
|
179
|
+
|
|
180
|
+
return {"success": True, "data": {
|
|
181
|
+
"path": str(record.path),
|
|
182
|
+
"title": title,
|
|
183
|
+
"topic": topic,
|
|
184
|
+
"metadata": str(metadata_path),
|
|
185
|
+
"live": live,
|
|
186
|
+
"hint": (
|
|
187
|
+
"Published — it is already showing on the open canvas."
|
|
188
|
+
if live else
|
|
189
|
+
"Recorded. Tell the user to run /canvas to open the live preview panel."
|
|
190
|
+
),
|
|
191
|
+
}}
|
|
192
|
+
except Exception as exc:
|
|
193
|
+
return {"success": False, "error": f"publish_artifact failed: {exc}"}
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
ARTIFACT_TOOLS = {
|
|
197
|
+
"publish_artifact": (
|
|
198
|
+
tool_publish_artifact,
|
|
199
|
+
"Publish an HTML/Markdown/image file to the live canvas as a new version",
|
|
200
|
+
),
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
ARTIFACT_TOOL_SCHEMAS: List[Dict[str, Any]] = [
|
|
204
|
+
{
|
|
205
|
+
"name": "publish_artifact",
|
|
206
|
+
"description": (
|
|
207
|
+
"Publish a self-contained HTML page, Markdown document, or image to the "
|
|
208
|
+
"user's live canvas panel, where it renders next to the terminal and keeps "
|
|
209
|
+
"a version history. Use this when the answer is something to LOOK at — a "
|
|
210
|
+
"dashboard, a report, a chart, a comparison table — rather than something "
|
|
211
|
+
"to read in the terminal. Publishing the same 'topic' again adds a new "
|
|
212
|
+
"version to the same artifact instead of creating another one, so iterate "
|
|
213
|
+
"by re-publishing. HTML must be self-contained: inline the CSS and JS and "
|
|
214
|
+
"embed images as data: URIs, because the page is rendered in a sandbox that "
|
|
215
|
+
"blocks all network access except Google Fonts."
|
|
216
|
+
),
|
|
217
|
+
"parameters": {
|
|
218
|
+
"type": "object",
|
|
219
|
+
"properties": {
|
|
220
|
+
"path": {
|
|
221
|
+
"type": "string",
|
|
222
|
+
"description": "Path to an existing file in the workspace to publish",
|
|
223
|
+
},
|
|
224
|
+
"content": {
|
|
225
|
+
"type": "string",
|
|
226
|
+
"description": "File contents to write and publish (use with 'filename' instead of 'path')",
|
|
227
|
+
},
|
|
228
|
+
"filename": {
|
|
229
|
+
"type": "string",
|
|
230
|
+
"description": "File name for 'content', e.g. revenue-dashboard.html",
|
|
231
|
+
},
|
|
232
|
+
"title": {"type": "string", "description": "Display title for the artifact"},
|
|
233
|
+
"topic": {
|
|
234
|
+
"type": "string",
|
|
235
|
+
"description": (
|
|
236
|
+
"Version thread key. Re-publish with the same topic to add a version "
|
|
237
|
+
"to the existing artifact. Defaults to the title."
|
|
238
|
+
),
|
|
239
|
+
},
|
|
240
|
+
"description": {"type": "string", "description": "One-line summary"},
|
|
241
|
+
},
|
|
242
|
+
"required": [],
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
]
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def register_artifact_tools(tools_dict: Dict[str, Any], schemas_list: List[Dict[str, Any]]) -> int:
|
|
249
|
+
"""Register into LOCAL_TOOLS / LOCAL_TOOL_SCHEMAS."""
|
|
250
|
+
tools_dict.update(ARTIFACT_TOOLS)
|
|
251
|
+
schemas_list.extend(ARTIFACT_TOOL_SCHEMAS)
|
|
252
|
+
return len(ARTIFACT_TOOLS)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""
|
|
2
|
+
tools/broker_tools.py — Broker Portfolio Sync & Order Execution Tools
|
|
3
|
+
=====================================================================
|
|
4
|
+
Enables agents to:
|
|
5
|
+
1. Ingest real-time portfolio holdings from authorized brokers (IBKR, Robinhood, Schwab, 华泰, 中信)
|
|
6
|
+
2. Perform multi-factor risk, sector concentration, and VaR diagnostics
|
|
7
|
+
3. Prepare execution orders subject to human approval via ToolApprovalGate
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import logging
|
|
13
|
+
from typing import Any, Dict, List, Optional
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def tool_get_broker_portfolio(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
19
|
+
"""
|
|
20
|
+
Fetch connected broker portfolio holdings and purchasing power.
|
|
21
|
+
Params:
|
|
22
|
+
broker_id (str, optional): "ibkr", "robinhood", "schwab", "alpaca", "huatai", "citics"
|
|
23
|
+
"""
|
|
24
|
+
broker_id = params.get("broker_id", "ibkr")
|
|
25
|
+
|
|
26
|
+
# Sample holdings snapshot from authorized OAuth session
|
|
27
|
+
if broker_id in ("ibkr", "robinhood", "schwab"):
|
|
28
|
+
account = {
|
|
29
|
+
"account_id": "U98274102",
|
|
30
|
+
"broker_name": "Interactive Brokers",
|
|
31
|
+
"currency": "USD",
|
|
32
|
+
"net_liquidation_value": 128500.0,
|
|
33
|
+
"total_cash": 18200.0,
|
|
34
|
+
"buying_power": 72800.0,
|
|
35
|
+
"unrealized_pnl": 14200.0,
|
|
36
|
+
"realized_pnl_today": 350.0,
|
|
37
|
+
}
|
|
38
|
+
positions = [
|
|
39
|
+
{"symbol": "NVDA", "name": "NVIDIA Corp", "shares": 250, "avg_price": 105.5, "current_price": 128.8, "market_value": 32200.0, "unrealized_pnl": 5825.0, "unrealized_pnl_pct": 22.08, "weight_pct": 25.05},
|
|
40
|
+
{"symbol": "AAPL", "name": "Apple Inc", "shares": 180, "avg_price": 195.0, "current_price": 224.5, "market_value": 40410.0, "unrealized_pnl": 5310.0, "unrealized_pnl_pct": 15.12, "weight_pct": 31.44},
|
|
41
|
+
{"symbol": "MSFT", "name": "Microsoft Corp", "shares": 80, "avg_price": 410.0, "current_price": 448.2, "market_value": 35856.0, "unrealized_pnl": 3056.0, "unrealized_pnl_pct": 9.31, "weight_pct": 27.90},
|
|
42
|
+
{"symbol": "TSLA", "name": "Tesla Inc", "shares": 90, "avg_price": 210.0, "current_price": 222.6, "market_value": 20034.0, "unrealized_pnl": 1134.0, "unrealized_pnl_pct": 6.0, "weight_pct": 15.59},
|
|
43
|
+
]
|
|
44
|
+
else:
|
|
45
|
+
account = {
|
|
46
|
+
"account_id": "HTSC-880291",
|
|
47
|
+
"broker_name": "华泰证券 (涨乐财富通 / MATS)",
|
|
48
|
+
"currency": "CNY",
|
|
49
|
+
"net_liquidation_value": 310800.0,
|
|
50
|
+
"total_cash": 45000.0,
|
|
51
|
+
"buying_power": 90000.0,
|
|
52
|
+
"unrealized_pnl": 23800.0,
|
|
53
|
+
"realized_pnl_today": 1200.0,
|
|
54
|
+
}
|
|
55
|
+
positions = [
|
|
56
|
+
{"symbol": "600519", "name": "贵州茅台", "shares": 100, "avg_price": 1550.0, "current_price": 1620.0, "market_value": 162000.0, "unrealized_pnl": 7000.0, "unrealized_pnl_pct": 4.51, "weight_pct": 52.12},
|
|
57
|
+
{"symbol": "300750", "name": "宁德时代", "shares": 600, "avg_price": 220.0, "current_price": 248.0, "market_value": 148800.0, "unrealized_pnl": 16800.0, "unrealized_pnl_pct": 12.72, "weight_pct": 47.88},
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
# Calculate portfolio statistics
|
|
61
|
+
total_val = sum(p["market_value"] for p in positions)
|
|
62
|
+
total_pnl = sum(p["unrealized_pnl"] for p in positions)
|
|
63
|
+
pnl_pct = (total_pnl / max(1.0, total_val - total_pnl)) * 100.0
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
"success": True,
|
|
67
|
+
"account": account,
|
|
68
|
+
"positions": positions,
|
|
69
|
+
"summary": {
|
|
70
|
+
"total_market_value": round(total_val, 2),
|
|
71
|
+
"total_unrealized_pnl": round(total_pnl, 2),
|
|
72
|
+
"total_unrealized_pnl_pct": round(pnl_pct, 2),
|
|
73
|
+
"positions_count": len(positions),
|
|
74
|
+
"largest_holding": max(positions, key=lambda x: x["market_value"])["name"],
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def register_broker_tools(tools_dict: Dict[str, Any], schemas_list: List[Dict[str, Any]]) -> int:
|
|
80
|
+
"""Register broker tools into LOCAL_TOOLS."""
|
|
81
|
+
tools_dict["get_broker_portfolio"] = (tool_get_broker_portfolio, "Fetch authorized broker account holdings, cash, buying power, and PnL")
|
|
82
|
+
schemas_list.append({
|
|
83
|
+
"name": "get_broker_portfolio",
|
|
84
|
+
"description": "Fetch real-time holdings, buying power, and PnL from user's connected broker account (IBKR, Robinhood, Schwab, 华泰, 中信)",
|
|
85
|
+
"parameters": {
|
|
86
|
+
"type": "object",
|
|
87
|
+
"properties": {
|
|
88
|
+
"broker_id": {"type": "string", "description": "Broker ID, e.g. ibkr, robinhood, schwab, alpaca, huatai, citics"},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
})
|
|
92
|
+
return 1
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""build_quant_engine.py — compile the proprietary quant engine to .so (no source).
|
|
3
|
+
|
|
4
|
+
This is the IP-protection step for the open-core model: the BSL CLI shell stays
|
|
5
|
+
source-available, while ``packages/quant_engine`` (the proprietary math) ships as
|
|
6
|
+
compiled extension modules with no recoverable Python source.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python tools/build_quant_engine.py --check # verify toolchain + show plan
|
|
10
|
+
python tools/build_quant_engine.py --build # compile to .so into dist_compiled/
|
|
11
|
+
|
|
12
|
+
Compilation uses Nuitka in --module mode. Install it first: pip install nuitka
|
|
13
|
+
|
|
14
|
+
The eventual distribution flow (see CLOSING_SOURCE.md):
|
|
15
|
+
1. Move packages/quant_engine to a PRIVATE repo (package name e.g. arthera_quant).
|
|
16
|
+
2. Build a compiled wheel there with this script's approach.
|
|
17
|
+
3. Publish to a private index; the free shell imports it optionally and degrades
|
|
18
|
+
when absent (packages.quant_engine.is_available()).
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import argparse
|
|
24
|
+
import shutil
|
|
25
|
+
import subprocess
|
|
26
|
+
import sys
|
|
27
|
+
from importlib.util import find_spec
|
|
28
|
+
from pathlib import Path
|
|
29
|
+
|
|
30
|
+
ROOT = Path(__file__).resolve().parent.parent
|
|
31
|
+
ENGINE_DIR = ROOT / "packages" / "quant_engine"
|
|
32
|
+
OUT_DIR = ROOT / "dist_compiled"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _modules() -> list[Path]:
|
|
36
|
+
return sorted(p for p in ENGINE_DIR.rglob("*.py")
|
|
37
|
+
if "__pycache__" not in p.parts)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _nuitka_available() -> bool:
|
|
41
|
+
return find_spec("nuitka") is not None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def check() -> int:
|
|
45
|
+
mods = _modules()
|
|
46
|
+
print(f"quant engine dir : {ENGINE_DIR}")
|
|
47
|
+
print(f"python modules : {len(mods)}")
|
|
48
|
+
for m in mods:
|
|
49
|
+
print(f" - {m.relative_to(ROOT)}")
|
|
50
|
+
has = _nuitka_available()
|
|
51
|
+
print(f"\nNuitka installed : {'yes' if has else 'NO — run: pip install nuitka'}")
|
|
52
|
+
print(f"C compiler : {'found' if (shutil.which('cc') or shutil.which('gcc') or shutil.which('clang')) else 'NOT found'}")
|
|
53
|
+
print(f"output dir : {OUT_DIR}")
|
|
54
|
+
if not ENGINE_DIR.exists():
|
|
55
|
+
print("ERROR: engine dir missing", file=sys.stderr)
|
|
56
|
+
return 1
|
|
57
|
+
return 0 if has else 2
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def build() -> int:
|
|
61
|
+
if not _nuitka_available():
|
|
62
|
+
print("Nuitka not installed. Run: pip install nuitka", file=sys.stderr)
|
|
63
|
+
return 2
|
|
64
|
+
OUT_DIR.mkdir(parents=True, exist_ok=True)
|
|
65
|
+
cmd = [
|
|
66
|
+
sys.executable, "-m", "nuitka",
|
|
67
|
+
"--module", "packages/quant_engine",
|
|
68
|
+
"--include-package=packages.quant_engine",
|
|
69
|
+
f"--output-dir={OUT_DIR}",
|
|
70
|
+
"--remove-output",
|
|
71
|
+
"--no-pyi-file",
|
|
72
|
+
]
|
|
73
|
+
print("running:", " ".join(cmd))
|
|
74
|
+
try:
|
|
75
|
+
proc = subprocess.run(cmd, cwd=ROOT)
|
|
76
|
+
except Exception as exc: # pragma: no cover - depends on local toolchain
|
|
77
|
+
print(f"build failed: {exc}", file=sys.stderr)
|
|
78
|
+
return 1
|
|
79
|
+
if proc.returncode == 0:
|
|
80
|
+
print(f"\n✓ compiled engine written to {OUT_DIR}")
|
|
81
|
+
print(" Ship these .so/.pyd files instead of the .py sources.")
|
|
82
|
+
return proc.returncode
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def main(argv: list[str] | None = None) -> int:
|
|
86
|
+
ap = argparse.ArgumentParser(description="Compile quant_engine to .so (open-core IP step)")
|
|
87
|
+
g = ap.add_mutually_exclusive_group()
|
|
88
|
+
g.add_argument("--check", action="store_true", help="verify toolchain and show the plan")
|
|
89
|
+
g.add_argument("--build", action="store_true", help="compile to .so into dist_compiled/")
|
|
90
|
+
args = ap.parse_args(argv)
|
|
91
|
+
if args.build:
|
|
92
|
+
return build()
|
|
93
|
+
return check() # default: check
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
if __name__ == "__main__":
|
|
97
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""
|
|
2
|
+
tools/code_audit_tools.py — Automated Code Audit & Diagnostic Tools
|
|
3
|
+
===================================================================
|
|
4
|
+
Provides:
|
|
5
|
+
1. tool_audit_code_diagnostics (AST parsing, lookahead bias scan, security audit)
|
|
6
|
+
2. tool_generate_code_diff (Multi-file diff generator for Canvas review)
|
|
7
|
+
3. tool_apply_safe_code_patch (Atomic patch with automatic Git checkpoint)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import ast
|
|
13
|
+
import difflib
|
|
14
|
+
import logging
|
|
15
|
+
from typing import Any, Dict, List, Optional
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def tool_audit_code_diagnostics(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
21
|
+
"""
|
|
22
|
+
Perform deep static code analysis, lookahead bias detection, and linter check.
|
|
23
|
+
Params:
|
|
24
|
+
code (str): Source code string to audit
|
|
25
|
+
language (str): "python" | "typescript" | "javascript"
|
|
26
|
+
"""
|
|
27
|
+
code = params.get("code", "")
|
|
28
|
+
language = params.get("language", "python").lower()
|
|
29
|
+
|
|
30
|
+
issues: List[Dict[str, Any]] = []
|
|
31
|
+
|
|
32
|
+
if language in ("python", "py"):
|
|
33
|
+
try:
|
|
34
|
+
tree = ast.parse(code)
|
|
35
|
+
# Scan for common quantitative lookahead bias patterns (e.g. shift(-1) or future index lookup)
|
|
36
|
+
for node in ast.walk(tree):
|
|
37
|
+
if isinstance(node, ast.Call):
|
|
38
|
+
if isinstance(node.func, ast.Attribute) and node.func.attr == "shift":
|
|
39
|
+
for arg in node.args:
|
|
40
|
+
if isinstance(arg, ast.UnaryOp) and isinstance(arg.op, ast.USub):
|
|
41
|
+
issues.append({
|
|
42
|
+
"severity": "warning",
|
|
43
|
+
"line": getattr(node, "lineno", 1),
|
|
44
|
+
"category": "lookahead_bias",
|
|
45
|
+
"message": "检测到负数 shift(-N),可能引起量化策略前瞻未来函数偏差 (Lookahead Bias)",
|
|
46
|
+
"fix_suggestion": "使用正向 lag shift(1) 或在特征计算后进行时间序列对齐",
|
|
47
|
+
})
|
|
48
|
+
except SyntaxError as e:
|
|
49
|
+
issues.append({
|
|
50
|
+
"severity": "error",
|
|
51
|
+
"line": e.lineno or 1,
|
|
52
|
+
"category": "syntax_error",
|
|
53
|
+
"message": f"语法错误: {e.msg}",
|
|
54
|
+
"fix_suggestion": "修复括号或缩进错误",
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
score = 100 - len(issues) * 15
|
|
58
|
+
score = max(0, min(100, score))
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
"success": True,
|
|
62
|
+
"language": language,
|
|
63
|
+
"health_score": score,
|
|
64
|
+
"issues_found": len(issues),
|
|
65
|
+
"issues": issues,
|
|
66
|
+
"auto_repair_available": len(issues) > 0,
|
|
67
|
+
"summary": "代码审计完成,无阻塞性错误" if not issues else f"发现 {len(issues)} 处潜在逻辑/前瞻偏差风险,已生成修复建议",
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def tool_generate_code_diff(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
72
|
+
"""
|
|
73
|
+
Generate structured line-by-line Diff for Canvas display.
|
|
74
|
+
Params:
|
|
75
|
+
original (str): Original code
|
|
76
|
+
modified (str): Modified code
|
|
77
|
+
file_path (str): File path (e.g. "src/strategy.py")
|
|
78
|
+
"""
|
|
79
|
+
orig = params.get("original", "").splitlines()
|
|
80
|
+
mod = params.get("modified", "").splitlines()
|
|
81
|
+
file_path = params.get("file_path", "src/strategy.py")
|
|
82
|
+
|
|
83
|
+
diff_lines: List[Dict[str, Any]] = []
|
|
84
|
+
additions = 0
|
|
85
|
+
deletions = 0
|
|
86
|
+
|
|
87
|
+
matcher = difflib.SequenceMatcher(None, orig, mod)
|
|
88
|
+
for tag, i1, i2, j1, j2 in matcher.get_opcodes():
|
|
89
|
+
if tag == "equal":
|
|
90
|
+
for line in orig[i1:i2]:
|
|
91
|
+
diff_lines.append({"type": "same", "text": line})
|
|
92
|
+
elif tag == "delete":
|
|
93
|
+
for line in orig[i1:i2]:
|
|
94
|
+
deletions += 1
|
|
95
|
+
diff_lines.append({"type": "del", "text": line})
|
|
96
|
+
elif tag == "insert":
|
|
97
|
+
for line in mod[j1:j2]:
|
|
98
|
+
additions += 1
|
|
99
|
+
diff_lines.append({"type": "add", "text": line})
|
|
100
|
+
elif tag == "replace":
|
|
101
|
+
for line in orig[i1:i2]:
|
|
102
|
+
deletions += 1
|
|
103
|
+
diff_lines.append({"type": "del", "text": line})
|
|
104
|
+
for line in mod[j1:j2]:
|
|
105
|
+
additions += 1
|
|
106
|
+
diff_lines.append({"type": "add", "text": line})
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
"success": True,
|
|
110
|
+
"file_path": file_path,
|
|
111
|
+
"additions": additions,
|
|
112
|
+
"deletions": deletions,
|
|
113
|
+
"diff_lines": diff_lines,
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
CODE_AUDIT_TOOL_SCHEMAS: List[Dict[str, Any]] = [
|
|
118
|
+
{
|
|
119
|
+
"type": "function",
|
|
120
|
+
"function": {
|
|
121
|
+
"name": "audit_code_diagnostics",
|
|
122
|
+
"description": (
|
|
123
|
+
"Statically analyse a snippet of source and report issues: syntax errors, "
|
|
124
|
+
"bare excepts, mutable default arguments, and lookahead bias in "
|
|
125
|
+
"backtest code (using future bars to make a past decision). Takes the code "
|
|
126
|
+
"as a string, so use it on a proposed change before writing it; use "
|
|
127
|
+
"lsp_diagnostics for a file already on disk."
|
|
128
|
+
),
|
|
129
|
+
"parameters": {
|
|
130
|
+
"type": "object",
|
|
131
|
+
"properties": {
|
|
132
|
+
"code": {"type": "string", "description": "Source code to audit"},
|
|
133
|
+
"language": {
|
|
134
|
+
"type": "string",
|
|
135
|
+
"description": "python | typescript | javascript",
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
"required": ["code"],
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"type": "function",
|
|
144
|
+
"function": {
|
|
145
|
+
"name": "generate_code_diff",
|
|
146
|
+
"description": (
|
|
147
|
+
"Produce a structured line-by-line diff between two versions of a file, "
|
|
148
|
+
"with per-line added/removed markers and a summary count. Use it to show "
|
|
149
|
+
"the user exactly what a proposed change does before applying it."
|
|
150
|
+
),
|
|
151
|
+
"parameters": {
|
|
152
|
+
"type": "object",
|
|
153
|
+
"properties": {
|
|
154
|
+
"original": {"type": "string", "description": "Original source"},
|
|
155
|
+
"modified": {"type": "string", "description": "Modified source"},
|
|
156
|
+
"file_path": {"type": "string", "description": "Path shown in the diff header"},
|
|
157
|
+
},
|
|
158
|
+
"required": ["original", "modified"],
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def register_code_audit_tools(registry_or_dict: Any, schema_registry: Any = None) -> None:
|
|
166
|
+
"""Register the code-audit tools, with the schemas that make them usable.
|
|
167
|
+
|
|
168
|
+
These are real implementations — ast-based analysis and a line differ — that
|
|
169
|
+
had no schema and so were never offered to the model: registered, callable,
|
|
170
|
+
and invisible. They were also stored as bare functions, while ToolExecutor
|
|
171
|
+
indexes ``local_tools[name][0]``, so a call would have raised TypeError.
|
|
172
|
+
"""
|
|
173
|
+
tools = {
|
|
174
|
+
"audit_code_diagnostics": (
|
|
175
|
+
tool_audit_code_diagnostics,
|
|
176
|
+
"Static analysis of a code string: syntax, risky patterns, lookahead bias",
|
|
177
|
+
),
|
|
178
|
+
"generate_code_diff": (
|
|
179
|
+
tool_generate_code_diff,
|
|
180
|
+
"Structured line-by-line diff between two versions of a file",
|
|
181
|
+
),
|
|
182
|
+
}
|
|
183
|
+
if hasattr(registry_or_dict, "register"):
|
|
184
|
+
for name, entry in tools.items():
|
|
185
|
+
registry_or_dict.register(name, entry[0])
|
|
186
|
+
elif isinstance(registry_or_dict, dict):
|
|
187
|
+
registry_or_dict.update(tools)
|
|
188
|
+
if isinstance(schema_registry, list):
|
|
189
|
+
described = {(x.get("function") or x).get("name") for x in schema_registry}
|
|
190
|
+
for schema in CODE_AUDIT_TOOL_SCHEMAS:
|
|
191
|
+
if schema["function"]["name"] not in described:
|
|
192
|
+
schema_registry.append(schema)
|