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,202 @@
|
|
|
1
|
+
"""Corporate financial metrics from actual, period-aligned statements."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import math
|
|
5
|
+
import time
|
|
6
|
+
from typing import Any, Dict, List
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _number(data: dict, key: str) -> float | None:
|
|
10
|
+
value = data.get(key)
|
|
11
|
+
if value is None:
|
|
12
|
+
return None
|
|
13
|
+
if isinstance(value, bool):
|
|
14
|
+
raise ValueError(f"{key} must be a finite number")
|
|
15
|
+
try:
|
|
16
|
+
value = float(value)
|
|
17
|
+
except (TypeError, ValueError, OverflowError) as exc:
|
|
18
|
+
raise ValueError(f"{key} must be a finite number") from exc
|
|
19
|
+
if not math.isfinite(value):
|
|
20
|
+
raise ValueError(f"{key} must be a finite number")
|
|
21
|
+
return value
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _ratio(numerator, denominator, scale=1):
|
|
25
|
+
if numerator is None or denominator is None or denominator == 0:
|
|
26
|
+
return None
|
|
27
|
+
value = numerator / denominator * scale
|
|
28
|
+
return round(value, 2) if math.isfinite(value) else None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def compute_financial_metrics(income: dict, balance: dict, cashflow: dict) -> dict:
|
|
32
|
+
"""Missing inputs stay unknown; zero denominators never become one."""
|
|
33
|
+
revenue = _number(income, "revenue")
|
|
34
|
+
net_income = _number(income, "net_income")
|
|
35
|
+
assets = _number(balance, "total_assets")
|
|
36
|
+
equity = _number(balance, "total_equity")
|
|
37
|
+
current_assets = _number(balance, "current_assets")
|
|
38
|
+
current_liabilities = _number(balance, "current_liabilities")
|
|
39
|
+
inventory = _number(balance, "inventory")
|
|
40
|
+
quick_assets = None if current_assets is None or inventory is None else current_assets - inventory
|
|
41
|
+
return {
|
|
42
|
+
"gross_margin_pct": _ratio(_number(income, "gross_profit"), revenue, 100),
|
|
43
|
+
"net_margin_pct": _ratio(net_income, revenue, 100),
|
|
44
|
+
"dupont": {
|
|
45
|
+
"roe": _ratio(net_income, equity, 100),
|
|
46
|
+
"net_profit_margin": _ratio(net_income, revenue, 100),
|
|
47
|
+
"asset_turnover": _ratio(revenue, assets),
|
|
48
|
+
"equity_multiplier": _ratio(assets, equity),
|
|
49
|
+
},
|
|
50
|
+
"working_capital": {
|
|
51
|
+
"current_ratio": _ratio(current_assets, current_liabilities),
|
|
52
|
+
"quick_ratio": _ratio(quick_assets, current_liabilities),
|
|
53
|
+
},
|
|
54
|
+
# The former three-term approximation is not a full Altman model.
|
|
55
|
+
"altman_z_score": None,
|
|
56
|
+
"solvency_risk": "UNKNOWN",
|
|
57
|
+
"limitations": ["Unavailable metrics are null. No complete Altman model was evaluated."],
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _fetch_yahoo_statements(symbol: str):
|
|
62
|
+
import yfinance as yf
|
|
63
|
+
from curl_cffi.requests import Session
|
|
64
|
+
|
|
65
|
+
deadline = time.monotonic() + 20
|
|
66
|
+
|
|
67
|
+
class BoundedSession(Session):
|
|
68
|
+
def request(self, method, url, **kwargs):
|
|
69
|
+
# yfinance passes timeout=30 explicitly, overriding a session default.
|
|
70
|
+
requested = kwargs.get("timeout", 8)
|
|
71
|
+
if isinstance(requested, (tuple, list)):
|
|
72
|
+
requested = max(requested)
|
|
73
|
+
remaining = deadline - time.monotonic()
|
|
74
|
+
if remaining <= 0:
|
|
75
|
+
raise TimeoutError("Financial statement source deadline exceeded")
|
|
76
|
+
kwargs["timeout"] = min(float(requested or 8), 8, remaining)
|
|
77
|
+
return super().request(method, url, **kwargs)
|
|
78
|
+
|
|
79
|
+
with BoundedSession(impersonate="chrome") as session:
|
|
80
|
+
ticker = yf.Ticker(symbol, session=session)
|
|
81
|
+
inc_df = ticker.income_stmt
|
|
82
|
+
bal_df = ticker.balance_sheet
|
|
83
|
+
if time.monotonic() >= deadline:
|
|
84
|
+
raise TimeoutError("Financial statement source deadline exceeded")
|
|
85
|
+
if inc_df.empty or bal_df.empty:
|
|
86
|
+
raise ValueError("empty_statements")
|
|
87
|
+
periods = inc_df.columns.intersection(bal_df.columns)
|
|
88
|
+
if periods.empty:
|
|
89
|
+
raise ValueError("no_common_period")
|
|
90
|
+
period = max(periods)
|
|
91
|
+
inc, bal = inc_df[period], bal_df[period]
|
|
92
|
+
def fields(series, mapping):
|
|
93
|
+
values = {}
|
|
94
|
+
for source, target in mapping.items():
|
|
95
|
+
value = series.get(source)
|
|
96
|
+
# pandas marks absent financial cells with NaN.
|
|
97
|
+
if value is not None and math.isfinite(float(value)):
|
|
98
|
+
values[target] = float(value)
|
|
99
|
+
return values
|
|
100
|
+
income = fields(inc, {
|
|
101
|
+
"Total Revenue": "revenue", "Cost Of Revenue": "cost_of_goods_sold",
|
|
102
|
+
"Gross Profit": "gross_profit", "Operating Income": "operating_income", "Net Income": "net_income",
|
|
103
|
+
})
|
|
104
|
+
balance = fields(bal, {
|
|
105
|
+
"Total Assets": "total_assets", "Stockholders Equity": "total_equity",
|
|
106
|
+
"Current Assets": "current_assets", "Current Liabilities": "current_liabilities",
|
|
107
|
+
"Inventory": "inventory", "Retained Earnings": "retained_earnings",
|
|
108
|
+
})
|
|
109
|
+
if not income:
|
|
110
|
+
raise ValueError("empty_statements")
|
|
111
|
+
return income, balance, str(period.date())
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def tool_analyze_financial_statements(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
115
|
+
company_name = str(params.get("company_name") or "").strip().upper()
|
|
116
|
+
data = params.get("financials") or {}
|
|
117
|
+
if not isinstance(data, dict):
|
|
118
|
+
return {"success": False, "error_code": "invalid_financials", "error": "financials must be an object"}
|
|
119
|
+
if params.get("file_path"):
|
|
120
|
+
return {"success": False, "error_code": "use_file_tool", "error": "Read the JSON file with read_file, then pass its contents as financials. This tool does not read arbitrary paths."}
|
|
121
|
+
income, balance, cashflow = (data.get(k, {}) for k in ("income_statement", "balance_sheet", "cashflow"))
|
|
122
|
+
if not all(isinstance(item, dict) for item in (income, balance, cashflow)):
|
|
123
|
+
return {"success": False, "error_code": "invalid_financials", "error": "Statement sections must be objects"}
|
|
124
|
+
source, period = "caller-supplied statements", None
|
|
125
|
+
source_attempts = []
|
|
126
|
+
disclosure = {}
|
|
127
|
+
diagnosis = "missing_statements"
|
|
128
|
+
if company_name and len(company_name) <= 10 and not income:
|
|
129
|
+
if not params.get("network_enabled", True):
|
|
130
|
+
diagnosis = "network_disabled"
|
|
131
|
+
else:
|
|
132
|
+
try:
|
|
133
|
+
income, balance, period = _fetch_yahoo_statements(company_name)
|
|
134
|
+
source = f"yfinance:{company_name}"
|
|
135
|
+
except ImportError:
|
|
136
|
+
diagnosis = "dependency_missing"
|
|
137
|
+
except TimeoutError:
|
|
138
|
+
diagnosis = "source_timeout"
|
|
139
|
+
except ValueError as exc:
|
|
140
|
+
diagnosis = str(exc) if str(exc) in {"empty_statements", "no_common_period"} else "source_error"
|
|
141
|
+
except Exception:
|
|
142
|
+
diagnosis = "source_unavailable"
|
|
143
|
+
source_attempts.append({'source': 'yfinance', 'success': bool(income), 'error_code': None if income else diagnosis})
|
|
144
|
+
if not income:
|
|
145
|
+
from aria_code.datasources.sec_statements import SECError, fetch_annual_statements
|
|
146
|
+
try:
|
|
147
|
+
disclosure = fetch_annual_statements(company_name)
|
|
148
|
+
income, balance = disclosure['income_statement'], disclosure['balance_sheet']
|
|
149
|
+
cashflow, period = disclosure['cashflow'], disclosure['period']
|
|
150
|
+
source = f"sec-edgar:{company_name}"
|
|
151
|
+
source_attempts.append({'source': 'sec-edgar', 'success': True})
|
|
152
|
+
except SECError as exc:
|
|
153
|
+
source_attempts.append({'source': 'sec-edgar', 'success': False, 'error_code': exc.code})
|
|
154
|
+
if not income:
|
|
155
|
+
fallback_code = next((attempt.get('error_code') for attempt in source_attempts if attempt['source'] == 'sec-edgar'), None)
|
|
156
|
+
fallback_message = {
|
|
157
|
+
'sec_identity_required': ' SEC fallback needs your declared company/contact email.',
|
|
158
|
+
'sec_access_denied': ' SEC fallback denied access.',
|
|
159
|
+
'sec_rate_limited': ' SEC fallback is rate-limited; no automatic retry was made.',
|
|
160
|
+
}.get(fallback_code, f' SEC fallback: {fallback_code}.' if fallback_code else '')
|
|
161
|
+
return {
|
|
162
|
+
"success": False, "error_code": diagnosis, "source": f"yfinance:{company_name}",
|
|
163
|
+
"source_attempts": source_attempts,
|
|
164
|
+
"error": f"No financial statements available for {company_name or 'this company'} ({diagnosis}).{fallback_message} This tool does not estimate missing figures.",
|
|
165
|
+
"next_actions": ["Continue other analysis using available market data; disclose missing financial statements.",
|
|
166
|
+
"Supply income_statement, balance_sheet and cashflow through financials.",
|
|
167
|
+
"Check source_attempts. Configure EDGAR_USER_AGENT with your company and contact email for the SEC fallback. Google login does not authorize financial sources."],
|
|
168
|
+
}
|
|
169
|
+
try:
|
|
170
|
+
metrics = compute_financial_metrics(income, balance, cashflow)
|
|
171
|
+
except ValueError as exc:
|
|
172
|
+
return {"success": False, "error_code": "invalid_financials", "error": str(exc)}
|
|
173
|
+
metrics.update(company_name=company_name, data_source=source, period=period)
|
|
174
|
+
if disclosure:
|
|
175
|
+
metrics.update({key: value for key, value in disclosure.items() if key not in {'income_statement', 'balance_sheet', 'cashflow'}})
|
|
176
|
+
metrics['limitations'].append('SEC metrics describe the disclosed annual period, not live market data. Cash flow was not evaluated.')
|
|
177
|
+
if disclosure.get('stale'):
|
|
178
|
+
metrics['limitations'].append('The selected annual period is over 550 days old; do not describe it as current financial data.')
|
|
179
|
+
def display(value):
|
|
180
|
+
return "unavailable" if value is None else str(value)
|
|
181
|
+
return {
|
|
182
|
+
"success": True, "data": metrics, "source_attempts": source_attempts,
|
|
183
|
+
"summary": f"{company_name} financial metrics ({source}, period {period or 'caller supplied'}): gross margin {display(metrics['gross_margin_pct'])}%; net margin {display(metrics['net_margin_pct'])}%; ROE {display(metrics['dupont']['roe'])}%. Missing metrics are unavailable; solvency was not classified.",
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def register_enterprise_finance_tools(tools_dict: Dict[str, Any], schemas_list: List[Dict[str, Any]]) -> int:
|
|
188
|
+
tools_dict["analyze_financial_statements"] = (tool_analyze_financial_statements, "Analyze company financial statements (P&L, Balance Sheet, Cash Flow) and Dupont decomposition")
|
|
189
|
+
schemas_list.append({
|
|
190
|
+
"name": "analyze_financial_statements",
|
|
191
|
+
"description": "Compute supported corporate financial metrics. For a ticker, try Yahoo then SEC annual disclosures. Missing metrics stay unknown; no solvency classification is inferred. Each result identifies its source and reporting period.",
|
|
192
|
+
"parameters": {
|
|
193
|
+
"type": "object",
|
|
194
|
+
"properties": {
|
|
195
|
+
"file_path": {"type": "string", "description": "Use read_file for JSON and pass financials; direct paths are not read"},
|
|
196
|
+
"financials": {"type": "object", "description": "Optional dict containing income_statement, balance_sheet, cashflow"},
|
|
197
|
+
"company_name": {"type": "string", "description": "Company name or ticker symbol (e.g. AAPL)"},
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
})
|
|
201
|
+
return 1
|
|
202
|
+
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"""Enterprise connector tools — SHAPES ONLY, not implementations.
|
|
2
|
+
|
|
3
|
+
Read this before using anything here.
|
|
4
|
+
=====================================
|
|
5
|
+
None of these functions contact the service they name. Every one returns a
|
|
6
|
+
hardcoded payload: ``tool_send_slack_notification`` reports
|
|
7
|
+
``"Successfully posted to Slack channel"`` with an invented timestamp and
|
|
8
|
+
permalink without opening a socket, and the QuickBooks, Shopify and Snowflake
|
|
9
|
+
tools return fabricated figures in the same way.
|
|
10
|
+
|
|
11
|
+
They define the intended request/response shape for six integrations that have
|
|
12
|
+
not been built. That is a legitimate thing to have; what is not legitimate is
|
|
13
|
+
letting a model call one and report the fabricated result to a user as fact —
|
|
14
|
+
"I posted the alert to #trading-desk" when nothing was sent, or a cash-runway
|
|
15
|
+
number invented out of nothing.
|
|
16
|
+
|
|
17
|
+
So ``register_extended_tools`` wraps each one in a guard that refuses to run
|
|
18
|
+
and says why. The shapes stay here as the specification for whoever implements
|
|
19
|
+
them; ``ARIA_ALLOW_STUB_TOOLS=1`` returns the canned payloads for tests and
|
|
20
|
+
demos, and names itself in the result so the caller cannot mistake it for real.
|
|
21
|
+
|
|
22
|
+
Implementing one means replacing the body with a real client call and dropping
|
|
23
|
+
it from ``_STUB_TOOLS``.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
import logging
|
|
29
|
+
from typing import Any, Dict, List, Optional
|
|
30
|
+
|
|
31
|
+
logger = logging.getLogger(__name__)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def tool_send_slack_notification(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
35
|
+
"""Send an automated report or approval card to a connected Slack channel."""
|
|
36
|
+
channel = params.get("channel", "#trading-desk")
|
|
37
|
+
text = params.get("text", "Aria Quantitative Alert: Portfolio Rebalanced.")
|
|
38
|
+
blocks = params.get("blocks", [])
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
"success": True,
|
|
42
|
+
"channel": channel,
|
|
43
|
+
"ts": "1724502800.102900",
|
|
44
|
+
"permalink": f"https://arthera.slack.com/archives/{channel.replace('#', '')}/p1724502800102900",
|
|
45
|
+
"message": f"Successfully posted to Slack channel {channel}",
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def tool_push_feishu_card(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
50
|
+
"""Send an interactive approval card to Feishu / Lark."""
|
|
51
|
+
title = params.get("title", "Aria 投资策略审批通知")
|
|
52
|
+
receive_id = params.get("receive_id", "ou_arthera_admin_001")
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
"success": True,
|
|
56
|
+
"instance_code": "FEISHU_APPR_8829104",
|
|
57
|
+
"status": "PENDING",
|
|
58
|
+
"target": receive_id,
|
|
59
|
+
"title": title,
|
|
60
|
+
"message": f"已将「{title}」推送到飞书工作台,等待责任人审批",
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def tool_parse_tradingview_alert(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
65
|
+
"""Ingest TradingView Webhook alert and map to quantitative execution order."""
|
|
66
|
+
ticker = params.get("ticker", "NASDAQ:NVDA")
|
|
67
|
+
action = params.get("action", "BUY").upper()
|
|
68
|
+
price = float(params.get("price", 128.5))
|
|
69
|
+
timeframe = params.get("timeframe", "1h")
|
|
70
|
+
strategy = params.get("strategy", "Aria Momentum Alpha V3")
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
"success": True,
|
|
74
|
+
"ticker": ticker,
|
|
75
|
+
"action": action,
|
|
76
|
+
"trigger_price": price,
|
|
77
|
+
"timeframe": timeframe,
|
|
78
|
+
"strategy": strategy,
|
|
79
|
+
"order_intent": {
|
|
80
|
+
"symbol": ticker.split(":")[-1] if ":" in ticker else ticker,
|
|
81
|
+
"side": action,
|
|
82
|
+
"limit_price": price,
|
|
83
|
+
"quantity": 100,
|
|
84
|
+
},
|
|
85
|
+
"message": f"TradingView 信号已解析: {strategy} 触发 {action} {ticker} @ {price}",
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def tool_get_quickbooks_pnl(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
90
|
+
"""Fetch corporate P&L statement, burn rate, and runway from QuickBooks / Xero."""
|
|
91
|
+
company = params.get("company_name", "Arthera Enterprise Corp")
|
|
92
|
+
period = params.get("period", "2026-Q2")
|
|
93
|
+
|
|
94
|
+
total_income = 485000.0
|
|
95
|
+
cogs = 142000.0
|
|
96
|
+
gross_profit = total_income - cogs
|
|
97
|
+
operating_expenses = 195000.0
|
|
98
|
+
net_operating_income = gross_profit - operating_expenses
|
|
99
|
+
monthly_burn = 45000.0
|
|
100
|
+
cash_balance = 1250000.0
|
|
101
|
+
runway_months = round(cash_balance / monthly_burn, 1)
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
"success": True,
|
|
105
|
+
"company_name": company,
|
|
106
|
+
"period": period,
|
|
107
|
+
"currency": "USD",
|
|
108
|
+
"metrics": {
|
|
109
|
+
"total_revenue": total_income,
|
|
110
|
+
"cogs": cogs,
|
|
111
|
+
"gross_profit": gross_profit,
|
|
112
|
+
"gross_margin_pct": round((gross_profit / total_income) * 100, 2),
|
|
113
|
+
"operating_expenses": operating_expenses,
|
|
114
|
+
"net_income": net_operating_income,
|
|
115
|
+
"net_margin_pct": round((net_operating_income / total_income) * 100, 2),
|
|
116
|
+
"cash_burn_rate_monthly": monthly_burn,
|
|
117
|
+
"total_cash_reserve": cash_balance,
|
|
118
|
+
"runway_months": runway_months,
|
|
119
|
+
"overdue_ar": 18500.0,
|
|
120
|
+
},
|
|
121
|
+
"health_rating": "HEALTHY",
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def tool_get_shopify_store_analytics(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
126
|
+
"""Fetch Shopify / Amazon Seller GMV, order volume, and ROAS."""
|
|
127
|
+
store = params.get("store_domain", "shop.arthera.com")
|
|
128
|
+
|
|
129
|
+
total_gmv = 248600.0
|
|
130
|
+
total_orders = 3120
|
|
131
|
+
aov = round(total_gmv / total_orders, 2)
|
|
132
|
+
ad_spend = 48000.0
|
|
133
|
+
roas = round(total_gmv / ad_spend, 2)
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
"success": True,
|
|
137
|
+
"store_domain": store,
|
|
138
|
+
"period_days": 30,
|
|
139
|
+
"currency": "USD",
|
|
140
|
+
"metrics": {
|
|
141
|
+
"total_gmv": total_gmv,
|
|
142
|
+
"total_orders": total_orders,
|
|
143
|
+
"average_order_value": aov,
|
|
144
|
+
"refund_rate_pct": 2.45,
|
|
145
|
+
"ad_spend": ad_spend,
|
|
146
|
+
"blended_roas": roas,
|
|
147
|
+
"out_of_stock_skus": 3,
|
|
148
|
+
},
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def tool_query_snowflake_data(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
153
|
+
"""Execute read-only SQL query against Snowflake / BigQuery Lakehouse."""
|
|
154
|
+
sql = params.get("sql", "SELECT date, ticker, factor_score FROM analytics.equity_factors LIMIT 5")
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
"success": True,
|
|
158
|
+
"query_id": "01b23456-0001-abcd-0001-1234567890ab",
|
|
159
|
+
"execution_time_ms": 142,
|
|
160
|
+
"row_count": 5,
|
|
161
|
+
"columns": ["date", "ticker", "factor_score", "sector", "z_score"],
|
|
162
|
+
"rows": [
|
|
163
|
+
["2026-08-20", "NVDA", 2.84, "Semiconductors", 2.15],
|
|
164
|
+
["2026-08-20", "AAPL", 1.95, "Consumer Tech", 1.42],
|
|
165
|
+
["2026-08-20", "MSFT", 2.10, "Software Cloud", 1.68],
|
|
166
|
+
["2026-08-20", "AMZN", 1.82, "E-Commerce", 1.30],
|
|
167
|
+
["2026-08-20", "GOOGL", 1.65, "Internet Media", 1.15],
|
|
168
|
+
],
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
# name → the service it would need, for the message the guard returns.
|
|
173
|
+
_STUB_TOOLS = {
|
|
174
|
+
"send_slack_notification": "Slack (bot token + channel)",
|
|
175
|
+
"push_feishu_card": "Feishu/Lark (app credentials + webhook)",
|
|
176
|
+
"parse_tradingview_alert": "TradingView webhook receiver",
|
|
177
|
+
"get_quickbooks_pnl": "QuickBooks Online API (OAuth)",
|
|
178
|
+
"get_shopify_store_analytics": "Shopify Admin API (store + token)",
|
|
179
|
+
"query_snowflake_data": "Snowflake (account, warehouse, credentials)",
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def stub_guard(name: str, service: str, handler):
|
|
184
|
+
"""Wrap a shape-only tool so it reports its status instead of inventing one.
|
|
185
|
+
|
|
186
|
+
Returning fabricated success is the one behaviour that must not survive:
|
|
187
|
+
the model relays it as fact, and the user is told a message was sent or a
|
|
188
|
+
figure was read when neither happened.
|
|
189
|
+
"""
|
|
190
|
+
import os
|
|
191
|
+
|
|
192
|
+
def _guarded(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
193
|
+
if os.getenv("ARIA_ALLOW_STUB_TOOLS", "").strip() in ("1", "true", "yes"):
|
|
194
|
+
result = dict(handler(params) or {})
|
|
195
|
+
result["stub"] = True
|
|
196
|
+
result["warning"] = f"{name} returned canned data; {service} is not connected."
|
|
197
|
+
return result
|
|
198
|
+
return {
|
|
199
|
+
"success": False,
|
|
200
|
+
"error": (
|
|
201
|
+
f"{name} is not implemented — it is a shape-only stub. "
|
|
202
|
+
f"Connecting it requires {service}. "
|
|
203
|
+
f"Do not report its result as if the action happened."
|
|
204
|
+
),
|
|
205
|
+
"stub": True,
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
_guarded.__name__ = getattr(handler, "__name__", name)
|
|
209
|
+
_guarded.__doc__ = getattr(handler, "__doc__", "")
|
|
210
|
+
return _guarded
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def register_extended_tools(registry_or_dict: Any) -> None:
|
|
214
|
+
"""Register the extended connector stubs, guarded.
|
|
215
|
+
|
|
216
|
+
Registered as ``(handler, description)`` pairs: bare functions were being
|
|
217
|
+
stored here, and ToolExecutor indexes ``local_tools[name][0]``, so calling
|
|
218
|
+
any of these raised ``TypeError: 'function' object is not subscriptable``.
|
|
219
|
+
They were unreachable in practice only because none of them had a schema.
|
|
220
|
+
"""
|
|
221
|
+
handlers = {
|
|
222
|
+
"send_slack_notification": tool_send_slack_notification,
|
|
223
|
+
"push_feishu_card": tool_push_feishu_card,
|
|
224
|
+
"parse_tradingview_alert": tool_parse_tradingview_alert,
|
|
225
|
+
"get_quickbooks_pnl": tool_get_quickbooks_pnl,
|
|
226
|
+
"get_shopify_store_analytics": tool_get_shopify_store_analytics,
|
|
227
|
+
"query_snowflake_data": tool_query_snowflake_data,
|
|
228
|
+
}
|
|
229
|
+
tools = {
|
|
230
|
+
name: (
|
|
231
|
+
stub_guard(name, _STUB_TOOLS[name], handler),
|
|
232
|
+
f"[not implemented] {name} — needs {_STUB_TOOLS[name]}",
|
|
233
|
+
)
|
|
234
|
+
for name, handler in handlers.items()
|
|
235
|
+
}
|
|
236
|
+
if hasattr(registry_or_dict, "register"):
|
|
237
|
+
for name, entry in tools.items():
|
|
238
|
+
registry_or_dict.register(name, entry[0])
|
|
239
|
+
elif isinstance(registry_or_dict, dict):
|
|
240
|
+
registry_or_dict.update(tools)
|