aria-code 0.167.0__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aria_bots/__init__.py +7 -0
- aria_bots/channels/README.md +97 -0
- aria_bots/channels/__init__.py +1 -0
- aria_bots/channels/approvals.py +263 -0
- aria_bots/channels/conversation.py +280 -0
- aria_bots/channels/digest.py +186 -0
- aria_bots/channels/registry.py +95 -0
- aria_bots/engine.py +144 -0
- aria_bots/feishu_bot.py +1385 -0
- aria_bots/logistics/__init__.py +1 -0
- aria_bots/logistics/carriers.py +253 -0
- aria_bots/logistics/freight.py +154 -0
- aria_bots/logistics/inventory.py +242 -0
- aria_bots/logistics/mcp_server.py +156 -0
- aria_bots/logistics/records.py +119 -0
- aria_bots/logistics/tenancy.py +152 -0
- aria_bots/market.py +91 -0
- aria_bots/relay_client.py +326 -0
- aria_bots/telegram_bot.py +299 -0
- aria_code/__init__.py +111 -0
- aria_code/_bin/aria-native.exe +0 -0
- aria_code/_bin/aria-runtime.exe +0 -0
- aria_code/_version.py +20 -0
- aria_code/account_memory.py +296 -0
- aria_code/account_session.py +166 -0
- aria_code/adk_apps/__init__.py +1 -0
- aria_code/adk_apps/aria_code_review/__init__.py +1 -0
- aria_code/adk_apps/aria_code_review/agent.py +32 -0
- aria_code/adk_apps/aria_research/__init__.py +1 -0
- aria_code/adk_apps/aria_research/agent.py +31 -0
- aria_code/agents/__init__.py +49 -0
- aria_code/agents/base.py +329 -0
- aria_code/agents/code_review.py +200 -0
- aria_code/agents/deep/__init__.py +37 -0
- aria_code/agents/deep/calibration_loop.py +144 -0
- aria_code/agents/deep/critic.py +125 -0
- aria_code/agents/deep/deepen.py +193 -0
- aria_code/agents/deep/models.py +149 -0
- aria_code/agents/deep/pipeline.py +164 -0
- aria_code/agents/deep/quant_fusion.py +192 -0
- aria_code/agents/deep/themes.py +95 -0
- aria_code/agents/deep/tiers.py +106 -0
- aria_code/agents/engineering/__init__.py +14 -0
- aria_code/agents/engineering/coder.py +222 -0
- aria_code/agents/engineering/tester.py +145 -0
- aria_code/agents/financial/__init__.py +21 -0
- aria_code/agents/financial/cashflow_burn.py +119 -0
- aria_code/agents/financial/catalyst.py +279 -0
- aria_code/agents/financial/corporate_finance.py +175 -0
- aria_code/agents/financial/debate.py +224 -0
- aria_code/agents/financial/earnings.py +315 -0
- aria_code/agents/financial/fundamental.py +178 -0
- aria_code/agents/financial/macro.py +111 -0
- aria_code/agents/financial/news.py +231 -0
- aria_code/agents/financial/risk.py +146 -0
- aria_code/agents/financial/sector.py +279 -0
- aria_code/agents/financial/strategist.py +121 -0
- aria_code/agents/financial/stripe_revenue.py +127 -0
- aria_code/agents/financial/synthesis.py +274 -0
- aria_code/agents/financial/technical.py +277 -0
- aria_code/agents/orchestrator.py +44 -0
- aria_code/agents/portfolio_agent.py +392 -0
- aria_code/agents/realty/__init__.py +62 -0
- aria_code/agents/realty/asset_diagnosis.py +152 -0
- aria_code/agents/realty/business_match.py +166 -0
- aria_code/agents/realty/cashflow_verify.py +209 -0
- aria_code/agents/realty/contract_rules.py +210 -0
- aria_code/agents/realty/energy_anomaly.py +189 -0
- aria_code/agents/realty/exit_settlement.py +208 -0
- aria_code/agents/realty/fulfillment_risk.py +206 -0
- aria_code/agents/realty/ops_optimize.py +160 -0
- aria_code/agents/realty/revenue_share.py +215 -0
- aria_code/agents/registry.py +168 -0
- aria_code/agents/signal_scheme.py +111 -0
- aria_code/agents/sports/__init__.py +0 -0
- aria_code/agents/sports/football_agent.py +197 -0
- aria_code/agents/supervisor.py +113 -0
- aria_code/agents/team.py +500 -0
- aria_code/agents/video/__init__.py +16 -0
- aria_code/agents/video/director.py +376 -0
- aria_code/agents/video/qa_agent.py +143 -0
- aria_code/agents/video/script_doctor.py +112 -0
- aria_code/agents/warehouse/__init__.py +25 -0
- aria_code/agents/warehouse/contracts.py +26 -0
- aria_code/agents/warehouse/dashboard.py +155 -0
- aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
- aria_code/agents/warehouse/inbound_exceptions.py +25 -0
- aria_code/agents/warehouse/inventory_health.py +24 -0
- aria_code/agents/warehouse/local_run.py +71 -0
- aria_code/agents/warehouse/local_snapshot.py +132 -0
- aria_code/agents/warehouse/logistics_cost.py +84 -0
- aria_code/agents/warehouse/logistics_sync.py +21 -0
- aria_code/agents/warehouse/navigation.schema.json +110 -0
- aria_code/agents/warehouse/task_agent.py +172 -0
- aria_code/agents/warehouse/workflow.py +31 -0
- aria_code/aliyun_data_client.py +4 -0
- aria_code/apps/README.md +12 -0
- aria_code/apps/__init__.py +2 -0
- aria_code/apps/channels/README.md +9 -0
- aria_code/apps/channels/__init__.py +17 -0
- aria_code/apps/channels/approvals.py +11 -0
- aria_code/apps/channels/conversation.py +11 -0
- aria_code/apps/channels/digest.py +11 -0
- aria_code/apps/channels/intake.py +92 -0
- aria_code/apps/channels/registry.py +11 -0
- aria_code/apps/channels/tradingview.py +94 -0
- aria_code/apps/cli/README.md +13 -0
- aria_code/apps/cli/__init__.py +2 -0
- aria_code/apps/cli/_optional.py +120 -0
- aria_code/apps/cli/app_server.py +656 -0
- aria_code/apps/cli/auto_update.py +125 -0
- aria_code/apps/cli/bootstrap.py +206 -0
- aria_code/apps/cli/broker_render.py +206 -0
- aria_code/apps/cli/chat_turn.py +1327 -0
- aria_code/apps/cli/cloud_models.py +231 -0
- aria_code/apps/cli/codegen_paths.py +29 -0
- aria_code/apps/cli/commands/__init__.py +34 -0
- aria_code/apps/cli/commands/_business_render.py +78 -0
- aria_code/apps/cli/commands/_ui.py +71 -0
- aria_code/apps/cli/commands/analysis_cmds.py +378 -0
- aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
- aria_code/apps/cli/commands/auth_cmds.py +215 -0
- aria_code/apps/cli/commands/backtest_cmds.py +2518 -0
- aria_code/apps/cli/commands/broker_cmds.py +1236 -0
- aria_code/apps/cli/commands/business_workflow_cmds.py +379 -0
- aria_code/apps/cli/commands/canvas_cmds.py +77 -0
- aria_code/apps/cli/commands/catalog.py +189 -0
- aria_code/apps/cli/commands/core_cmds.py +2748 -0
- aria_code/apps/cli/commands/data_cmds.py +521 -0
- aria_code/apps/cli/commands/diagnostic_cmds.py +285 -0
- aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
- aria_code/apps/cli/commands/engineering_cmds.py +399 -0
- aria_code/apps/cli/commands/file_cmds.py +312 -0
- aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
- aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
- aria_code/apps/cli/commands/market.py +544 -0
- aria_code/apps/cli/commands/market_cmds.py +1419 -0
- aria_code/apps/cli/commands/market_context.py +432 -0
- aria_code/apps/cli/commands/market_render.py +7 -0
- aria_code/apps/cli/commands/model_cmds.py +2374 -0
- aria_code/apps/cli/commands/ops_cmds.py +721 -0
- aria_code/apps/cli/commands/orchestrator_cmds.py +181 -0
- aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
- aria_code/apps/cli/commands/portfolio_cmds.py +1316 -0
- aria_code/apps/cli/commands/report.py +476 -0
- aria_code/apps/cli/commands/scaffold_templates.py +617 -0
- aria_code/apps/cli/commands/session_cmds.py +236 -0
- aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
- aria_code/apps/cli/commands/team.py +723 -0
- aria_code/apps/cli/commands/team_render.py +8 -0
- aria_code/apps/cli/commands/ui_cmds.py +401 -0
- aria_code/apps/cli/commands/warehouse_cmds.py +297 -0
- aria_code/apps/cli/commands/workflow_cmds.py +629 -0
- aria_code/apps/cli/commands/workspace_cmds.py +1543 -0
- aria_code/apps/cli/config_paths.py +73 -0
- aria_code/apps/cli/config_store.py +158 -0
- aria_code/apps/cli/constants.py +88 -0
- aria_code/apps/cli/context.py +34 -0
- aria_code/apps/cli/conversation_policy.py +53 -0
- aria_code/apps/cli/deterministic.py +200 -0
- aria_code/apps/cli/direct.py +48 -0
- aria_code/apps/cli/earnings_view.py +172 -0
- aria_code/apps/cli/endpoint_migration.py +64 -0
- aria_code/apps/cli/exec_events.py +255 -0
- aria_code/apps/cli/file_references.py +155 -0
- aria_code/apps/cli/finance_service_catalog.py +111 -0
- aria_code/apps/cli/football_reports.py +231 -0
- aria_code/apps/cli/github_app_auth.py +135 -0
- aria_code/apps/cli/google_login.py +239 -0
- aria_code/apps/cli/handlers/__init__.py +11 -0
- aria_code/apps/cli/handlers/broker_handlers.py +122 -0
- aria_code/apps/cli/handlers/chart_handlers.py +1314 -0
- aria_code/apps/cli/handlers/market_handlers.py +2570 -0
- aria_code/apps/cli/handlers/realty_handlers.py +114 -0
- aria_code/apps/cli/handlers/sports_handlers.py +22 -0
- aria_code/apps/cli/handlers/strategy_advice.py +82 -0
- aria_code/apps/cli/headless.py +352 -0
- aria_code/apps/cli/helpers.py +326 -0
- aria_code/apps/cli/hooks.py +180 -0
- aria_code/apps/cli/i18n.py +310 -0
- aria_code/apps/cli/intent.py +136 -0
- aria_code/apps/cli/intent_router.py +305 -0
- aria_code/apps/cli/intent_shadow.py +72 -0
- aria_code/apps/cli/intent_signals.py +347 -0
- aria_code/apps/cli/lifecycle_hooks.py +48 -0
- aria_code/apps/cli/local_tool_schemas.py +550 -0
- aria_code/apps/cli/main.py +39 -0
- aria_code/apps/cli/market_hours.py +100 -0
- aria_code/apps/cli/market_metadata.py +135 -0
- aria_code/apps/cli/market_universe.py +487 -0
- aria_code/apps/cli/message_processing.py +310 -0
- aria_code/apps/cli/mixin_binding.py +32 -0
- aria_code/apps/cli/model_catalog.py +652 -0
- aria_code/apps/cli/model_probe.py +169 -0
- aria_code/apps/cli/model_retirement.py +65 -0
- aria_code/apps/cli/native_branding.py +12 -0
- aria_code/apps/cli/native_bridge.py +118 -0
- aria_code/apps/cli/native_entry.py +58 -0
- aria_code/apps/cli/pdf_report.py +977 -0
- aria_code/apps/cli/plan_mode.py +139 -0
- aria_code/apps/cli/plotly_html.py +15 -0
- aria_code/apps/cli/prediction_feedback.py +202 -0
- aria_code/apps/cli/preflight.py +502 -0
- aria_code/apps/cli/project_aria.py +60 -0
- aria_code/apps/cli/prompt_assembly.py +78 -0
- aria_code/apps/cli/prompts/__init__.py +0 -0
- aria_code/apps/cli/prompts/coding.py +71 -0
- aria_code/apps/cli/prompts/select.py +193 -0
- aria_code/apps/cli/prompts/system_prompts.py +562 -0
- aria_code/apps/cli/prompts/ui.py +436 -0
- aria_code/apps/cli/provider_endpoints.py +237 -0
- aria_code/apps/cli/provider_keys.py +73 -0
- aria_code/apps/cli/providers/__init__.py +1 -0
- aria_code/apps/cli/providers/base.py +775 -0
- aria_code/apps/cli/providers/chat_routing.py +139 -0
- aria_code/apps/cli/providers/collaboration.py +98 -0
- aria_code/apps/cli/providers/llm/__init__.py +1 -0
- aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
- aria_code/apps/cli/providers/llm/ollama_stream.py +1574 -0
- aria_code/apps/cli/providers/llm/response_cache.py +60 -0
- aria_code/apps/cli/providers/llm/sse_stream.py +298 -0
- aria_code/apps/cli/providers/runtime_bridge.py +586 -0
- aria_code/apps/cli/providers/vertexai_stream.py +592 -0
- aria_code/apps/cli/release_download.py +159 -0
- aria_code/apps/cli/review_runner.py +111 -0
- aria_code/apps/cli/runtime_consumer.py +769 -0
- aria_code/apps/cli/sandbox.py +32 -0
- aria_code/apps/cli/session_export.py +120 -0
- aria_code/apps/cli/session_jsonl.py +208 -0
- aria_code/apps/cli/session_refresh.py +123 -0
- aria_code/apps/cli/session_store.py +125 -0
- aria_code/apps/cli/skills_catalog.py +273 -0
- aria_code/apps/cli/task_isolation.py +211 -0
- aria_code/apps/cli/terminal_chrome.py +412 -0
- aria_code/apps/cli/todo_tracker.py +190 -0
- aria_code/apps/cli/tool_executor.py +932 -0
- aria_code/apps/cli/tool_registry.py +34 -0
- aria_code/apps/cli/tool_scope.py +113 -0
- aria_code/apps/cli/tools/__init__.py +40 -0
- aria_code/apps/cli/tools/context.py +46 -0
- aria_code/apps/cli/tools/file_tools.py +181 -0
- aria_code/apps/cli/tools/market_tools.py +626 -0
- aria_code/apps/cli/tools/notebook_tools.py +111 -0
- aria_code/apps/cli/tools/system_tools.py +656 -0
- aria_code/apps/cli/tools/write_tools.py +961 -0
- aria_code/apps/cli/tradingview_bridge.py +529 -0
- aria_code/apps/cli/transactions.py +269 -0
- aria_code/apps/cli/turn_planning.py +137 -0
- aria_code/apps/cli/update_check.py +257 -0
- aria_code/apps/cli/updater.py +373 -0
- aria_code/apps/cli/utils/__init__.py +0 -0
- aria_code/apps/cli/utils/market_detect.py +1663 -0
- aria_code/apps/cli/web_login.py +136 -0
- aria_code/apps/cli/workflow_runner.py +127 -0
- aria_code/apps/cli/workspace_route.py +121 -0
- aria_code/apps/daemon/README.md +14 -0
- aria_code/apps/vscode/README.md +115 -0
- aria_code/apps/vscode/package.json +70 -0
- aria_code/aria_cli.py +5244 -0
- aria_code/aria_daemon.py +1372 -0
- aria_code/aria_feishu_bot.py +16 -0
- aria_code/aria_mcp_server.py +61 -0
- aria_code/aria_relay_client.py +4 -0
- aria_code/aria_telegram_bot.py +11 -0
- aria_code/ariarc.py +385 -0
- aria_code/artifacts.py +581 -0
- aria_code/backtest_engine.py +4 -0
- aria_code/backtest_report.py +4 -0
- aria_code/brokers/__init__.py +78 -0
- aria_code/brokers/automation.py +193 -0
- aria_code/brokers/base.py +231 -0
- aria_code/brokers/capabilities.py +264 -0
- aria_code/brokers/cn/__init__.py +10 -0
- aria_code/brokers/cn/easytrader_broker.py +193 -0
- aria_code/brokers/cn/futu_broker.py +194 -0
- aria_code/brokers/cn/longbridge_broker.py +190 -0
- aria_code/brokers/cn/tiger_broker.py +196 -0
- aria_code/brokers/cn/xtquant_broker.py +225 -0
- aria_code/brokers/config.py +414 -0
- aria_code/brokers/intl/__init__.py +5 -0
- aria_code/brokers/intl/alpaca_broker.py +183 -0
- aria_code/brokers/intl/ibkr_broker.py +215 -0
- aria_code/brokers/intl/trading212_broker.py +183 -0
- aria_code/brokers/intl/webull_broker.py +156 -0
- aria_code/brokers/paper_broker.py +266 -0
- aria_code/brokers/planning.py +296 -0
- aria_code/brokers/registry.py +213 -0
- aria_code/brokers/trading.py +267 -0
- aria_code/canva_client.py +4 -0
- aria_code/change_store.py +127 -0
- aria_code/clients/__init__.py +0 -0
- aria_code/clients/aliyun_data_client.py +660 -0
- aria_code/clients/aria_relay_client.py +16 -0
- aria_code/clients/canva_client.py +284 -0
- aria_code/clients/figma_client.py +100 -0
- aria_code/clients/football_data_client.py +1671 -0
- aria_code/clients/kling_video_client.py +182 -0
- aria_code/clients/market_data_client.py +1985 -0
- aria_code/clients/openai_image_client.py +242 -0
- aria_code/clients/runway_video_client.py +157 -0
- aria_code/clients/warehouse_erp_client.py +105 -0
- aria_code/cloud_memory.py +190 -0
- aria_code/command_safety.py +19 -0
- aria_code/computer_use_server.py +276 -0
- aria_code/computer_use_tools.py +4 -0
- aria_code/dashboard_generator.py +579 -0
- aria_code/data_analysis_tools.py +4 -0
- aria_code/data_cleaner.py +483 -0
- aria_code/data_service.py +513 -0
- aria_code/datasources/__init__.py +23 -0
- aria_code/datasources/base.py +166 -0
- aria_code/datasources/router.py +253 -0
- aria_code/datasources/sec_statements.py +217 -0
- aria_code/datasources/sources/__init__.py +15 -0
- aria_code/datasources/sources/akshare_source.py +269 -0
- aria_code/datasources/sources/alpha_vantage_source.py +203 -0
- aria_code/datasources/sources/edgar_source.py +219 -0
- aria_code/datasources/sources/finnhub_source.py +198 -0
- aria_code/datasources/sources/fred_source.py +223 -0
- aria_code/datasources/sources/tushare_source.py +143 -0
- aria_code/datasources/sources/web_scraper_source.py +278 -0
- aria_code/datasources/sources/world_bank_source.py +206 -0
- aria_code/datasources/sources/yfinance_source.py +152 -0
- aria_code/doctor.py +860 -0
- aria_code/domain/__init__.py +0 -0
- aria_code/domain/_finance_core/__init__.py +5 -0
- aria_code/domain/_finance_core/backtest_engine.py +325 -0
- aria_code/domain/_finance_core/performance_stats.py +101 -0
- aria_code/domain/backtest_engine.py +75 -0
- aria_code/domain/backtest_report.py +488 -0
- aria_code/domain/finance_formulas.py +389 -0
- aria_code/domain/performance_stats.py +6 -0
- aria_code/domain/portfolio_ledger.py +307 -0
- aria_code/domain/strategy_vault.py +421 -0
- aria_code/evals/__init__.py +37 -0
- aria_code/evals/behavior.py +113 -0
- aria_code/evals/gap.py +93 -0
- aria_code/evals/harness.py +949 -0
- aria_code/evals/review_probe.py +132 -0
- aria_code/evals/runner.py +425 -0
- aria_code/evals/scorecard.py +322 -0
- aria_code/evals/summary.py +125 -0
- aria_code/external_agent_runner.py +115 -0
- aria_code/figma_client.py +4 -0
- aria_code/file_analysis_tools.py +4 -0
- aria_code/finance_formulas.py +4 -0
- aria_code/football_data_client.py +4 -0
- aria_code/image_gen_tools.py +4 -0
- aria_code/intent_classifier.py +459 -0
- aria_code/kling_video_client.py +4 -0
- aria_code/licensing.py +151 -0
- aria_code/local_finance_tools.py +4 -0
- aria_code/local_image_provider.py +4 -0
- aria_code/local_llm_provider.py +4 -0
- aria_code/macro_tools.py +4 -0
- aria_code/markdown_pdf.py +289 -0
- aria_code/market_data_client.py +4 -0
- aria_code/mcp_client.py +744 -0
- aria_code/memory_manager.py +273 -0
- aria_code/model_capability.py +512 -0
- aria_code/notification_tools.py +4 -0
- aria_code/openai_image_client.py +4 -0
- aria_code/packages/__init__.py +26 -0
- aria_code/packages/adk_bridge/__init__.py +11 -0
- aria_code/packages/adk_bridge/code_review_tools.py +49 -0
- aria_code/packages/adk_bridge/market_tools.py +125 -0
- aria_code/packages/aria_agents/__init__.py +5 -0
- aria_code/packages/aria_agents/manifest.py +78 -0
- aria_code/packages/aria_core/__init__.py +34 -0
- aria_code/packages/aria_core/architecture.py +269 -0
- aria_code/packages/aria_core/export.py +147 -0
- aria_code/packages/aria_core/manifest.py +65 -0
- aria_code/packages/aria_core/paths.py +57 -0
- aria_code/packages/aria_core/secure_file.py +68 -0
- aria_code/packages/aria_infra/__init__.py +15 -0
- aria_code/packages/aria_infra/arthera.py +58 -0
- aria_code/packages/aria_infra/doctor.py +246 -0
- aria_code/packages/aria_infra/product.py +40 -0
- aria_code/packages/aria_mcp/__init__.py +25 -0
- aria_code/packages/aria_mcp/bridge.py +232 -0
- aria_code/packages/aria_mcp/circuit.py +82 -0
- aria_code/packages/aria_mcp/config.py +162 -0
- aria_code/packages/aria_mcp/installer.py +95 -0
- aria_code/packages/aria_mcp/server.py +1705 -0
- aria_code/packages/aria_mcp/tools.py +81 -0
- aria_code/packages/aria_sdk/__init__.py +19 -0
- aria_code/packages/aria_sdk/client.py +393 -0
- aria_code/packages/aria_sdk/providers.py +70 -0
- aria_code/packages/aria_sdk/streaming.py +75 -0
- aria_code/packages/aria_sdk/types.py +86 -0
- aria_code/packages/aria_services/__init__.py +92 -0
- aria_code/packages/aria_services/cache.py +60 -0
- aria_code/packages/aria_services/context.py +356 -0
- aria_code/packages/aria_services/context_checkpoints.py +157 -0
- aria_code/packages/aria_services/data.py +11 -0
- aria_code/packages/aria_services/provider_health.py +304 -0
- aria_code/packages/aria_services/references.py +247 -0
- aria_code/packages/aria_services/registry.py +249 -0
- aria_code/packages/aria_services/research_protocol.py +137 -0
- aria_code/packages/aria_services/research_quality.py +186 -0
- aria_code/packages/aria_services/settings.py +160 -0
- aria_code/packages/aria_services/usage.py +151 -0
- aria_code/packages/aria_skills/__init__.py +46 -0
- aria_code/packages/aria_skills/catalog.py +149 -0
- aria_code/packages/aria_skills/loader.py +455 -0
- aria_code/packages/aria_skills/registry.py +84 -0
- aria_code/packages/aria_tools/__init__.py +5 -0
- aria_code/packages/aria_tools/financial/__init__.py +5 -0
- aria_code/packages/aria_tools/financial/_paths.py +92 -0
- aria_code/packages/aria_tools/registry.py +129 -0
- aria_code/packages/quant_engine/__init__.py +33 -0
- aria_code/packages/quant_engine/_namespace.py +24 -0
- aria_code/packages/quant_engine/backtest/__init__.py +10 -0
- aria_code/packages/quant_engine/backtest/core.py +53 -0
- aria_code/packages/quant_engine/backtest/engine.py +102 -0
- aria_code/packages/quant_engine/portfolio/__init__.py +9 -0
- aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
- aria_code/packages/quant_engine/sports/__init__.py +76 -0
- aria_code/packages/quant_engine/sports/calibrator.py +354 -0
- aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
- aria_code/packages/quant_engine/sports/elo.py +300 -0
- aria_code/packages/quant_engine/sports/form.py +188 -0
- aria_code/packages/quant_engine/sports/h2h.py +195 -0
- aria_code/packages/quant_engine/sports/predictor.py +312 -0
- aria_code/packages/quant_engine/sports/tracker.py +665 -0
- aria_code/packages/quant_engine/stochastic/__init__.py +31 -0
- aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
- aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
- aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
- aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
- aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
- aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
- aria_code/packs/__init__.py +85 -0
- aria_code/packs/base.py +168 -0
- aria_code/packs/finance/__init__.py +250 -0
- aria_code/packs/healthcare/__init__.py +40 -0
- aria_code/packs/logistics/__init__.py +171 -0
- aria_code/packs/payments/__init__.py +139 -0
- aria_code/packs/realty/__init__.py +190 -0
- aria_code/packs/registry.py +202 -0
- aria_code/packs/rules.py +90 -0
- aria_code/plan_utils.py +194 -0
- aria_code/plugin_loader.py +328 -0
- aria_code/portfolio_ledger.py +4 -0
- aria_code/preview_server.py +449 -0
- aria_code/privacy/__init__.py +5 -0
- aria_code/privacy/feedback.py +123 -0
- aria_code/project_review.py +278 -0
- aria_code/project_review_api.py +235 -0
- aria_code/project_review_server.py +18 -0
- aria_code/project_tools.py +4 -0
- aria_code/providers/__init__.py +30 -0
- aria_code/providers/google_video_provider.py +256 -0
- aria_code/providers/llm/__init__.py +19 -0
- aria_code/providers/llm/anthropic.py +184 -0
- aria_code/providers/llm/arthera_gateway.py +90 -0
- aria_code/providers/llm/autoconfig.py +213 -0
- aria_code/providers/llm/base.py +139 -0
- aria_code/providers/llm/custom.py +158 -0
- aria_code/providers/llm/ollama.py +137 -0
- aria_code/providers/llm/openai_compat.py +350 -0
- aria_code/providers/llm/registry.py +457 -0
- aria_code/providers/local_image_provider.py +202 -0
- aria_code/providers/local_llm_provider.py +549 -0
- aria_code/providers/ollama_models.py +79 -0
- aria_code/providers/openai_params.py +32 -0
- aria_code/providers/tool_messages.py +100 -0
- aria_code/realty_data_tools.py +4 -0
- aria_code/report_exporters.py +150 -0
- aria_code/report_generator.py +1764 -0
- aria_code/review_service.py +497 -0
- aria_code/runtime/__init__.py +176 -0
- aria_code/runtime/acceptance.py +632 -0
- aria_code/runtime/agent_loop.py +1851 -0
- aria_code/runtime/agent_profiles.py +75 -0
- aria_code/runtime/approval.py +71 -0
- aria_code/runtime/baseline.py +219 -0
- aria_code/runtime/budget.py +232 -0
- aria_code/runtime/checkpoints.py +481 -0
- aria_code/runtime/consult.py +65 -0
- aria_code/runtime/contract.py +282 -0
- aria_code/runtime/delivery.py +432 -0
- aria_code/runtime/events.py +113 -0
- aria_code/runtime/gateway.py +167 -0
- aria_code/runtime/lsp.py +484 -0
- aria_code/runtime/native_index.py +153 -0
- aria_code/runtime/orchestrator.py +55 -0
- aria_code/runtime/processes.py +343 -0
- aria_code/runtime/project_graph.py +614 -0
- aria_code/runtime/repo_map.py +712 -0
- aria_code/runtime/research_bundle.py +105 -0
- aria_code/runtime/review.py +269 -0
- aria_code/runtime/run_state.py +127 -0
- aria_code/runtime/run_store.py +522 -0
- aria_code/runtime/scoped_runs.py +113 -0
- aria_code/runtime/self_healing.py +422 -0
- aria_code/runtime/semantic_diff.py +171 -0
- aria_code/runtime/subagent.py +721 -0
- aria_code/runtime/symbol_edit.py +117 -0
- aria_code/runtime/task_brief.py +46 -0
- aria_code/runtime/task_context.py +145 -0
- aria_code/runtime/task_ledger.py +108 -0
- aria_code/runtime/task_orchestrator.py +90 -0
- aria_code/runtime/task_outcome.py +33 -0
- aria_code/runtime/task_verification.py +266 -0
- aria_code/runtime/task_worktree.py +448 -0
- aria_code/runtime/tool_executor.py +329 -0
- aria_code/runtime/tool_policy.py +107 -0
- aria_code/runtime/transactions.py +216 -0
- aria_code/runtime/windows_job.py +115 -0
- aria_code/runtime/workflows.py +222 -0
- aria_code/runtime/worktrees.py +215 -0
- aria_code/runway_video_client.py +4 -0
- aria_code/safety/__init__.py +27 -0
- aria_code/safety/client_isolation.py +178 -0
- aria_code/safety/permissions.py +339 -0
- aria_code/safety/risk.py +699 -0
- aria_code/safety/sandbox.py +148 -0
- aria_code/safety/service.py +102 -0
- aria_code/service_endpoints.py +14 -0
- aria_code/setup_wizard.py +684 -0
- aria_code/spreadsheet_tools.py +4 -0
- aria_code/strategy_vault.py +4 -0
- aria_code/tools/__init__.py +0 -0
- aria_code/tools/artifact_tools.py +252 -0
- aria_code/tools/broker_tools.py +92 -0
- aria_code/tools/build_quant_engine.py +97 -0
- aria_code/tools/code_audit_tools.py +192 -0
- aria_code/tools/computer_use_tools.py +509 -0
- aria_code/tools/data_analysis_tools.py +831 -0
- aria_code/tools/enterprise_finance_tools.py +202 -0
- aria_code/tools/extended_tools.py +240 -0
- aria_code/tools/file_analysis_tools.py +880 -0
- aria_code/tools/image_gen_tools.py +114 -0
- aria_code/tools/local_finance_tools.py +3488 -0
- aria_code/tools/logistics_carriers.py +11 -0
- aria_code/tools/logistics_inventory.py +11 -0
- aria_code/tools/logistics_io.py +11 -0
- aria_code/tools/logistics_tenancy.py +11 -0
- aria_code/tools/logistics_tools.py +11 -0
- aria_code/tools/macro_tools.py +412 -0
- aria_code/tools/notification_tools.py +249 -0
- aria_code/tools/project_tools.py +525 -0
- aria_code/tools/realty_data_tools.py +662 -0
- aria_code/tools/spreadsheet_tools.py +399 -0
- aria_code/tools/stripe_tools.py +115 -0
- aria_code/tools/video_tools.py +500 -0
- aria_code/training/__init__.py +1 -0
- aria_code/training/compare.py +117 -0
- aria_code/training/prelude_commands.py +111 -0
- aria_code/training/prelude_eval.py +390 -0
- aria_code/training/prelude_real.py +183 -0
- aria_code/training/prelude_train.py +248 -0
- aria_code/training/sft_dataset.py +230 -0
- aria_code/training/trajectory_dataset.py +263 -0
- aria_code/ui/__init__.py +105 -0
- aria_code/ui/banner.py +404 -0
- aria_code/ui/completer.py +571 -0
- aria_code/ui/console.py +285 -0
- aria_code/ui/input_box.py +505 -0
- aria_code/ui/mentions.py +206 -0
- aria_code/ui/picker.py +248 -0
- aria_code/ui/render/__init__.py +11 -0
- aria_code/ui/render/actions.py +297 -0
- aria_code/ui/render/finance.py +1732 -0
- aria_code/ui/render/market.py +253 -0
- aria_code/ui/render/output.py +954 -0
- aria_code/ui/render/responsive.py +75 -0
- aria_code/ui/render/team.py +367 -0
- aria_code/ui/robot.py +239 -0
- aria_code/ui/startup_dashboard.py +110 -0
- aria_code/video_analysis.py +147 -0
- aria_code/video_editor.py +518 -0
- aria_code/video_workflow/__init__.py +8 -0
- aria_code/video_workflow/__main__.py +61 -0
- aria_code/video_workflow/engines/__init__.py +18 -0
- aria_code/video_workflow/engines/base.py +69 -0
- aria_code/video_workflow/engines/custom_model.py +204 -0
- aria_code/video_workflow/engines/google_veo.py +94 -0
- aria_code/video_workflow/engines/local_engine.py +71 -0
- aria_code/video_workflow/engines/registry.py +98 -0
- aria_code/video_workflow/google_models.py +278 -0
- aria_code/video_workflow/music/__init__.py +5 -0
- aria_code/video_workflow/music/foley_service.py +132 -0
- aria_code/video_workflow/music/service.py +212 -0
- aria_code/video_workflow/pipeline.py +620 -0
- aria_code/video_workflow/plan.py +202 -0
- aria_code/video_workflow/session.py +297 -0
- aria_code/workspace/__init__.py +6 -0
- aria_code/workspace/files.py +219 -0
- aria_code/workspace/verify.py +167 -0
- aria_code/workspace_changes.py +199 -0
- aria_code/workspace_service.py +196 -0
- aria_code/workspace_tools.py +150 -0
- aria_code-0.167.0.dist-info/METADATA +330 -0
- aria_code-0.167.0.dist-info/RECORD +601 -0
- aria_code-0.167.0.dist-info/WHEEL +5 -0
- aria_code-0.167.0.dist-info/entry_points.txt +5 -0
- aria_code-0.167.0.dist-info/licenses/LICENSE +201 -0
- aria_code-0.167.0.dist-info/licenses/NOTICE +49 -0
- aria_code-0.167.0.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"""Safe installation helpers for GitHub-hosted portable skill catalogs."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
import os
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
import re
|
|
9
|
+
import shutil
|
|
10
|
+
import subprocess
|
|
11
|
+
from typing import Callable, Sequence
|
|
12
|
+
|
|
13
|
+
from .loader import LoadedSkill, discover_external_skills
|
|
14
|
+
from aria_code.packages.aria_core.paths import aria_home
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
_REPOSITORY_RE = re.compile(r"^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$")
|
|
18
|
+
_REF_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._/-]{0,127}$")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass(frozen=True)
|
|
22
|
+
class CatalogSource:
|
|
23
|
+
owner: str
|
|
24
|
+
repository: str
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def full_name(self) -> str:
|
|
28
|
+
return f"{self.owner}/{self.repository}"
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def clone_url(self) -> str:
|
|
32
|
+
return f"https://github.com/{self.full_name}.git"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass(frozen=True)
|
|
36
|
+
class CatalogInstallResult:
|
|
37
|
+
source: CatalogSource
|
|
38
|
+
destination: Path
|
|
39
|
+
revision: str
|
|
40
|
+
skills: tuple[LoadedSkill, ...]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def parse_catalog_source(value: str) -> CatalogSource:
|
|
44
|
+
text = str(value or "").strip()
|
|
45
|
+
for prefix in ("https://github.com/", "http://github.com/"):
|
|
46
|
+
if text.startswith(prefix):
|
|
47
|
+
text = text[len(prefix) :]
|
|
48
|
+
break
|
|
49
|
+
text = text.removesuffix(".git").strip("/")
|
|
50
|
+
if not _REPOSITORY_RE.fullmatch(text):
|
|
51
|
+
raise ValueError("catalog must be a GitHub owner/repository path")
|
|
52
|
+
owner, repository = text.split("/", 1)
|
|
53
|
+
if owner in {".", ".."} or repository in {".", ".."}:
|
|
54
|
+
raise ValueError("catalog path traversal is not allowed")
|
|
55
|
+
return CatalogSource(owner=owner, repository=repository)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def default_catalog_home() -> Path:
|
|
59
|
+
configured = os.getenv("ARIA_SKILL_CATALOG_HOME", "")
|
|
60
|
+
if configured:
|
|
61
|
+
return Path(configured).expanduser().resolve()
|
|
62
|
+
return (aria_home() / "skill-catalogs").resolve()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def catalog_clone_command(
|
|
66
|
+
source: CatalogSource,
|
|
67
|
+
destination: Path,
|
|
68
|
+
ref: str = "",
|
|
69
|
+
) -> list[str]:
|
|
70
|
+
if ref and not _REF_RE.fullmatch(ref):
|
|
71
|
+
raise ValueError("invalid catalog ref")
|
|
72
|
+
command = ["git", "clone", "--depth", "1", "--filter=blob:none"]
|
|
73
|
+
command.extend([source.clone_url, str(destination)])
|
|
74
|
+
return command
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def install_catalog(
|
|
78
|
+
source_value: str,
|
|
79
|
+
*,
|
|
80
|
+
ref: str = "",
|
|
81
|
+
catalog_home: Path | None = None,
|
|
82
|
+
runner: Callable[..., subprocess.CompletedProcess] = subprocess.run,
|
|
83
|
+
) -> CatalogInstallResult:
|
|
84
|
+
source = parse_catalog_source(source_value)
|
|
85
|
+
home = (catalog_home or default_catalog_home()).expanduser().resolve()
|
|
86
|
+
destination = home / source.owner / source.repository
|
|
87
|
+
if destination.exists():
|
|
88
|
+
raise FileExistsError(
|
|
89
|
+
f"catalog already installed at {destination}; remove or update it explicitly"
|
|
90
|
+
)
|
|
91
|
+
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
92
|
+
command = catalog_clone_command(source, destination, ref)
|
|
93
|
+
try:
|
|
94
|
+
runner(
|
|
95
|
+
command,
|
|
96
|
+
check=True,
|
|
97
|
+
capture_output=True,
|
|
98
|
+
text=True,
|
|
99
|
+
timeout=120,
|
|
100
|
+
)
|
|
101
|
+
if ref:
|
|
102
|
+
runner(
|
|
103
|
+
["git", "fetch", "--depth", "1", "origin", ref],
|
|
104
|
+
cwd=destination,
|
|
105
|
+
check=True,
|
|
106
|
+
capture_output=True,
|
|
107
|
+
text=True,
|
|
108
|
+
timeout=120,
|
|
109
|
+
)
|
|
110
|
+
runner(
|
|
111
|
+
["git", "checkout", "--detach", "FETCH_HEAD"],
|
|
112
|
+
cwd=destination,
|
|
113
|
+
check=True,
|
|
114
|
+
capture_output=True,
|
|
115
|
+
text=True,
|
|
116
|
+
timeout=30,
|
|
117
|
+
)
|
|
118
|
+
skills_root = destination / "skills"
|
|
119
|
+
skills = discover_external_skills([skills_root])
|
|
120
|
+
if not skills:
|
|
121
|
+
raise ValueError("catalog contains no discoverable SKILL.md entries")
|
|
122
|
+
invalid = [
|
|
123
|
+
skill.qualified_name for skill in skills
|
|
124
|
+
if skill.integrity != "verified"
|
|
125
|
+
]
|
|
126
|
+
if invalid:
|
|
127
|
+
raise ValueError(
|
|
128
|
+
"catalog integrity verification failed for: " + ", ".join(invalid)
|
|
129
|
+
)
|
|
130
|
+
revision_result = runner(
|
|
131
|
+
["git", "rev-parse", "HEAD"],
|
|
132
|
+
cwd=destination,
|
|
133
|
+
check=True,
|
|
134
|
+
capture_output=True,
|
|
135
|
+
text=True,
|
|
136
|
+
timeout=15,
|
|
137
|
+
)
|
|
138
|
+
except Exception:
|
|
139
|
+
# The destination did not exist before this call, so it is safe to
|
|
140
|
+
# remove a partial clone or a catalog that failed verification.
|
|
141
|
+
if destination.exists():
|
|
142
|
+
shutil.rmtree(destination)
|
|
143
|
+
raise
|
|
144
|
+
return CatalogInstallResult(
|
|
145
|
+
source=source,
|
|
146
|
+
destination=destination,
|
|
147
|
+
revision=str(revision_result.stdout or "").strip(),
|
|
148
|
+
skills=tuple(skills),
|
|
149
|
+
)
|
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
"""Discover, verify, match, and activate portable SKILL.md workflows."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections import deque
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
|
+
from datetime import datetime, timezone
|
|
8
|
+
import hashlib
|
|
9
|
+
import json
|
|
10
|
+
import os
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
import re
|
|
13
|
+
from typing import Iterable, Sequence
|
|
14
|
+
from aria_code.packages.aria_core.paths import aria_home
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
#: Basic file I/O and deliverable-export tools that stay available no matter
|
|
18
|
+
#: which skill is active or what its `allowed_tools` policy declares.
|
|
19
|
+
#:
|
|
20
|
+
#: Why: a skill's allowed_tools is a *domain* policy (which market-data/
|
|
21
|
+
#: research tools may run), not a statement about whether the model may read
|
|
22
|
+
#: or write files. Observed failure: the "equity-research-report" skill's
|
|
23
|
+
#: policy listed only research tools; matched on the CJK term "报告" against
|
|
24
|
+
#: a user request to convert an *existing* file to PDF; once activated it
|
|
25
|
+
#: silently stripped read_file/write_file from the tool schema, and the model
|
|
26
|
+
#: could only reply "please paste the file contents" — it had no idea the
|
|
27
|
+
#: tool had been taken away. Keeping these core tools exempt means a
|
|
28
|
+
#: mismatched skill activation degrades to "runs extra irrelevant workflow
|
|
29
|
+
#: steps" instead of "loses the ability to read a file the user pointed to".
|
|
30
|
+
CORE_FILE_TOOLS: frozenset[str] = frozenset({
|
|
31
|
+
"read_file", "analyze_file", "write_file", "edit_file", "multi_edit",
|
|
32
|
+
"write_spreadsheet", "export_markdown_pdf",
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
_NAME_RE = re.compile(r"^[a-z0-9][a-z0-9-]{0,63}$")
|
|
36
|
+
_QUALIFIED_NAME_RE = re.compile(
|
|
37
|
+
r"^[a-z0-9][a-z0-9-]{0,63}:[a-z0-9][a-z0-9-]{0,63}$"
|
|
38
|
+
)
|
|
39
|
+
_MAX_SKILL_CHARS = 20_000
|
|
40
|
+
_ACTIVATION_HISTORY: deque["SkillActivationTrace"] = deque(maxlen=100)
|
|
41
|
+
_LATIN_STOP_WORDS = {
|
|
42
|
+
"about", "after", "also", "and", "any", "create", "does", "for", "from",
|
|
43
|
+
"into", "only", "report", "request", "skill", "that", "the", "this", "use",
|
|
44
|
+
"user", "when", "with",
|
|
45
|
+
}
|
|
46
|
+
# CJK equivalents of the above. Without these, a Chinese request scores almost
|
|
47
|
+
# entirely on function words: "帮我设计一个牙科诊所的网站" once ranked
|
|
48
|
+
# `strategy-generation` (a trading-strategy skill) above `ui-asset-sourcing` on
|
|
49
|
+
# the strength of 一个/帮我/设计 alone, because Chinese has no spaces and the
|
|
50
|
+
# n-gram tokenizer below emits every 2-4 char window — so polite framing like
|
|
51
|
+
# 帮我 also produces 帮我设, 帮我设计, 我设, 我设计, multiplying a single
|
|
52
|
+
# meaningless phrase into several "matches".
|
|
53
|
+
_CJK_STOP_WORDS = {
|
|
54
|
+
"一个", "一下", "一些", "个", "什么", "可以", "如何", "帮我", "帮我做", "帮我设",
|
|
55
|
+
"帮忙", "我们", "我的", "我想", "我要", "我设", "我需要", "怎么", "怎样",
|
|
56
|
+
"应该", "开始", "我", "然后", "现在", "生成", "用我", "的", "目前", "看看",
|
|
57
|
+
"给我", "请求", "需要", "麻烦", "这个", "那个", "项目", "使用", "进行",
|
|
58
|
+
}
|
|
59
|
+
_IGNORED_TREE_NAMES = {".DS_Store", ".pytest_cache", "__pycache__"}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass(frozen=True)
|
|
63
|
+
class SkillPolicy:
|
|
64
|
+
allowed_tools: tuple[str, ...] = ()
|
|
65
|
+
permissions: tuple[str, ...] = ()
|
|
66
|
+
# Specialist agents this skill expects to orchestrate, by registry name.
|
|
67
|
+
# Mirrors SkillSpec.agents in ..registry, which has carried the same
|
|
68
|
+
# skill→agent relationship for the built-in specs all along; this makes the
|
|
69
|
+
# portable SKILL.md catalog able to express it too. Advisory only — the
|
|
70
|
+
# loader never imports the agent registry, because it must keep working in
|
|
71
|
+
# runtimes that have no agents at all.
|
|
72
|
+
agents: tuple[str, ...] = ()
|
|
73
|
+
script_execution: str = "approval"
|
|
74
|
+
script_network: bool = False
|
|
75
|
+
script_workspace_write: bool = False
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass(frozen=True)
|
|
79
|
+
class LoadedSkill:
|
|
80
|
+
name: str
|
|
81
|
+
description: str
|
|
82
|
+
instructions: str
|
|
83
|
+
path: Path
|
|
84
|
+
plugin_name: str = "local"
|
|
85
|
+
plugin_version: str = ""
|
|
86
|
+
repository: str = ""
|
|
87
|
+
content_sha256: str = ""
|
|
88
|
+
integrity: str = "unlocked"
|
|
89
|
+
policy: SkillPolicy = field(default_factory=SkillPolicy)
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def qualified_name(self) -> str:
|
|
93
|
+
return f"{self.plugin_name}:{self.name}"
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@dataclass(frozen=True)
|
|
97
|
+
class SkillActivationTrace:
|
|
98
|
+
qualified_name: str
|
|
99
|
+
activated: bool
|
|
100
|
+
reason: str
|
|
101
|
+
score: float
|
|
102
|
+
integrity: str
|
|
103
|
+
source: str
|
|
104
|
+
timestamp: str = field(
|
|
105
|
+
default_factory=lambda: datetime.now(timezone.utc).isoformat(timespec="seconds")
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
def to_dict(self) -> dict[str, object]:
|
|
109
|
+
return {
|
|
110
|
+
"qualified_name": self.qualified_name,
|
|
111
|
+
"activated": self.activated,
|
|
112
|
+
"reason": self.reason,
|
|
113
|
+
"score": self.score,
|
|
114
|
+
"integrity": self.integrity,
|
|
115
|
+
"source": self.source,
|
|
116
|
+
"timestamp": self.timestamp,
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@dataclass(frozen=True)
|
|
121
|
+
class SkillActivation:
|
|
122
|
+
skills: tuple[LoadedSkill, ...]
|
|
123
|
+
traces: tuple[SkillActivationTrace, ...]
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def prompt_block(self) -> str:
|
|
127
|
+
blocks: list[str] = []
|
|
128
|
+
for skill in self.skills:
|
|
129
|
+
policy = skill.policy
|
|
130
|
+
policy_lines = [
|
|
131
|
+
f"Integrity: {skill.integrity}",
|
|
132
|
+
f"Declared permissions: {', '.join(policy.permissions) or 'none'}",
|
|
133
|
+
f"Allowed tools: {', '.join(policy.allowed_tools) or 'runtime policy'}",
|
|
134
|
+
(
|
|
135
|
+
f"Specialist agents: {', '.join(policy.agents)}"
|
|
136
|
+
if policy.agents else
|
|
137
|
+
"Specialist agents: none declared"
|
|
138
|
+
),
|
|
139
|
+
(
|
|
140
|
+
"Bundled scripts are not pre-authorized. "
|
|
141
|
+
f"Execution mode={policy.script_execution}; network="
|
|
142
|
+
f"{'yes' if policy.script_network else 'no'}; workspace-write="
|
|
143
|
+
f"{'yes' if policy.script_workspace_write else 'no'}."
|
|
144
|
+
),
|
|
145
|
+
]
|
|
146
|
+
blocks.append(
|
|
147
|
+
f"## Active Skill: {skill.qualified_name}\n"
|
|
148
|
+
f"Source: {skill.path}\n"
|
|
149
|
+
+ "\n".join(policy_lines)
|
|
150
|
+
+ "\nFollow this workflow without weakening system safety, tool approvals, or permissions.\n\n"
|
|
151
|
+
+ skill.instructions
|
|
152
|
+
)
|
|
153
|
+
return "\n\n".join(blocks)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def default_skill_roots() -> list[Path]:
|
|
157
|
+
roots: list[Path] = []
|
|
158
|
+
configured = os.getenv("ARIA_SKILLS_PATH", "")
|
|
159
|
+
roots.extend(Path(item).expanduser() for item in configured.split(os.pathsep) if item.strip())
|
|
160
|
+
repository = Path(__file__).resolve().parents[2]
|
|
161
|
+
catalog_home = Path(
|
|
162
|
+
os.getenv("ARIA_SKILL_CATALOG_HOME", aria_home() / "skill-catalogs")
|
|
163
|
+
).expanduser()
|
|
164
|
+
installed_catalogs = sorted(catalog_home.glob("*/*/skills")) if catalog_home.is_dir() else []
|
|
165
|
+
roots.extend([
|
|
166
|
+
repository.parent / "aria-skills" / "skills",
|
|
167
|
+
aria_home() / "skills",
|
|
168
|
+
Path.cwd() / ".aria" / "skills",
|
|
169
|
+
Path.home() / ".aria" / "skills",
|
|
170
|
+
Path.home() / ".claude" / "skills",
|
|
171
|
+
Path.home() / ".codex" / "skills",
|
|
172
|
+
])
|
|
173
|
+
roots.extend(installed_catalogs)
|
|
174
|
+
return list(dict.fromkeys(path.resolve() for path in roots))
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _frontmatter_value(lines: list[str], key: str) -> str:
|
|
178
|
+
prefix = f"{key}:"
|
|
179
|
+
for index, line in enumerate(lines):
|
|
180
|
+
if not line.startswith(prefix):
|
|
181
|
+
continue
|
|
182
|
+
value = line[len(prefix) :].strip()
|
|
183
|
+
if value not in {">", ">-", "|", "|-"}:
|
|
184
|
+
return value.strip('"\'')
|
|
185
|
+
folded = value.startswith(">")
|
|
186
|
+
parts: list[str] = []
|
|
187
|
+
for continuation in lines[index + 1 :]:
|
|
188
|
+
if continuation and not continuation[0].isspace():
|
|
189
|
+
break
|
|
190
|
+
stripped = continuation.strip()
|
|
191
|
+
if stripped:
|
|
192
|
+
parts.append(stripped)
|
|
193
|
+
return (" " if folded else "\n").join(parts)
|
|
194
|
+
return ""
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def skill_tree_sha256(folder: Path) -> str:
|
|
198
|
+
digest = hashlib.sha256()
|
|
199
|
+
for path in sorted(item for item in folder.rglob("*") if item.is_file()):
|
|
200
|
+
relative = path.relative_to(folder)
|
|
201
|
+
if any(part in _IGNORED_TREE_NAMES for part in relative.parts) or path.suffix == ".pyc":
|
|
202
|
+
continue
|
|
203
|
+
digest.update(relative.as_posix().encode("utf-8"))
|
|
204
|
+
digest.update(b"\0")
|
|
205
|
+
digest.update(path.read_bytes())
|
|
206
|
+
digest.update(b"\0")
|
|
207
|
+
return digest.hexdigest()
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def _catalog_metadata(root: Path) -> tuple[dict[Path, dict[str, str]], dict[str, str]]:
|
|
211
|
+
catalog = root.parent if root.name == "skills" else root
|
|
212
|
+
manifest_path = catalog / ".claude-plugin" / "marketplace.json"
|
|
213
|
+
lock_path = catalog / ".claude-plugin" / "skills.lock.json"
|
|
214
|
+
mapping: dict[Path, dict[str, str]] = {}
|
|
215
|
+
locks: dict[str, str] = {}
|
|
216
|
+
try:
|
|
217
|
+
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
|
|
218
|
+
catalog_version = str((manifest.get("metadata") or {}).get("version") or "")
|
|
219
|
+
catalog_repository = str(
|
|
220
|
+
(manifest.get("metadata") or {}).get("repository")
|
|
221
|
+
or (manifest.get("owner") or {}).get("url")
|
|
222
|
+
or ""
|
|
223
|
+
)
|
|
224
|
+
for plugin in manifest.get("plugins") or []:
|
|
225
|
+
plugin_name = str(plugin.get("name") or "local")
|
|
226
|
+
plugin_version = str(plugin.get("version") or catalog_version)
|
|
227
|
+
repository = str(plugin.get("repository") or plugin.get("homepage") or catalog_repository)
|
|
228
|
+
for skill_path in plugin.get("skills") or []:
|
|
229
|
+
resolved = (catalog / str(skill_path)).resolve()
|
|
230
|
+
mapping[resolved] = {
|
|
231
|
+
"plugin_name": plugin_name,
|
|
232
|
+
"plugin_version": plugin_version,
|
|
233
|
+
"repository": repository,
|
|
234
|
+
}
|
|
235
|
+
except (OSError, json.JSONDecodeError, TypeError):
|
|
236
|
+
pass
|
|
237
|
+
try:
|
|
238
|
+
lock = json.loads(lock_path.read_text(encoding="utf-8"))
|
|
239
|
+
for qualified_name, entry in (lock.get("skills") or {}).items():
|
|
240
|
+
if isinstance(entry, dict) and entry.get("sha256"):
|
|
241
|
+
locks[str(qualified_name)] = str(entry["sha256"])
|
|
242
|
+
except (OSError, json.JSONDecodeError, TypeError):
|
|
243
|
+
pass
|
|
244
|
+
return mapping, locks
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def _load_policy(folder: Path) -> SkillPolicy:
|
|
248
|
+
try:
|
|
249
|
+
payload = json.loads((folder / "skill-policy.json").read_text(encoding="utf-8"))
|
|
250
|
+
except (OSError, json.JSONDecodeError, TypeError):
|
|
251
|
+
return SkillPolicy()
|
|
252
|
+
scripts = payload.get("scripts") or {}
|
|
253
|
+
return SkillPolicy(
|
|
254
|
+
allowed_tools=tuple(str(item) for item in payload.get("allowed_tools") or []),
|
|
255
|
+
permissions=tuple(str(item) for item in payload.get("permissions") or []),
|
|
256
|
+
agents=tuple(str(item) for item in payload.get("agents") or []),
|
|
257
|
+
script_execution=str(scripts.get("execution") or "approval"),
|
|
258
|
+
script_network=bool(scripts.get("network", False)),
|
|
259
|
+
script_workspace_write=bool(scripts.get("workspace_write", False)),
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def _parse_skill(
|
|
264
|
+
path: Path,
|
|
265
|
+
metadata: dict[str, str] | None = None,
|
|
266
|
+
locks: dict[str, str] | None = None,
|
|
267
|
+
) -> LoadedSkill | None:
|
|
268
|
+
try:
|
|
269
|
+
text = path.read_text(encoding="utf-8")
|
|
270
|
+
except OSError:
|
|
271
|
+
return None
|
|
272
|
+
if len(text) > _MAX_SKILL_CHARS or not text.startswith("---\n"):
|
|
273
|
+
return None
|
|
274
|
+
end = text.find("\n---\n", 4)
|
|
275
|
+
if end < 0:
|
|
276
|
+
return None
|
|
277
|
+
frontmatter = text[4:end].splitlines()
|
|
278
|
+
name = _frontmatter_value(frontmatter, "name")
|
|
279
|
+
description = _frontmatter_value(frontmatter, "description")
|
|
280
|
+
if not _NAME_RE.fullmatch(name) or not description:
|
|
281
|
+
return None
|
|
282
|
+
instructions = text[end + 5 :].strip()
|
|
283
|
+
if not instructions:
|
|
284
|
+
return None
|
|
285
|
+
metadata = metadata or {}
|
|
286
|
+
plugin_name = metadata.get("plugin_name") or "local"
|
|
287
|
+
if not _NAME_RE.fullmatch(plugin_name):
|
|
288
|
+
plugin_name = "local"
|
|
289
|
+
qualified_name = f"{plugin_name}:{name}"
|
|
290
|
+
content_sha256 = skill_tree_sha256(path.parent)
|
|
291
|
+
expected = (locks or {}).get(qualified_name)
|
|
292
|
+
integrity = "verified" if expected == content_sha256 else "mismatch" if expected else "unlocked"
|
|
293
|
+
return LoadedSkill(
|
|
294
|
+
name=name,
|
|
295
|
+
description=description,
|
|
296
|
+
instructions=instructions,
|
|
297
|
+
path=path,
|
|
298
|
+
plugin_name=plugin_name,
|
|
299
|
+
plugin_version=metadata.get("plugin_version", ""),
|
|
300
|
+
repository=metadata.get("repository", ""),
|
|
301
|
+
content_sha256=content_sha256,
|
|
302
|
+
integrity=integrity,
|
|
303
|
+
policy=_load_policy(path.parent),
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def discover_external_skills(roots: Sequence[Path] | None = None) -> list[LoadedSkill]:
|
|
308
|
+
found: dict[str, LoadedSkill] = {}
|
|
309
|
+
for raw_root in roots or default_skill_roots():
|
|
310
|
+
root = Path(raw_root).expanduser().resolve()
|
|
311
|
+
if not root.is_dir():
|
|
312
|
+
continue
|
|
313
|
+
mapping, locks = _catalog_metadata(root)
|
|
314
|
+
for candidate in sorted(root.glob("*/SKILL.md")):
|
|
315
|
+
loaded = _parse_skill(candidate, mapping.get(candidate.parent.resolve()), locks)
|
|
316
|
+
if loaded and loaded.qualified_name not in found:
|
|
317
|
+
found[loaded.qualified_name] = loaded
|
|
318
|
+
return list(found.values())
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def _requested_skill_names(message: str) -> set[str]:
|
|
322
|
+
return set(
|
|
323
|
+
re.findall(
|
|
324
|
+
r"\$([a-z0-9][a-z0-9-]{0,63}(?::[a-z0-9][a-z0-9-]{0,63})?)\b",
|
|
325
|
+
message.lower(),
|
|
326
|
+
)
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def _quoted_phrases(description: str) -> list[str]:
|
|
331
|
+
return [
|
|
332
|
+
next(group for group in match.groups() if group is not None).strip().lower()
|
|
333
|
+
for match in re.finditer(r'"([^"]+)"|“([^”]+)”|\'([^\']+)\'', description)
|
|
334
|
+
]
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def _terms(text: str) -> set[str]:
|
|
338
|
+
low = text.lower()
|
|
339
|
+
latin = {
|
|
340
|
+
token for token in re.findall(r"[a-z0-9][a-z0-9_-]{2,}", low)
|
|
341
|
+
if token not in _LATIN_STOP_WORDS
|
|
342
|
+
}
|
|
343
|
+
cjk: set[str] = set()
|
|
344
|
+
for chunk in re.findall(r"[\u3400-\u9fff]{2,}", low):
|
|
345
|
+
if len(chunk) <= 8:
|
|
346
|
+
cjk.add(chunk)
|
|
347
|
+
for size in (2, 3, 4):
|
|
348
|
+
cjk.update(chunk[index : index + size] for index in range(len(chunk) - size + 1))
|
|
349
|
+
cjk -= _CJK_STOP_WORDS
|
|
350
|
+
# An n-gram that merely *contains* a stop word is usually noise too:
|
|
351
|
+
# "\u5e2e\u6211\u8bbe\u8ba1" is \u5e2e\u6211 + \u8bbe\u8ba1 with no extra signal, yet it scores as its own
|
|
352
|
+
# distinct match. Drop windows that are a stop word plus at most one
|
|
353
|
+
# character, which is where that inflation comes from.
|
|
354
|
+
cjk = {
|
|
355
|
+
gram for gram in cjk
|
|
356
|
+
if not any(
|
|
357
|
+
stop in gram and len(gram) - len(stop) <= 1
|
|
358
|
+
for stop in _CJK_STOP_WORDS
|
|
359
|
+
)
|
|
360
|
+
}
|
|
361
|
+
return latin | cjk
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def _match_score(message: str, skill: LoadedSkill) -> tuple[float, str]:
|
|
365
|
+
low = message.lower()
|
|
366
|
+
for phrase in _quoted_phrases(skill.description):
|
|
367
|
+
if len(phrase) >= 2 and phrase in low:
|
|
368
|
+
return 20.0 + min(len(phrase), 20) / 10, f'description phrase "{phrase}"'
|
|
369
|
+
overlap = _terms(message) & _terms(skill.description)
|
|
370
|
+
if not overlap:
|
|
371
|
+
return 0.0, "no metadata overlap"
|
|
372
|
+
score = float(len(overlap))
|
|
373
|
+
if len(overlap) >= 2:
|
|
374
|
+
score += 2.0
|
|
375
|
+
return score, f"metadata overlap: {', '.join(sorted(overlap)[:6])}"
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
def activate_external_skills(
|
|
379
|
+
message: str,
|
|
380
|
+
skills: Iterable[LoadedSkill] | None = None,
|
|
381
|
+
max_skills: int = 2,
|
|
382
|
+
record: bool = True,
|
|
383
|
+
) -> SkillActivation:
|
|
384
|
+
available = list(skills if skills is not None else discover_external_skills())
|
|
385
|
+
requested = _requested_skill_names(message)
|
|
386
|
+
by_short_name: dict[str, list[LoadedSkill]] = {}
|
|
387
|
+
for skill in available:
|
|
388
|
+
by_short_name.setdefault(skill.name, []).append(skill)
|
|
389
|
+
|
|
390
|
+
candidates: list[tuple[float, str, LoadedSkill]] = []
|
|
391
|
+
traces: list[SkillActivationTrace] = []
|
|
392
|
+
for skill in available:
|
|
393
|
+
explicit_qualified = skill.qualified_name in requested
|
|
394
|
+
explicit_short = skill.name in requested and len(by_short_name[skill.name]) == 1
|
|
395
|
+
if explicit_qualified or explicit_short:
|
|
396
|
+
score, reason = 100.0, "explicit invocation"
|
|
397
|
+
else:
|
|
398
|
+
score, reason = _match_score(message, skill)
|
|
399
|
+
if score < 4.0:
|
|
400
|
+
continue
|
|
401
|
+
if skill.integrity == "mismatch":
|
|
402
|
+
traces.append(SkillActivationTrace(
|
|
403
|
+
qualified_name=skill.qualified_name,
|
|
404
|
+
activated=False,
|
|
405
|
+
reason="integrity mismatch",
|
|
406
|
+
score=score,
|
|
407
|
+
integrity=skill.integrity,
|
|
408
|
+
source=str(skill.path),
|
|
409
|
+
))
|
|
410
|
+
continue
|
|
411
|
+
if skill.integrity == "unlocked" and not (explicit_qualified or explicit_short):
|
|
412
|
+
traces.append(SkillActivationTrace(
|
|
413
|
+
qualified_name=skill.qualified_name,
|
|
414
|
+
activated=False,
|
|
415
|
+
reason="automatic activation requires an integrity lock",
|
|
416
|
+
score=score,
|
|
417
|
+
integrity=skill.integrity,
|
|
418
|
+
source=str(skill.path),
|
|
419
|
+
))
|
|
420
|
+
continue
|
|
421
|
+
candidates.append((score, reason, skill))
|
|
422
|
+
|
|
423
|
+
candidates.sort(key=lambda item: (-item[0], item[2].qualified_name))
|
|
424
|
+
selected = candidates[: max(1, max_skills)]
|
|
425
|
+
for score, reason, skill in selected:
|
|
426
|
+
traces.append(SkillActivationTrace(
|
|
427
|
+
qualified_name=skill.qualified_name,
|
|
428
|
+
activated=True,
|
|
429
|
+
reason=reason,
|
|
430
|
+
score=round(score, 2),
|
|
431
|
+
integrity=skill.integrity,
|
|
432
|
+
source=str(skill.path),
|
|
433
|
+
))
|
|
434
|
+
if record:
|
|
435
|
+
_ACTIVATION_HISTORY.extend(traces)
|
|
436
|
+
return SkillActivation(
|
|
437
|
+
skills=tuple(item[2] for item in selected),
|
|
438
|
+
traces=tuple(traces),
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def select_external_skills(
|
|
443
|
+
message: str,
|
|
444
|
+
skills: Iterable[LoadedSkill] | None = None,
|
|
445
|
+
) -> list[LoadedSkill]:
|
|
446
|
+
return list(activate_external_skills(message, skills).skills)
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
def build_skill_prompt_block(message: str) -> str:
|
|
450
|
+
return activate_external_skills(message).prompt_block
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
def recent_skill_activation_traces(limit: int = 20) -> list[SkillActivationTrace]:
|
|
454
|
+
bounded = max(1, min(int(limit), len(_ACTIVATION_HISTORY) or 1))
|
|
455
|
+
return list(_ACTIVATION_HISTORY)[-bounded:]
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""Skill manifests for model-facing workflows."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from typing import List
|
|
7
|
+
|
|
8
|
+
from aria_code.packages.aria_core import CapabilityManifest, PermissionLevel, ServiceKind
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(frozen=True)
|
|
12
|
+
class SkillSpec:
|
|
13
|
+
name: str
|
|
14
|
+
description: str
|
|
15
|
+
tools: List[str] = field(default_factory=list)
|
|
16
|
+
agents: List[str] = field(default_factory=list)
|
|
17
|
+
permissions: List[PermissionLevel] = field(default_factory=list)
|
|
18
|
+
|
|
19
|
+
def manifest(self) -> CapabilityManifest:
|
|
20
|
+
return CapabilityManifest(
|
|
21
|
+
name=self.name,
|
|
22
|
+
kind=ServiceKind.SKILL,
|
|
23
|
+
description=self.description,
|
|
24
|
+
capabilities=[f"tool:{name}" for name in self.tools] + [f"agent:{name}" for name in self.agents],
|
|
25
|
+
permissions=self.permissions,
|
|
26
|
+
required_services=self.tools + self.agents,
|
|
27
|
+
tags=["skill"],
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def builtin_skill_specs() -> List[SkillSpec]:
|
|
32
|
+
return [
|
|
33
|
+
SkillSpec(
|
|
34
|
+
name="financial-research",
|
|
35
|
+
description="Multi-source quote, fundamentals, technical analysis, and narrative report generation.",
|
|
36
|
+
tools=["get_market_data", "get_market_history", "get_risk_metrics", "analyze_news"],
|
|
37
|
+
agents=["technical", "fundamental", "macro", "risk", "synthesis"],
|
|
38
|
+
permissions=[PermissionLevel.NETWORK],
|
|
39
|
+
),
|
|
40
|
+
SkillSpec(
|
|
41
|
+
name="equity-research-report",
|
|
42
|
+
description=(
|
|
43
|
+
"Evidence-backed equity report workflow with specialist agents, "
|
|
44
|
+
"deterministic fallbacks, provenance, critique, and completion gates."
|
|
45
|
+
),
|
|
46
|
+
tools=[
|
|
47
|
+
"get_market_data",
|
|
48
|
+
"get_market_history",
|
|
49
|
+
"calculate_factors",
|
|
50
|
+
"get_risk_metrics",
|
|
51
|
+
"analyze_news",
|
|
52
|
+
],
|
|
53
|
+
agents=[
|
|
54
|
+
"technical",
|
|
55
|
+
"fundamental",
|
|
56
|
+
"macro",
|
|
57
|
+
"risk",
|
|
58
|
+
"news",
|
|
59
|
+
"catalyst",
|
|
60
|
+
"sector",
|
|
61
|
+
"synthesis",
|
|
62
|
+
],
|
|
63
|
+
permissions=[PermissionLevel.NETWORK, PermissionLevel.WORKSPACE_WRITE],
|
|
64
|
+
),
|
|
65
|
+
SkillSpec(
|
|
66
|
+
name="strategy-backtest",
|
|
67
|
+
description="Generate and validate trading strategies with historical simulation and artifacts.",
|
|
68
|
+
tools=["get_market_data"],
|
|
69
|
+
agents=["technical", "risk"],
|
|
70
|
+
permissions=[PermissionLevel.NETWORK, PermissionLevel.WORKSPACE_WRITE],
|
|
71
|
+
),
|
|
72
|
+
SkillSpec(
|
|
73
|
+
name="workspace-coding",
|
|
74
|
+
description="Read, edit, and verify local project files with explicit workspace permissions.",
|
|
75
|
+
tools=["read_file", "list_files", "search_code", "edit_file", "write_file", "run_command"],
|
|
76
|
+
permissions=[PermissionLevel.READ_ONLY, PermissionLevel.WORKSPACE_WRITE],
|
|
77
|
+
),
|
|
78
|
+
SkillSpec(
|
|
79
|
+
name="broker-portfolio",
|
|
80
|
+
description="Read broker account state and propose guarded orders with user approval.",
|
|
81
|
+
tools=["broker_query", "broker_order"],
|
|
82
|
+
permissions=[PermissionLevel.BROKER_READ, PermissionLevel.BROKER_TRADE],
|
|
83
|
+
),
|
|
84
|
+
]
|