aria-code 0.52.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aria_code/__init__.py +42 -0
- aria_code/_version.py +20 -0
- aria_code/adk_apps/__init__.py +1 -0
- aria_code/adk_apps/aria_code_review/__init__.py +1 -0
- aria_code/adk_apps/aria_code_review/agent.py +32 -0
- aria_code/adk_apps/aria_research/__init__.py +1 -0
- aria_code/adk_apps/aria_research/agent.py +31 -0
- aria_code/agents/__init__.py +34 -0
- aria_code/agents/base.py +318 -0
- aria_code/agents/code_review.py +200 -0
- aria_code/agents/deep/__init__.py +37 -0
- aria_code/agents/deep/calibration_loop.py +144 -0
- aria_code/agents/deep/critic.py +125 -0
- aria_code/agents/deep/deepen.py +193 -0
- aria_code/agents/deep/models.py +149 -0
- aria_code/agents/deep/pipeline.py +164 -0
- aria_code/agents/deep/quant_fusion.py +192 -0
- aria_code/agents/deep/themes.py +95 -0
- aria_code/agents/deep/tiers.py +106 -0
- aria_code/agents/engineering/__init__.py +14 -0
- aria_code/agents/engineering/coder.py +222 -0
- aria_code/agents/engineering/tester.py +145 -0
- aria_code/agents/financial/__init__.py +21 -0
- aria_code/agents/financial/cashflow_burn.py +119 -0
- aria_code/agents/financial/catalyst.py +279 -0
- aria_code/agents/financial/corporate_finance.py +175 -0
- aria_code/agents/financial/debate.py +224 -0
- aria_code/agents/financial/earnings.py +303 -0
- aria_code/agents/financial/fundamental.py +191 -0
- aria_code/agents/financial/macro.py +99 -0
- aria_code/agents/financial/news.py +207 -0
- aria_code/agents/financial/risk.py +165 -0
- aria_code/agents/financial/sector.py +279 -0
- aria_code/agents/financial/strategist.py +121 -0
- aria_code/agents/financial/stripe_revenue.py +127 -0
- aria_code/agents/financial/synthesis.py +274 -0
- aria_code/agents/financial/technical.py +258 -0
- aria_code/agents/orchestrator.py +44 -0
- aria_code/agents/portfolio_agent.py +363 -0
- aria_code/agents/realty/__init__.py +62 -0
- aria_code/agents/realty/asset_diagnosis.py +152 -0
- aria_code/agents/realty/business_match.py +166 -0
- aria_code/agents/realty/cashflow_verify.py +209 -0
- aria_code/agents/realty/contract_rules.py +210 -0
- aria_code/agents/realty/energy_anomaly.py +189 -0
- aria_code/agents/realty/exit_settlement.py +208 -0
- aria_code/agents/realty/fulfillment_risk.py +206 -0
- aria_code/agents/realty/ops_optimize.py +160 -0
- aria_code/agents/realty/revenue_share.py +215 -0
- aria_code/agents/registry.py +158 -0
- aria_code/agents/signal_scheme.py +111 -0
- aria_code/agents/sports/__init__.py +0 -0
- aria_code/agents/sports/football_agent.py +197 -0
- aria_code/agents/supervisor.py +113 -0
- aria_code/agents/team.py +492 -0
- aria_code/agents/warehouse/__init__.py +25 -0
- aria_code/agents/warehouse/contracts.py +26 -0
- aria_code/agents/warehouse/dashboard.py +155 -0
- aria_code/agents/warehouse/fulfillment_leadtime.py +95 -0
- aria_code/agents/warehouse/inbound_exceptions.py +25 -0
- aria_code/agents/warehouse/inventory_health.py +24 -0
- aria_code/agents/warehouse/local_run.py +71 -0
- aria_code/agents/warehouse/local_snapshot.py +132 -0
- aria_code/agents/warehouse/logistics_cost.py +84 -0
- aria_code/agents/warehouse/logistics_sync.py +21 -0
- aria_code/agents/warehouse/workflow.py +31 -0
- aria_code/aliyun_data_client.py +4 -0
- aria_code/apps/README.md +12 -0
- aria_code/apps/__init__.py +2 -0
- aria_code/apps/channels/README.md +15 -0
- aria_code/apps/channels/__init__.py +17 -0
- aria_code/apps/channels/intake.py +92 -0
- aria_code/apps/channels/registry.py +95 -0
- aria_code/apps/channels/tradingview.py +94 -0
- aria_code/apps/cli/README.md +13 -0
- aria_code/apps/cli/__init__.py +2 -0
- aria_code/apps/cli/_optional.py +120 -0
- aria_code/apps/cli/bootstrap.py +145 -0
- aria_code/apps/cli/broker_render.py +206 -0
- aria_code/apps/cli/codegen_paths.py +29 -0
- aria_code/apps/cli/commands/__init__.py +16 -0
- aria_code/apps/cli/commands/_business_render.py +78 -0
- aria_code/apps/cli/commands/_ui.py +71 -0
- aria_code/apps/cli/commands/analysis_cmds.py +369 -0
- aria_code/apps/cli/commands/ashare_prediction_cmds.py +327 -0
- aria_code/apps/cli/commands/auth_cmds.py +239 -0
- aria_code/apps/cli/commands/backtest_cmds.py +2543 -0
- aria_code/apps/cli/commands/broker_cmds.py +1234 -0
- aria_code/apps/cli/commands/business_workflow_cmds.py +319 -0
- aria_code/apps/cli/commands/canvas_cmds.py +77 -0
- aria_code/apps/cli/commands/catalog.py +87 -0
- aria_code/apps/cli/commands/core_cmds.py +2520 -0
- aria_code/apps/cli/commands/data_cmds.py +457 -0
- aria_code/apps/cli/commands/diagnostic_cmds.py +230 -0
- aria_code/apps/cli/commands/diagnostic_ops_cmds.py +813 -0
- aria_code/apps/cli/commands/file_cmds.py +312 -0
- aria_code/apps/cli/commands/finance_service_cmds.py +60 -0
- aria_code/apps/cli/commands/fx_commodity_cmds.py +123 -0
- aria_code/apps/cli/commands/market.py +434 -0
- aria_code/apps/cli/commands/market_cmds.py +1381 -0
- aria_code/apps/cli/commands/market_context.py +425 -0
- aria_code/apps/cli/commands/market_render.py +7 -0
- aria_code/apps/cli/commands/model_cmds.py +2153 -0
- aria_code/apps/cli/commands/ops_cmds.py +721 -0
- aria_code/apps/cli/commands/orchestrator_cmds.py +179 -0
- aria_code/apps/cli/commands/pdf_export_cmds.py +125 -0
- aria_code/apps/cli/commands/portfolio_cmds.py +1278 -0
- aria_code/apps/cli/commands/report.py +437 -0
- aria_code/apps/cli/commands/scaffold_templates.py +617 -0
- aria_code/apps/cli/commands/session_cmds.py +236 -0
- aria_code/apps/cli/commands/session_ux_cmds.py +359 -0
- aria_code/apps/cli/commands/team.py +669 -0
- aria_code/apps/cli/commands/team_render.py +8 -0
- aria_code/apps/cli/commands/ui_cmds.py +401 -0
- aria_code/apps/cli/commands/warehouse_cmds.py +79 -0
- aria_code/apps/cli/commands/workflow_cmds.py +480 -0
- aria_code/apps/cli/commands/workspace_cmds.py +1494 -0
- aria_code/apps/cli/config_paths.py +73 -0
- aria_code/apps/cli/config_store.py +78 -0
- aria_code/apps/cli/constants.py +88 -0
- aria_code/apps/cli/context.py +34 -0
- aria_code/apps/cli/deterministic.py +191 -0
- aria_code/apps/cli/direct.py +48 -0
- aria_code/apps/cli/finance_service_catalog.py +111 -0
- aria_code/apps/cli/football_reports.py +231 -0
- aria_code/apps/cli/github_app_auth.py +135 -0
- aria_code/apps/cli/google_login.py +196 -0
- aria_code/apps/cli/handlers/__init__.py +11 -0
- aria_code/apps/cli/handlers/broker_handlers.py +122 -0
- aria_code/apps/cli/handlers/chart_handlers.py +1309 -0
- aria_code/apps/cli/handlers/market_handlers.py +2513 -0
- aria_code/apps/cli/handlers/realty_handlers.py +114 -0
- aria_code/apps/cli/handlers/sports_handlers.py +22 -0
- aria_code/apps/cli/handlers/strategy_advice.py +82 -0
- aria_code/apps/cli/helpers.py +302 -0
- aria_code/apps/cli/hooks.py +180 -0
- aria_code/apps/cli/i18n.py +297 -0
- aria_code/apps/cli/intent.py +136 -0
- aria_code/apps/cli/intent_router.py +276 -0
- aria_code/apps/cli/intent_signals.py +344 -0
- aria_code/apps/cli/lifecycle_hooks.py +48 -0
- aria_code/apps/cli/local_tool_schemas.py +536 -0
- aria_code/apps/cli/main.py +29 -0
- aria_code/apps/cli/market_metadata.py +135 -0
- aria_code/apps/cli/market_universe.py +487 -0
- aria_code/apps/cli/message_processing.py +310 -0
- aria_code/apps/cli/model_catalog.py +620 -0
- aria_code/apps/cli/pdf_report.py +977 -0
- aria_code/apps/cli/plan_mode.py +139 -0
- aria_code/apps/cli/plotly_html.py +15 -0
- aria_code/apps/cli/prediction_feedback.py +202 -0
- aria_code/apps/cli/preflight.py +502 -0
- aria_code/apps/cli/project_aria.py +60 -0
- aria_code/apps/cli/prompt_assembly.py +59 -0
- aria_code/apps/cli/prompts/__init__.py +0 -0
- aria_code/apps/cli/prompts/coding.py +53 -0
- aria_code/apps/cli/prompts/select.py +142 -0
- aria_code/apps/cli/prompts/system_prompts.py +552 -0
- aria_code/apps/cli/prompts/ui.py +436 -0
- aria_code/apps/cli/provider_endpoints.py +237 -0
- aria_code/apps/cli/provider_keys.py +73 -0
- aria_code/apps/cli/providers/__init__.py +1 -0
- aria_code/apps/cli/providers/base.py +521 -0
- aria_code/apps/cli/providers/chat_routing.py +128 -0
- aria_code/apps/cli/providers/collaboration.py +98 -0
- aria_code/apps/cli/providers/llm/__init__.py +1 -0
- aria_code/apps/cli/providers/llm/offline_responses.py +68 -0
- aria_code/apps/cli/providers/llm/ollama_stream.py +1594 -0
- aria_code/apps/cli/providers/llm/response_cache.py +60 -0
- aria_code/apps/cli/providers/llm/sse_stream.py +257 -0
- aria_code/apps/cli/providers/runtime_bridge.py +353 -0
- aria_code/apps/cli/providers/vertexai_stream.py +316 -0
- aria_code/apps/cli/runtime_consumer.py +657 -0
- aria_code/apps/cli/sandbox.py +32 -0
- aria_code/apps/cli/session_export.py +120 -0
- aria_code/apps/cli/session_jsonl.py +208 -0
- aria_code/apps/cli/session_store.py +112 -0
- aria_code/apps/cli/skills_catalog.py +273 -0
- aria_code/apps/cli/todo_tracker.py +190 -0
- aria_code/apps/cli/tool_executor.py +823 -0
- aria_code/apps/cli/tool_registry.py +34 -0
- aria_code/apps/cli/tool_scope.py +106 -0
- aria_code/apps/cli/tools/__init__.py +40 -0
- aria_code/apps/cli/tools/context.py +46 -0
- aria_code/apps/cli/tools/file_tools.py +180 -0
- aria_code/apps/cli/tools/market_tools.py +620 -0
- aria_code/apps/cli/tools/notebook_tools.py +111 -0
- aria_code/apps/cli/tools/system_tools.py +726 -0
- aria_code/apps/cli/tools/write_tools.py +845 -0
- aria_code/apps/cli/tradingview_bridge.py +529 -0
- aria_code/apps/cli/turn_planning.py +137 -0
- aria_code/apps/cli/update_check.py +153 -0
- aria_code/apps/cli/utils/__init__.py +0 -0
- aria_code/apps/cli/utils/market_detect.py +1597 -0
- aria_code/apps/daemon/README.md +14 -0
- aria_code/apps/vscode/README.md +115 -0
- aria_code/apps/vscode/package.json +70 -0
- aria_code/aria_cli.py +6743 -0
- aria_code/aria_daemon.py +1398 -0
- aria_code/aria_feishu_bot.py +1423 -0
- aria_code/aria_mcp_server.py +7 -0
- aria_code/aria_relay_client.py +4 -0
- aria_code/aria_relay_server.py +490 -0
- aria_code/aria_telegram_bot.py +202 -0
- aria_code/ariarc.py +385 -0
- aria_code/artifacts.py +581 -0
- aria_code/backtest_engine.py +4 -0
- aria_code/backtest_report.py +4 -0
- aria_code/brokers/__init__.py +78 -0
- aria_code/brokers/automation.py +193 -0
- aria_code/brokers/base.py +231 -0
- aria_code/brokers/capabilities.py +264 -0
- aria_code/brokers/cn/__init__.py +10 -0
- aria_code/brokers/cn/easytrader_broker.py +193 -0
- aria_code/brokers/cn/futu_broker.py +194 -0
- aria_code/brokers/cn/longbridge_broker.py +190 -0
- aria_code/brokers/cn/tiger_broker.py +196 -0
- aria_code/brokers/cn/xtquant_broker.py +225 -0
- aria_code/brokers/config.py +414 -0
- aria_code/brokers/intl/__init__.py +5 -0
- aria_code/brokers/intl/alpaca_broker.py +183 -0
- aria_code/brokers/intl/ibkr_broker.py +215 -0
- aria_code/brokers/intl/trading212_broker.py +183 -0
- aria_code/brokers/intl/webull_broker.py +156 -0
- aria_code/brokers/paper_broker.py +266 -0
- aria_code/brokers/planning.py +296 -0
- aria_code/brokers/registry.py +213 -0
- aria_code/brokers/trading.py +267 -0
- aria_code/canva_client.py +4 -0
- aria_code/change_store.py +127 -0
- aria_code/clients/__init__.py +0 -0
- aria_code/clients/aliyun_data_client.py +660 -0
- aria_code/clients/aria_relay_client.py +182 -0
- aria_code/clients/canva_client.py +284 -0
- aria_code/clients/figma_client.py +100 -0
- aria_code/clients/football_data_client.py +1671 -0
- aria_code/clients/kling_video_client.py +182 -0
- aria_code/clients/market_data_client.py +1976 -0
- aria_code/clients/openai_image_client.py +242 -0
- aria_code/clients/runway_video_client.py +157 -0
- aria_code/clients/warehouse_erp_client.py +105 -0
- aria_code/cloud_memory.py +181 -0
- aria_code/command_safety.py +19 -0
- aria_code/computer_use_tools.py +4 -0
- aria_code/dashboard_generator.py +579 -0
- aria_code/data_analysis_tools.py +4 -0
- aria_code/data_cleaner.py +483 -0
- aria_code/data_service.py +513 -0
- aria_code/datasources/__init__.py +23 -0
- aria_code/datasources/base.py +166 -0
- aria_code/datasources/router.py +253 -0
- aria_code/datasources/sources/__init__.py +15 -0
- aria_code/datasources/sources/akshare_source.py +269 -0
- aria_code/datasources/sources/alpha_vantage_source.py +203 -0
- aria_code/datasources/sources/edgar_source.py +219 -0
- aria_code/datasources/sources/finnhub_source.py +198 -0
- aria_code/datasources/sources/fred_source.py +223 -0
- aria_code/datasources/sources/tushare_source.py +143 -0
- aria_code/datasources/sources/web_scraper_source.py +278 -0
- aria_code/datasources/sources/world_bank_source.py +206 -0
- aria_code/datasources/sources/yfinance_source.py +152 -0
- aria_code/demo_player.py +207 -0
- aria_code/doctor.py +813 -0
- aria_code/domain/__init__.py +0 -0
- aria_code/domain/backtest_engine.py +354 -0
- aria_code/domain/backtest_report.py +472 -0
- aria_code/domain/finance_formulas.py +389 -0
- aria_code/domain/portfolio_ledger.py +307 -0
- aria_code/domain/strategy_vault.py +421 -0
- aria_code/evals/__init__.py +37 -0
- aria_code/evals/harness.py +598 -0
- aria_code/evals/runner.py +238 -0
- aria_code/external_agent_runner.py +115 -0
- aria_code/figma_client.py +4 -0
- aria_code/file_analysis_tools.py +4 -0
- aria_code/finance_formulas.py +4 -0
- aria_code/football_data_client.py +4 -0
- aria_code/image_gen_tools.py +4 -0
- aria_code/intent_classifier.py +386 -0
- aria_code/kling_video_client.py +4 -0
- aria_code/licensing.py +151 -0
- aria_code/local_finance_tools.py +4 -0
- aria_code/local_image_provider.py +4 -0
- aria_code/local_llm_provider.py +4 -0
- aria_code/macro_tools.py +4 -0
- aria_code/markdown_pdf.py +289 -0
- aria_code/market_data_client.py +4 -0
- aria_code/mcp_client.py +639 -0
- aria_code/memory_manager.py +246 -0
- aria_code/model_capability.py +486 -0
- aria_code/notification_tools.py +4 -0
- aria_code/openai_image_client.py +4 -0
- aria_code/packages/__init__.py +23 -0
- aria_code/packages/adk_bridge/__init__.py +11 -0
- aria_code/packages/adk_bridge/code_review_tools.py +49 -0
- aria_code/packages/adk_bridge/market_tools.py +125 -0
- aria_code/packages/aria_agents/__init__.py +5 -0
- aria_code/packages/aria_agents/manifest.py +78 -0
- aria_code/packages/aria_core/__init__.py +34 -0
- aria_code/packages/aria_core/architecture.py +269 -0
- aria_code/packages/aria_core/export.py +147 -0
- aria_code/packages/aria_core/manifest.py +65 -0
- aria_code/packages/aria_core/paths.py +57 -0
- aria_code/packages/aria_core/secure_file.py +68 -0
- aria_code/packages/aria_infra/__init__.py +15 -0
- aria_code/packages/aria_infra/arthera.py +52 -0
- aria_code/packages/aria_infra/doctor.py +246 -0
- aria_code/packages/aria_infra/product.py +40 -0
- aria_code/packages/aria_mcp/__init__.py +25 -0
- aria_code/packages/aria_mcp/bridge.py +201 -0
- aria_code/packages/aria_mcp/circuit.py +82 -0
- aria_code/packages/aria_mcp/config.py +111 -0
- aria_code/packages/aria_mcp/installer.py +95 -0
- aria_code/packages/aria_mcp/server.py +1550 -0
- aria_code/packages/aria_mcp/tools.py +81 -0
- aria_code/packages/aria_sdk/__init__.py +19 -0
- aria_code/packages/aria_sdk/client.py +396 -0
- aria_code/packages/aria_sdk/providers.py +70 -0
- aria_code/packages/aria_sdk/streaming.py +79 -0
- aria_code/packages/aria_sdk/types.py +86 -0
- aria_code/packages/aria_services/__init__.py +92 -0
- aria_code/packages/aria_services/cache.py +60 -0
- aria_code/packages/aria_services/context.py +356 -0
- aria_code/packages/aria_services/context_checkpoints.py +157 -0
- aria_code/packages/aria_services/data.py +11 -0
- aria_code/packages/aria_services/provider_health.py +268 -0
- aria_code/packages/aria_services/references.py +247 -0
- aria_code/packages/aria_services/registry.py +249 -0
- aria_code/packages/aria_services/research_protocol.py +57 -0
- aria_code/packages/aria_services/research_quality.py +186 -0
- aria_code/packages/aria_services/settings.py +157 -0
- aria_code/packages/aria_services/usage.py +151 -0
- aria_code/packages/aria_skills/__init__.py +46 -0
- aria_code/packages/aria_skills/catalog.py +149 -0
- aria_code/packages/aria_skills/loader.py +455 -0
- aria_code/packages/aria_skills/registry.py +84 -0
- aria_code/packages/aria_tools/__init__.py +5 -0
- aria_code/packages/aria_tools/financial/__init__.py +8 -0
- aria_code/packages/aria_tools/financial/_paths.py +130 -0
- aria_code/packages/aria_tools/financial/compliance.py +31 -0
- aria_code/packages/aria_tools/financial/factors.py +33 -0
- aria_code/packages/aria_tools/financial/risk_tools.py +33 -0
- aria_code/packages/aria_tools/financial/strategy.py +31 -0
- aria_code/packages/aria_tools/registry.py +128 -0
- aria_code/packages/quant_engine/__init__.py +34 -0
- aria_code/packages/quant_engine/_namespace.py +62 -0
- aria_code/packages/quant_engine/backtest/__init__.py +14 -0
- aria_code/packages/quant_engine/backtest/core.py +53 -0
- aria_code/packages/quant_engine/backtest/engine.py +96 -0
- aria_code/packages/quant_engine/portfolio/__init__.py +13 -0
- aria_code/packages/quant_engine/portfolio/optimizer.py +85 -0
- aria_code/packages/quant_engine/sports/__init__.py +80 -0
- aria_code/packages/quant_engine/sports/calibrator.py +354 -0
- aria_code/packages/quant_engine/sports/dixon_coles.py +234 -0
- aria_code/packages/quant_engine/sports/elo.py +300 -0
- aria_code/packages/quant_engine/sports/form.py +188 -0
- aria_code/packages/quant_engine/sports/h2h.py +195 -0
- aria_code/packages/quant_engine/sports/ml_model.py +377 -0
- aria_code/packages/quant_engine/sports/predictor.py +312 -0
- aria_code/packages/quant_engine/sports/tracker.py +665 -0
- aria_code/packages/quant_engine/stochastic/__init__.py +35 -0
- aria_code/packages/quant_engine/stochastic/gbm_enhanced.py +195 -0
- aria_code/packages/quant_engine/stochastic/ito_calculus.py +477 -0
- aria_code/packages/quant_engine/stochastic/kelly_criterion.py +181 -0
- aria_code/packages/quant_engine/stochastic/monte_carlo_advanced.py +95 -0
- aria_code/packages/quant_engine/stochastic/options_pricing.py +576 -0
- aria_code/packages/quant_engine/stochastic/stochastic_processes.py +90 -0
- aria_code/packs/__init__.py +85 -0
- aria_code/packs/base.py +168 -0
- aria_code/packs/finance/__init__.py +250 -0
- aria_code/packs/logistics/__init__.py +169 -0
- aria_code/packs/payments/__init__.py +139 -0
- aria_code/packs/realty/__init__.py +190 -0
- aria_code/packs/registry.py +202 -0
- aria_code/packs/rules.py +90 -0
- aria_code/plan_utils.py +194 -0
- aria_code/plugin_loader.py +328 -0
- aria_code/portfolio_ledger.py +4 -0
- aria_code/preview_server.py +449 -0
- aria_code/privacy/__init__.py +5 -0
- aria_code/privacy/feedback.py +123 -0
- aria_code/project_review.py +278 -0
- aria_code/project_review_api.py +235 -0
- aria_code/project_review_server.py +18 -0
- aria_code/project_tools.py +4 -0
- aria_code/providers/__init__.py +30 -0
- aria_code/providers/llm/__init__.py +19 -0
- aria_code/providers/llm/anthropic.py +184 -0
- aria_code/providers/llm/autoconfig.py +213 -0
- aria_code/providers/llm/base.py +139 -0
- aria_code/providers/llm/custom.py +158 -0
- aria_code/providers/llm/ollama.py +129 -0
- aria_code/providers/llm/openai_compat.py +313 -0
- aria_code/providers/llm/registry.py +444 -0
- aria_code/providers/local_image_provider.py +202 -0
- aria_code/providers/local_llm_provider.py +589 -0
- aria_code/realty_data_tools.py +4 -0
- aria_code/report_exporters.py +150 -0
- aria_code/report_generator.py +1764 -0
- aria_code/runtime/__init__.py +169 -0
- aria_code/runtime/acceptance.py +481 -0
- aria_code/runtime/agent_loop.py +1520 -0
- aria_code/runtime/approval.py +57 -0
- aria_code/runtime/budget.py +232 -0
- aria_code/runtime/checkpoints.py +432 -0
- aria_code/runtime/crash_report.py +174 -0
- aria_code/runtime/events.py +113 -0
- aria_code/runtime/gateway.py +150 -0
- aria_code/runtime/lsp.py +484 -0
- aria_code/runtime/orchestrator.py +55 -0
- aria_code/runtime/repo_map.py +700 -0
- aria_code/runtime/run_state.py +127 -0
- aria_code/runtime/run_store.py +450 -0
- aria_code/runtime/self_healing.py +422 -0
- aria_code/runtime/subagent.py +547 -0
- aria_code/runtime/task_ledger.py +86 -0
- aria_code/runtime/task_orchestrator.py +90 -0
- aria_code/runtime/tool_executor.py +217 -0
- aria_code/runtime/tool_policy.py +107 -0
- aria_code/runtime/worktrees.py +215 -0
- aria_code/runway_video_client.py +4 -0
- aria_code/safety/__init__.py +23 -0
- aria_code/safety/permissions.py +306 -0
- aria_code/safety/service.py +102 -0
- aria_code/setup_wizard.py +673 -0
- aria_code/spreadsheet_tools.py +4 -0
- aria_code/strategy_vault.py +4 -0
- aria_code/tools/__init__.py +0 -0
- aria_code/tools/artifact_tools.py +252 -0
- aria_code/tools/broker_tools.py +92 -0
- aria_code/tools/build_quant_engine.py +97 -0
- aria_code/tools/code_audit_tools.py +192 -0
- aria_code/tools/computer_use_tools.py +504 -0
- aria_code/tools/data_analysis_tools.py +809 -0
- aria_code/tools/enterprise_finance_tools.py +156 -0
- aria_code/tools/extended_tools.py +240 -0
- aria_code/tools/file_analysis_tools.py +885 -0
- aria_code/tools/image_gen_tools.py +114 -0
- aria_code/tools/local_finance_tools.py +3417 -0
- aria_code/tools/logistics_tools.py +135 -0
- aria_code/tools/macro_tools.py +369 -0
- aria_code/tools/notification_tools.py +249 -0
- aria_code/tools/project_tools.py +525 -0
- aria_code/tools/realty_data_tools.py +659 -0
- aria_code/tools/spreadsheet_tools.py +388 -0
- aria_code/tools/stripe_tools.py +115 -0
- aria_code/ui/__init__.py +105 -0
- aria_code/ui/banner.py +508 -0
- aria_code/ui/completer.py +501 -0
- aria_code/ui/console.py +281 -0
- aria_code/ui/image_render.py +243 -0
- aria_code/ui/input_box.py +488 -0
- aria_code/ui/picker.py +201 -0
- aria_code/ui/render/__init__.py +11 -0
- aria_code/ui/render/finance.py +1705 -0
- aria_code/ui/render/market.py +225 -0
- aria_code/ui/render/output.py +775 -0
- aria_code/ui/render/responsive.py +75 -0
- aria_code/ui/render/team.py +354 -0
- aria_code/ui/robot.py +235 -0
- aria_code/ui/startup_dashboard.py +109 -0
- aria_code/utils/vscode_uri.py +37 -0
- aria_code/video_analysis.py +147 -0
- aria_code/video_editor.py +271 -0
- aria_code/workspace/__init__.py +6 -0
- aria_code/workspace/files.py +193 -0
- aria_code/workspace/verify.py +113 -0
- aria_code/workspace_changes.py +199 -0
- aria_code/workspace_context.py +233 -0
- aria_code/workspace_service.py +196 -0
- aria_code/workspace_tools.py +150 -0
- aria_code-0.52.0.dist-info/METADATA +237 -0
- aria_code-0.52.0.dist-info/RECORD +478 -0
- aria_code-0.52.0.dist-info/WHEEL +5 -0
- aria_code-0.52.0.dist-info/entry_points.txt +3 -0
- aria_code-0.52.0.dist-info/licenses/LICENSE +201 -0
- aria_code-0.52.0.dist-info/licenses/NOTICE +49 -0
- aria_code-0.52.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""
|
|
2
|
+
tools/enterprise_finance_tools.py — Corporate Financial Statement Analysis Tool
|
|
3
|
+
================================================================================
|
|
4
|
+
Provides CLI and agent tools to ingest and analyze company financial reports.
|
|
5
|
+
Now supports fetching real data from Yahoo Finance.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import logging
|
|
12
|
+
import pathlib
|
|
13
|
+
from typing import Any, Dict, List
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
def compute_financial_metrics(income: dict, balance: dict, cashflow: dict) -> dict:
|
|
18
|
+
"""Perform real financial math."""
|
|
19
|
+
revenue = income.get("revenue", 0) or 1
|
|
20
|
+
net_income = income.get("net_income", 0)
|
|
21
|
+
gross_profit = income.get("gross_profit", 0)
|
|
22
|
+
total_assets = balance.get("total_assets", 0) or 1
|
|
23
|
+
total_equity = balance.get("total_equity", 0) or 1
|
|
24
|
+
current_assets = balance.get("current_assets", 0)
|
|
25
|
+
current_liabilities = balance.get("current_liabilities", 0) or 1
|
|
26
|
+
inventory = balance.get("inventory", 0)
|
|
27
|
+
cogs = income.get("cost_of_goods_sold", 0) or 1
|
|
28
|
+
|
|
29
|
+
# Dupont
|
|
30
|
+
net_margin = net_income / revenue
|
|
31
|
+
asset_turnover = revenue / total_assets
|
|
32
|
+
equity_multiplier = total_assets / total_equity
|
|
33
|
+
roe = net_margin * asset_turnover * equity_multiplier
|
|
34
|
+
|
|
35
|
+
# Working capital
|
|
36
|
+
current_ratio = current_assets / current_liabilities
|
|
37
|
+
quick_ratio = (current_assets - inventory) / current_liabilities
|
|
38
|
+
|
|
39
|
+
# Altman Z-Score approximation (simplified)
|
|
40
|
+
working_capital = current_assets - current_liabilities
|
|
41
|
+
retained_earnings = balance.get("retained_earnings", 0)
|
|
42
|
+
ebit = income.get("operating_income", 0)
|
|
43
|
+
|
|
44
|
+
z_score = 1.2 * (working_capital/total_assets) + 1.4 * (retained_earnings/total_assets) + 3.3 * (ebit/total_assets)
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
"gross_margin_pct": round((gross_profit / revenue) * 100, 2),
|
|
48
|
+
"net_margin_pct": round(net_margin * 100, 2),
|
|
49
|
+
"dupont": {
|
|
50
|
+
"roe": round(roe * 100, 2),
|
|
51
|
+
"net_profit_margin": round(net_margin * 100, 2),
|
|
52
|
+
"asset_turnover": round(asset_turnover, 2),
|
|
53
|
+
"equity_multiplier": round(equity_multiplier, 2)
|
|
54
|
+
},
|
|
55
|
+
"working_capital": {
|
|
56
|
+
"current_ratio": round(current_ratio, 2),
|
|
57
|
+
"quick_ratio": round(quick_ratio, 2)
|
|
58
|
+
},
|
|
59
|
+
"altman_z_score": round(z_score, 2),
|
|
60
|
+
"solvency_risk": "SAFE" if z_score > 2.99 else ("DISTRESS" if z_score < 1.8 else "GREY")
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
def tool_analyze_financial_statements(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
64
|
+
company_name = params.get("company_name", "").upper()
|
|
65
|
+
data = params.get("financials", {})
|
|
66
|
+
|
|
67
|
+
income = data.get("income_statement", {})
|
|
68
|
+
balance = data.get("balance_sheet", {})
|
|
69
|
+
cashflow = data.get("cashflow", {})
|
|
70
|
+
|
|
71
|
+
# Try fetching real data via yfinance if it looks like a ticker and we have no data
|
|
72
|
+
if company_name and len(company_name) <= 5 and not income:
|
|
73
|
+
try:
|
|
74
|
+
import yfinance as yf
|
|
75
|
+
ticker = yf.Ticker(company_name)
|
|
76
|
+
inc_df = ticker.income_stmt
|
|
77
|
+
bal_df = ticker.balance_sheet
|
|
78
|
+
cf_df = ticker.cashflow
|
|
79
|
+
|
|
80
|
+
if not inc_df.empty and not bal_df.empty:
|
|
81
|
+
# Take most recent year
|
|
82
|
+
inc_latest = inc_df.iloc[:, 0]
|
|
83
|
+
bal_latest = bal_df.iloc[:, 0]
|
|
84
|
+
|
|
85
|
+
income = {
|
|
86
|
+
"revenue": inc_latest.get("Total Revenue", 0),
|
|
87
|
+
"cost_of_goods_sold": inc_latest.get("Cost Of Revenue", 0),
|
|
88
|
+
"gross_profit": inc_latest.get("Gross Profit", 0),
|
|
89
|
+
"operating_income": inc_latest.get("Operating Income", 0),
|
|
90
|
+
"net_income": inc_latest.get("Net Income", 0)
|
|
91
|
+
}
|
|
92
|
+
balance = {
|
|
93
|
+
"total_assets": bal_latest.get("Total Assets", 0),
|
|
94
|
+
"total_equity": bal_latest.get("Stockholders Equity", 0),
|
|
95
|
+
"current_assets": bal_latest.get("Current Assets", 0),
|
|
96
|
+
"current_liabilities": bal_latest.get("Current Liabilities", 0),
|
|
97
|
+
"inventory": bal_latest.get("Inventory", 0),
|
|
98
|
+
"retained_earnings": bal_latest.get("Retained Earnings", 0)
|
|
99
|
+
}
|
|
100
|
+
except ImportError:
|
|
101
|
+
pass
|
|
102
|
+
except Exception as e:
|
|
103
|
+
logger.warning(f"yfinance failed for {company_name}: {e}")
|
|
104
|
+
|
|
105
|
+
# No statements, no diagnosis.
|
|
106
|
+
#
|
|
107
|
+
# A "sensible mock" used to fill in here — revenue 12,000,000, net income
|
|
108
|
+
# 2,000,000 — and the result then carried the requested company's name.
|
|
109
|
+
# Asked about a real company whose filings could not be fetched, the tool
|
|
110
|
+
# returned a complete, confident diagnosis of a business that does not
|
|
111
|
+
# exist, labelled with that company's ticker. There is no way for the
|
|
112
|
+
# caller to tell that apart from a real one.
|
|
113
|
+
if not income:
|
|
114
|
+
return {
|
|
115
|
+
"success": False,
|
|
116
|
+
"error": (
|
|
117
|
+
f"No financial statements available"
|
|
118
|
+
f"{f' for {company_name}' if company_name else ''}. "
|
|
119
|
+
"Pass financials={income_statement, balance_sheet, cashflow}, or "
|
|
120
|
+
"give a ticker whose filings yfinance can fetch. "
|
|
121
|
+
"This tool does not estimate missing figures."
|
|
122
|
+
),
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
metrics = compute_financial_metrics(income, balance, cashflow)
|
|
126
|
+
metrics["company_name"] = company_name
|
|
127
|
+
metrics["data_source"] = (
|
|
128
|
+
"caller-supplied statements" if params.get("financials") else f"yfinance:{company_name}"
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
"success": True,
|
|
133
|
+
"data": metrics,
|
|
134
|
+
"summary": (
|
|
135
|
+
f"{company_name} 财务诊断完成(来源:{metrics['data_source']}): 毛利率 {metrics.get('gross_margin_pct')}%,"
|
|
136
|
+
f"净利率 {metrics.get('net_margin_pct')}%,杜邦 ROE {metrics.get('dupont', {}).get('roe')}%,"
|
|
137
|
+
f"偿债安全性 {metrics.get('solvency_risk')} (Altman Z: {metrics.get('altman_z_score')})。"
|
|
138
|
+
),
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
def register_enterprise_finance_tools(tools_dict: Dict[str, Any], schemas_list: List[Dict[str, Any]]) -> int:
|
|
142
|
+
tools_dict["analyze_financial_statements"] = (tool_analyze_financial_statements, "Analyze company financial statements (P&L, Balance Sheet, Cash Flow) and Dupont decomposition")
|
|
143
|
+
schemas_list.append({
|
|
144
|
+
"name": "analyze_financial_statements",
|
|
145
|
+
"description": "Analyze corporate financial statements, working capital cycle, and solvency. If company_name is a ticker (e.g. AAPL), it fetches real Yahoo Finance data.",
|
|
146
|
+
"parameters": {
|
|
147
|
+
"type": "object",
|
|
148
|
+
"properties": {
|
|
149
|
+
"file_path": {"type": "string", "description": "Optional path to JSON financial statements"},
|
|
150
|
+
"financials": {"type": "object", "description": "Optional dict containing income_statement, balance_sheet, cashflow"},
|
|
151
|
+
"company_name": {"type": "string", "description": "Company name or ticker symbol (e.g. AAPL)"},
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
})
|
|
155
|
+
return 1
|
|
156
|
+
|
|
@@ -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)
|