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
aria_code/__init__.py
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"""Aria Code.
|
|
2
|
+
|
|
3
|
+
This package is importable under two roots by design, and has been since the
|
|
4
|
+
src/ restructure: ``aria_code.X`` and a bare ``X``. The tree uses both — 399
|
|
5
|
+
modules import each other bare (``from market_data_client import get_mdc``)
|
|
6
|
+
while others use the package path, and the tests patch whichever root the code
|
|
7
|
+
under test actually uses. tests/test_single_import_root.py exists to keep a
|
|
8
|
+
single *file* from mixing the two.
|
|
9
|
+
|
|
10
|
+
In development both roots resolve because pyproject's
|
|
11
|
+
``pythonpath = [".", "src", "src/aria_code"]`` and tests/conftest.py put them
|
|
12
|
+
there. An installed wheel has neither, so only ``aria_code`` resolved and the
|
|
13
|
+
console script died immediately:
|
|
14
|
+
|
|
15
|
+
$ aria-code --version
|
|
16
|
+
ModuleNotFoundError: No module named 'aria_cli'
|
|
17
|
+
|
|
18
|
+
4.4.1 did not hit this because its wheel predates the restructure — it shipped
|
|
19
|
+
``aria_cli.py`` and 56 other modules at top level, so the bare root *was* the
|
|
20
|
+
package. After the move, nothing put the inner directory on the path.
|
|
21
|
+
|
|
22
|
+
Adding it here rather than shipping a .pth file keeps it inside the package, so
|
|
23
|
+
it applies to `pip install`, `pip install -e .`, a zipapp and a PyInstaller
|
|
24
|
+
bundle alike, and it is visible to anyone reading the package rather than hidden
|
|
25
|
+
in site-packages.
|
|
26
|
+
|
|
27
|
+
Both roots now give the same module object (``_OneModulePerFile`` below), so
|
|
28
|
+
a bare import is an alias rather than a second copy.
|
|
29
|
+
|
|
30
|
+
This is a bridge, not the destination. One root is the goal — v4.4.2 converted
|
|
31
|
+
the tree to ``aria_code.*`` throughout — but converting it means moving every
|
|
32
|
+
test's patch target with it, and doing that silently under a release is how the
|
|
33
|
+
bare-root bugs in this history were introduced.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
import importlib as _importlib
|
|
37
|
+
import importlib.abc as _importlib_abc
|
|
38
|
+
import importlib.machinery as _machinery
|
|
39
|
+
import os as _os
|
|
40
|
+
import sys as _sys
|
|
41
|
+
|
|
42
|
+
_HERE = _os.path.dirname(_os.path.abspath(__file__))
|
|
43
|
+
if _HERE not in _sys.path:
|
|
44
|
+
# Appended, not inserted: a module that legitimately shadows one of these
|
|
45
|
+
# names in the user's own project must keep winning.
|
|
46
|
+
_sys.path.append(_HERE)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class _OneModulePerFile(_importlib_abc.MetaPathFinder, _importlib_abc.Loader):
|
|
50
|
+
"""A bare import of a module in this package returns the ``aria_code.*`` object.
|
|
51
|
+
|
|
52
|
+
Two roots used to mean two module objects per file, each with its own
|
|
53
|
+
globals, and nothing ever errored: a patch, a registry, a cache or an
|
|
54
|
+
exception class applied to one copy simply missed code using the other.
|
|
55
|
+
In one week that was a task list cleared in the copy nobody wrote to, a
|
|
56
|
+
rewind whose conflict error was a different class from the one caught,
|
|
57
|
+
and a test fixture isolating a ledger nobody used while the real one
|
|
58
|
+
filled with pending tasks. Here ``import runtime.checkpoints`` and
|
|
59
|
+
``import aria_code.runtime.checkpoints`` give the same object.
|
|
60
|
+
|
|
61
|
+
Only when the bare name would load a file from this package: a user's
|
|
62
|
+
own ``tools`` or ``utils`` earlier on ``sys.path`` is found first and
|
|
63
|
+
left alone, as before.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
def __init__(self, root: str) -> None:
|
|
67
|
+
self._own: dict = {}
|
|
68
|
+
self.root = _os.path.normcase(root) + _os.sep
|
|
69
|
+
if not getattr(_sys, "frozen", False) and _os.path.isdir(root):
|
|
70
|
+
self.names = {
|
|
71
|
+
entry[:-3] if entry.endswith(".py") else entry
|
|
72
|
+
for entry in _os.listdir(root)
|
|
73
|
+
if entry != "__init__.py" and not entry.startswith(("_", "."))
|
|
74
|
+
and (entry.endswith(".py") or _os.path.isfile(_os.path.join(root, entry, "__init__.py")))
|
|
75
|
+
}
|
|
76
|
+
else:
|
|
77
|
+
# Frozen Python modules live in PYZ, not a physical source tree.
|
|
78
|
+
# PyInstaller's pkgutil hook enumerates that archive even when the
|
|
79
|
+
# package directory is absent, or contains only bundled data files.
|
|
80
|
+
from pkgutil import iter_modules
|
|
81
|
+
self.names = {module.name for module in iter_modules([root])
|
|
82
|
+
if not module.name.startswith(("_", "."))}
|
|
83
|
+
|
|
84
|
+
def find_spec(self, fullname, path=None, target=None):
|
|
85
|
+
if fullname.partition(".")[0] not in self.names:
|
|
86
|
+
return None
|
|
87
|
+
spec = _machinery.PathFinder.find_spec(fullname, path)
|
|
88
|
+
origin = getattr(spec, "origin", None) or ""
|
|
89
|
+
locations = list(getattr(spec, "submodule_search_locations", None) or ())
|
|
90
|
+
mine = [loc for loc in [origin, *locations] if loc and _os.path.normcase(loc).startswith(self.root)]
|
|
91
|
+
if spec is None or not mine:
|
|
92
|
+
return None
|
|
93
|
+
return _machinery.ModuleSpec(fullname, self, is_package=bool(locations))
|
|
94
|
+
|
|
95
|
+
def create_module(self, spec):
|
|
96
|
+
module = _importlib.import_module("aria_code." + spec.name)
|
|
97
|
+
# Keyed by name: importing the real module can alias others first.
|
|
98
|
+
self._own[spec.name] = (module.__spec__, getattr(module, "__loader__", None))
|
|
99
|
+
return module
|
|
100
|
+
|
|
101
|
+
def exec_module(self, module):
|
|
102
|
+
# Already executed under its aria_code.* name. The import system has
|
|
103
|
+
# just stamped this alias's spec on it; put the real one back, or
|
|
104
|
+
# importlib.reload() would re-run this no-op instead of the module.
|
|
105
|
+
module.__spec__, module.__loader__ = self._own.pop(module.__spec__.name)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
if not any(isinstance(finder, _OneModulePerFile) for finder in _sys.meta_path):
|
|
109
|
+
_sys.meta_path.insert(0, _OneModulePerFile(_HERE))
|
|
110
|
+
|
|
111
|
+
del _HERE, _importlib_abc # the finder still uses _os, _importlib and _machinery
|
|
Binary file
|
|
Binary file
|
aria_code/_version.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Single source of truth for the package version.
|
|
2
|
+
|
|
3
|
+
__version__ used to live in aria_cli.py, which meant anything wanting the
|
|
4
|
+
version string had to import the whole interactive CLI — prompt_toolkit,
|
|
5
|
+
bootstrap hooks, the tool registry, all of it. The three consumers each worked
|
|
6
|
+
around that differently: a crash reporter (since removed) and a diagnostics accessor imported
|
|
7
|
+
aria_cli anyway, and the MCP server went to importlib.metadata instead, with a
|
|
8
|
+
comment explaining that pulling in aria_cli was too heavy for a binary whose
|
|
9
|
+
job is speaking JSON-RPC over stdio.
|
|
10
|
+
|
|
11
|
+
Keeping it here costs nothing to import and gives all three the same answer.
|
|
12
|
+
Note that importlib.metadata reports what was *installed*, which is not the
|
|
13
|
+
same thing when running from a source checkout.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
__all__ = ["__version__"]
|
|
19
|
+
|
|
20
|
+
__version__ = "0.167.0"
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
"""Account-scoped durable memory: a cloud snapshot plus a retryable outbox.
|
|
2
|
+
|
|
3
|
+
Only newly captured account facts are queued. Legacy files and repository
|
|
4
|
+
instructions are never uploaded. A failed request never becomes a success.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import uuid
|
|
10
|
+
import os
|
|
11
|
+
from contextlib import contextmanager
|
|
12
|
+
import json
|
|
13
|
+
import threading
|
|
14
|
+
import time
|
|
15
|
+
from typing import Callable
|
|
16
|
+
|
|
17
|
+
from aria_code.account_session import account_id, account_root, get_account_token, read_config
|
|
18
|
+
from aria_code.cloud_memory import CloudMemoryClient
|
|
19
|
+
from aria_code.packages.aria_core.secure_file import write_secret_json
|
|
20
|
+
|
|
21
|
+
_LOCKS: dict[str, threading.RLock] = {}
|
|
22
|
+
_SYNC_LOCKS: dict[str, threading.Lock] = {}
|
|
23
|
+
_LOCK = threading.Lock()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _lock_for(table, key, factory):
|
|
27
|
+
with _LOCK:
|
|
28
|
+
return table.setdefault(str(key), factory())
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@contextmanager
|
|
32
|
+
def _state_lock(path):
|
|
33
|
+
"""Protect read-modify-write across CLI windows as well as threads."""
|
|
34
|
+
with _lock_for(_LOCKS, path, threading.RLock):
|
|
35
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
36
|
+
descriptor = os.open(str(path) + ".lock", os.O_CREAT | os.O_RDWR, 0o600)
|
|
37
|
+
with os.fdopen(descriptor, "r+b") as handle:
|
|
38
|
+
if os.name == "nt":
|
|
39
|
+
import msvcrt
|
|
40
|
+
|
|
41
|
+
handle.seek(0, 2)
|
|
42
|
+
if handle.tell() == 0:
|
|
43
|
+
handle.write(b"0")
|
|
44
|
+
handle.flush()
|
|
45
|
+
handle.seek(0)
|
|
46
|
+
msvcrt.locking(handle.fileno(), msvcrt.LK_LOCK, 1)
|
|
47
|
+
try:
|
|
48
|
+
yield
|
|
49
|
+
finally:
|
|
50
|
+
handle.seek(0)
|
|
51
|
+
msvcrt.locking(handle.fileno(), msvcrt.LK_UNLCK, 1)
|
|
52
|
+
else:
|
|
53
|
+
import fcntl
|
|
54
|
+
|
|
55
|
+
fcntl.flock(handle, fcntl.LOCK_EX)
|
|
56
|
+
try:
|
|
57
|
+
yield
|
|
58
|
+
finally:
|
|
59
|
+
fcntl.flock(handle, fcntl.LOCK_UN)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _write_state(path, data):
|
|
63
|
+
temporary = path.with_name(f".{path.name}.{os.getpid()}.{threading.get_ident()}.tmp")
|
|
64
|
+
try:
|
|
65
|
+
write_secret_json(temporary, data)
|
|
66
|
+
os.replace(temporary, path)
|
|
67
|
+
finally:
|
|
68
|
+
temporary.unlink(missing_ok=True)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class AccountMemory:
|
|
72
|
+
def __init__(self, config: dict | Callable[[], dict] | None = None, save=None):
|
|
73
|
+
self._config = config if config is not None else read_config
|
|
74
|
+
self.save = save
|
|
75
|
+
|
|
76
|
+
def config(self):
|
|
77
|
+
return self._config() if callable(self._config) else self._config
|
|
78
|
+
|
|
79
|
+
def _owner(self):
|
|
80
|
+
config = self.config()
|
|
81
|
+
uid = account_id(config)
|
|
82
|
+
return config, uid, account_root(config) / "cloud-memory.json"
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def _read(path):
|
|
86
|
+
try:
|
|
87
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
88
|
+
return data if isinstance(data, dict) else {}
|
|
89
|
+
except (OSError, ValueError):
|
|
90
|
+
return {}
|
|
91
|
+
|
|
92
|
+
def status(self):
|
|
93
|
+
config, uid, path = self._owner()
|
|
94
|
+
with _state_lock(path):
|
|
95
|
+
data = self._read(path)
|
|
96
|
+
return {
|
|
97
|
+
"account_id": uid,
|
|
98
|
+
"email": config.get("email") or "",
|
|
99
|
+
"enabled": data.get("preferences", {}).get("enabled", True),
|
|
100
|
+
"pending": len(data.get("outbox", [])),
|
|
101
|
+
"last_synced": data.get("last_synced"),
|
|
102
|
+
"error": data.get("error"),
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
def facts(self, *, include_disabled=False):
|
|
106
|
+
_, uid, path = self._owner()
|
|
107
|
+
if not uid:
|
|
108
|
+
return []
|
|
109
|
+
with _state_lock(path):
|
|
110
|
+
data = self._read(path)
|
|
111
|
+
if not include_disabled and data.get("preferences", {}).get("enabled") is False:
|
|
112
|
+
return []
|
|
113
|
+
outbox = data.get("outbox", [])
|
|
114
|
+
hidden = {op["id"] for op in outbox if op.get("op") == "delete"}
|
|
115
|
+
cancelled = set(data.get("cancelled_adds", []))
|
|
116
|
+
facts = [
|
|
117
|
+
f
|
|
118
|
+
for f in data.get("facts", [])
|
|
119
|
+
if f.get("id") not in hidden and (f.get("metadata") or {}).get("client_id") not in cancelled
|
|
120
|
+
]
|
|
121
|
+
seen = {f.get("content") for f in facts}
|
|
122
|
+
for op in outbox:
|
|
123
|
+
if op.get("op") == "add" and op.get("content") not in seen:
|
|
124
|
+
facts.append({"id": op["id"], "content": op["content"], "pending": True})
|
|
125
|
+
seen.add(op["content"])
|
|
126
|
+
return facts
|
|
127
|
+
|
|
128
|
+
def context(self, max_chars=800):
|
|
129
|
+
_, uid, path = self._owner()
|
|
130
|
+
if not uid:
|
|
131
|
+
return ""
|
|
132
|
+
with _state_lock(path):
|
|
133
|
+
preferences = self._read(path).get("preferences", {})
|
|
134
|
+
if preferences.get("enabled") is False:
|
|
135
|
+
return ""
|
|
136
|
+
lines = [str(preferences[key]).strip() for key in ("nickname", "occupation", "about") if preferences.get(key)]
|
|
137
|
+
lines.extend(str(f.get("content", "")) for f in self.facts())
|
|
138
|
+
text = "\n".join(dict.fromkeys(lines))[:max_chars]
|
|
139
|
+
return f"## Account Memory\n{text}\n" if text else ""
|
|
140
|
+
|
|
141
|
+
def add(self, content: str):
|
|
142
|
+
config, uid, path = self._owner()
|
|
143
|
+
content = content.strip()[:4000]
|
|
144
|
+
if not uid or not content:
|
|
145
|
+
return False
|
|
146
|
+
# Stable per queued operation, so a retry is idempotent but an explicit
|
|
147
|
+
# re-add after deletion can create a new fact.
|
|
148
|
+
item_id = uuid.uuid4().hex
|
|
149
|
+
with _state_lock(path):
|
|
150
|
+
data = self._read(path)
|
|
151
|
+
if data.get("preferences", {}).get("enabled") is False or account_id(self.config()) != uid:
|
|
152
|
+
return False
|
|
153
|
+
if any(f.get("content") == content for f in data.get("facts", [])):
|
|
154
|
+
return True
|
|
155
|
+
outbox = data.setdefault("outbox", [])
|
|
156
|
+
if not any(op.get("op") == "add" and op.get("content") == content for op in outbox):
|
|
157
|
+
outbox.append({"op": "add", "id": item_id, "content": content})
|
|
158
|
+
_write_state(path, data)
|
|
159
|
+
return True
|
|
160
|
+
|
|
161
|
+
def forget(self, item_id):
|
|
162
|
+
_, uid, path = self._owner()
|
|
163
|
+
if not uid:
|
|
164
|
+
return False
|
|
165
|
+
with _state_lock(path):
|
|
166
|
+
data = self._read(path)
|
|
167
|
+
pending = data.setdefault("outbox", [])
|
|
168
|
+
local = any(op.get("id") == item_id and op.get("op") == "add" for op in pending)
|
|
169
|
+
if local:
|
|
170
|
+
data["cancelled_adds"] = list(set(data.get("cancelled_adds", [])) | {item_id})
|
|
171
|
+
data["outbox"] = [op for op in pending if op.get("id") != item_id]
|
|
172
|
+
if not local and any(f.get("id") == item_id for f in data.get("facts", [])):
|
|
173
|
+
data["outbox"].append({"op": "delete", "id": item_id})
|
|
174
|
+
_write_state(path, data)
|
|
175
|
+
return True
|
|
176
|
+
|
|
177
|
+
def sync(self, *, force=False):
|
|
178
|
+
config, uid, path = self._owner()
|
|
179
|
+
if not uid:
|
|
180
|
+
return {"ok": False, "reason": "sign-in-required"}
|
|
181
|
+
lock = _lock_for(_SYNC_LOCKS, path, threading.Lock)
|
|
182
|
+
if not lock.acquire(blocking=False):
|
|
183
|
+
return {"ok": False, "reason": "in-progress"}
|
|
184
|
+
state_lock = lambda: _state_lock(path)
|
|
185
|
+
original = config.get("auth_token")
|
|
186
|
+
|
|
187
|
+
def current():
|
|
188
|
+
now = self.config()
|
|
189
|
+
return account_id(now) == uid and now.get("auth_token") == original
|
|
190
|
+
|
|
191
|
+
def update(**fields):
|
|
192
|
+
if not current():
|
|
193
|
+
return
|
|
194
|
+
with state_lock():
|
|
195
|
+
data = self._read(path)
|
|
196
|
+
data.update(fields)
|
|
197
|
+
_write_state(path, data)
|
|
198
|
+
|
|
199
|
+
try:
|
|
200
|
+
with state_lock():
|
|
201
|
+
data = self._read(path)
|
|
202
|
+
if not force and time.time() - data.get("last_attempt", 0) < 60:
|
|
203
|
+
return {"ok": not data.get("error"), "cached": True}
|
|
204
|
+
update(last_attempt=time.time())
|
|
205
|
+
token = get_account_token(config, self.save)
|
|
206
|
+
if token:
|
|
207
|
+
original = token
|
|
208
|
+
if not token or not current():
|
|
209
|
+
update(error="sign-in-required")
|
|
210
|
+
return {"ok": False, "reason": "sign-in-required"}
|
|
211
|
+
from aria_code.apps.cli.endpoint_migration import PRODUCTION_API_URL
|
|
212
|
+
|
|
213
|
+
client = CloudMemoryClient(str(config.get("api_url") or PRODUCTION_API_URL), token)
|
|
214
|
+
preferences = client.get_preferences()
|
|
215
|
+
if not preferences or not current():
|
|
216
|
+
reason = "sign-in-required" if client.last_status == 401 else "service-unavailable"
|
|
217
|
+
update(error=reason)
|
|
218
|
+
return {"ok": False, "reason": reason}
|
|
219
|
+
# A newly disabled switch takes effect even if the next read fails.
|
|
220
|
+
update(preferences=preferences)
|
|
221
|
+
summary = client._request("GET", "/api/v2/memory/summary")
|
|
222
|
+
if summary is None:
|
|
223
|
+
update(error="service-unavailable")
|
|
224
|
+
return {"ok": False, "reason": "service-unavailable"}
|
|
225
|
+
if not current():
|
|
226
|
+
return {"ok": False, "reason": "account-changed"}
|
|
227
|
+
facts = summary.get("facts", [])
|
|
228
|
+
facts = [f for f in facts if isinstance(f, dict) and f.get("id") and isinstance(f.get("content"), str)]
|
|
229
|
+
update(preferences=preferences, facts=facts)
|
|
230
|
+
enabled = preferences.get("enabled") is not False
|
|
231
|
+
with state_lock():
|
|
232
|
+
latest = self._read(path)
|
|
233
|
+
cancelled = set(latest.get("cancelled_adds", []))
|
|
234
|
+
outbox = latest.setdefault("outbox", [])
|
|
235
|
+
for fact in facts:
|
|
236
|
+
if (fact.get("metadata") or {}).get("client_id") in cancelled:
|
|
237
|
+
deletion = {"op": "delete", "id": fact["id"]}
|
|
238
|
+
if deletion not in outbox:
|
|
239
|
+
outbox.append(deletion)
|
|
240
|
+
_write_state(path, latest)
|
|
241
|
+
pending = list(outbox)
|
|
242
|
+
failed = False
|
|
243
|
+
for op in pending[:10]:
|
|
244
|
+
if not enabled and op["op"] == "add":
|
|
245
|
+
continue
|
|
246
|
+
if not current():
|
|
247
|
+
return {"ok": False, "reason": "account-changed"}
|
|
248
|
+
if op["op"] == "add":
|
|
249
|
+
existing = next(
|
|
250
|
+
(
|
|
251
|
+
f
|
|
252
|
+
for f in facts
|
|
253
|
+
if (f.get("metadata") or {}).get("client_id") == op["id"]
|
|
254
|
+
or f.get("content") == op["content"]
|
|
255
|
+
),
|
|
256
|
+
None,
|
|
257
|
+
)
|
|
258
|
+
item = existing or client._request(
|
|
259
|
+
"POST",
|
|
260
|
+
"/api/v2/memory/items",
|
|
261
|
+
body={
|
|
262
|
+
"content": op["content"],
|
|
263
|
+
"client_id": op["id"],
|
|
264
|
+
"scope": "user",
|
|
265
|
+
"kind": "durable",
|
|
266
|
+
"metadata": {"source": "aria-code", "client_id": op["id"]},
|
|
267
|
+
},
|
|
268
|
+
)
|
|
269
|
+
success = isinstance(item, dict) and bool(item.get("id"))
|
|
270
|
+
if success and not existing and not item.get("deleted_at"):
|
|
271
|
+
facts.append(item)
|
|
272
|
+
else:
|
|
273
|
+
success = client.delete_item(op["id"])
|
|
274
|
+
if success:
|
|
275
|
+
facts = [f for f in facts if f.get("id") != op["id"]]
|
|
276
|
+
if not current():
|
|
277
|
+
return {"ok": False, "reason": "account-changed"}
|
|
278
|
+
if not success:
|
|
279
|
+
failed = True
|
|
280
|
+
break
|
|
281
|
+
with state_lock():
|
|
282
|
+
latest = self._read(path)
|
|
283
|
+
latest["outbox"] = [item for item in latest.get("outbox", []) if item != op]
|
|
284
|
+
if op["op"] == "add" and op["id"] in latest.get("cancelled_adds", []) and item.get("id"):
|
|
285
|
+
deletion = {"op": "delete", "id": item["id"]}
|
|
286
|
+
if deletion not in latest["outbox"]:
|
|
287
|
+
latest["outbox"].append(deletion)
|
|
288
|
+
latest["facts"] = facts
|
|
289
|
+
_write_state(path, latest)
|
|
290
|
+
update(last_synced=time.time(), error="pending-retry" if failed else None)
|
|
291
|
+
return {"ok": not failed, "pending": self.status()["pending"], "enabled": enabled}
|
|
292
|
+
except Exception:
|
|
293
|
+
update(error="service-unavailable")
|
|
294
|
+
return {"ok": False, "reason": "service-unavailable"}
|
|
295
|
+
finally:
|
|
296
|
+
lock.release()
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"""Firebase account identity and refresh shared by the CLI and memory client.
|
|
2
|
+
|
|
3
|
+
JWT claims here are a local consistency check, never authorization: the API
|
|
4
|
+
still verifies Firebase's signature/project on every request.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import base64
|
|
10
|
+
import hashlib
|
|
11
|
+
import json
|
|
12
|
+
import time
|
|
13
|
+
import urllib.parse
|
|
14
|
+
import urllib.request
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from typing import Callable
|
|
17
|
+
|
|
18
|
+
from aria_code.packages.aria_core.paths import aria_home
|
|
19
|
+
from aria_code.packages.aria_core.secure_file import write_secret_json
|
|
20
|
+
|
|
21
|
+
PROJECT_ID = "arthera-66e5b"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def read_config() -> dict:
|
|
25
|
+
try:
|
|
26
|
+
value = json.loads((aria_home() / "config.json").read_text(encoding="utf-8"))
|
|
27
|
+
return value if isinstance(value, dict) else {}
|
|
28
|
+
except (OSError, ValueError):
|
|
29
|
+
return {}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def claims_for(token: str) -> dict:
|
|
33
|
+
try:
|
|
34
|
+
encoded = token.split(".")[1]
|
|
35
|
+
claims = json.loads(base64.urlsafe_b64decode(encoded + "=" * (-len(encoded) % 4)))
|
|
36
|
+
if claims.get("aud") != PROJECT_ID or claims.get("iss") != f"https://securetoken.google.com/{PROJECT_ID}":
|
|
37
|
+
return {}
|
|
38
|
+
return claims if isinstance(claims.get("sub"), str) and claims["sub"] else {}
|
|
39
|
+
except (ValueError, IndexError, TypeError, AttributeError):
|
|
40
|
+
return {}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def account_id(config: dict) -> str | None:
|
|
44
|
+
if not config.get("auth_token"):
|
|
45
|
+
return None
|
|
46
|
+
uid = str(config.get("user_id") or "")
|
|
47
|
+
claims = claims_for(str(config["auth_token"]))
|
|
48
|
+
# Never infer identity from email or reuse a different account's token.
|
|
49
|
+
return uid if uid and claims.get("sub") == uid else None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def account_root(config: dict | None = None) -> Path:
|
|
53
|
+
config = read_config() if config is None else config
|
|
54
|
+
uid = account_id(config)
|
|
55
|
+
bucket = hashlib.sha256(uid.encode()).hexdigest() if uid else "anonymous"
|
|
56
|
+
return aria_home() / "accounts" / bucket
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def profile_path(config: dict | None = None) -> Path:
|
|
60
|
+
return account_root(config) / "ARIA.md"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def persist_if_current(config: dict, original: tuple, updates: dict, save: Callable | None = None) -> bool:
|
|
64
|
+
if (config.get("user_id"), config.get("auth_token"), config.get("refresh_token")) != original:
|
|
65
|
+
return False
|
|
66
|
+
config.update(updates)
|
|
67
|
+
if save:
|
|
68
|
+
save(config)
|
|
69
|
+
else:
|
|
70
|
+
disk = read_config()
|
|
71
|
+
if (disk.get("user_id"), disk.get("auth_token"), disk.get("refresh_token")) != original:
|
|
72
|
+
return False
|
|
73
|
+
disk.update(updates)
|
|
74
|
+
write_secret_json(aria_home() / "config.json", disk)
|
|
75
|
+
return True
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def get_account_token(config: dict, save: Callable | None = None, *, force=False) -> str | None:
|
|
79
|
+
uid = account_id(config)
|
|
80
|
+
if not uid:
|
|
81
|
+
return None
|
|
82
|
+
token = str(config["auth_token"])
|
|
83
|
+
claims = claims_for(token)
|
|
84
|
+
try:
|
|
85
|
+
expires = float(claims.get("exp", 0))
|
|
86
|
+
except (ValueError, TypeError):
|
|
87
|
+
return None
|
|
88
|
+
if not force and expires > time.time() + 120:
|
|
89
|
+
return token
|
|
90
|
+
refresh = config.get("refresh_token")
|
|
91
|
+
if not refresh:
|
|
92
|
+
return token if expires > time.time() else None
|
|
93
|
+
original = (uid, token, refresh)
|
|
94
|
+
from aria_code.apps.cli.google_login import FIREBASE_WEB_API_KEY
|
|
95
|
+
|
|
96
|
+
request = urllib.request.Request(
|
|
97
|
+
f"https://securetoken.googleapis.com/v1/token?key={FIREBASE_WEB_API_KEY}",
|
|
98
|
+
data=urllib.parse.urlencode({"grant_type": "refresh_token", "refresh_token": refresh}).encode(),
|
|
99
|
+
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
|
100
|
+
method="POST",
|
|
101
|
+
)
|
|
102
|
+
try:
|
|
103
|
+
with urllib.request.urlopen(request, timeout=8) as response:
|
|
104
|
+
result = json.loads(response.read())
|
|
105
|
+
fresh = result.get("id_token", "")
|
|
106
|
+
fresh_claims = claims_for(fresh)
|
|
107
|
+
if (
|
|
108
|
+
result.get("user_id") != uid
|
|
109
|
+
or fresh_claims.get("sub") != uid
|
|
110
|
+
or float(fresh_claims.get("exp", 0)) <= time.time()
|
|
111
|
+
):
|
|
112
|
+
return None
|
|
113
|
+
updates = {"auth_token": fresh, "refresh_token": result.get("refresh_token") or refresh}
|
|
114
|
+
if isinstance(fresh_claims.get("email"), str):
|
|
115
|
+
updates["email"] = fresh_claims["email"].strip().lower()
|
|
116
|
+
from datetime import datetime, timezone
|
|
117
|
+
|
|
118
|
+
updates["token_expires_at"] = datetime.fromtimestamp(float(fresh_claims["exp"]), timezone.utc).isoformat()
|
|
119
|
+
if not persist_if_current(config, original, updates, save):
|
|
120
|
+
return None
|
|
121
|
+
return fresh
|
|
122
|
+
except Exception:
|
|
123
|
+
# Do not expose tokens, refresh tokens, HTTP bodies or URLs in errors.
|
|
124
|
+
return token if not force and expires > time.time() else None
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def password_session(email: str, password: str) -> dict:
|
|
128
|
+
"""Browserless fallback, using the exact same Firebase account provider."""
|
|
129
|
+
from aria_code.apps.cli.google_login import FIREBASE_WEB_API_KEY
|
|
130
|
+
|
|
131
|
+
request = urllib.request.Request(
|
|
132
|
+
f"https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key={FIREBASE_WEB_API_KEY}",
|
|
133
|
+
data=json.dumps({"email": email, "password": password, "returnSecureToken": True}).encode(),
|
|
134
|
+
headers={"Content-Type": "application/json"},
|
|
135
|
+
method="POST",
|
|
136
|
+
)
|
|
137
|
+
with urllib.request.urlopen(request, timeout=15) as response:
|
|
138
|
+
result = json.loads(response.read())
|
|
139
|
+
token, uid = result.get("idToken"), result.get("localId")
|
|
140
|
+
if not token or claims_for(token).get("sub") != uid:
|
|
141
|
+
raise ValueError("Missing Firebase identity")
|
|
142
|
+
return {
|
|
143
|
+
"auth_token": token,
|
|
144
|
+
"user_id": uid,
|
|
145
|
+
"refresh_token": result.get("refreshToken"),
|
|
146
|
+
"email": result.get("email"),
|
|
147
|
+
"display_name": result.get("displayName"),
|
|
148
|
+
"provider": "password",
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
async def prepare_account(config: dict, save=None) -> str | None:
|
|
153
|
+
"""Refresh credentials, and give memory two seconds before using its cache.
|
|
154
|
+
|
|
155
|
+
The fenced sync may finish in the background; a slow memory service must
|
|
156
|
+
not hold up sending a chat turn. Its status/outbox remains inspectable.
|
|
157
|
+
"""
|
|
158
|
+
import asyncio
|
|
159
|
+
from aria_code.account_memory import AccountMemory
|
|
160
|
+
|
|
161
|
+
token = await asyncio.to_thread(get_account_token, config, save)
|
|
162
|
+
try:
|
|
163
|
+
await asyncio.wait_for(asyncio.shield(asyncio.to_thread(AccountMemory(config, save=save).sync)), timeout=2)
|
|
164
|
+
except asyncio.TimeoutError:
|
|
165
|
+
pass
|
|
166
|
+
return token
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""ADK application packages shipped as optional Aria Code integrations."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Google ADK entrypoint package for Aria's read-only code reviewer."""
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Google ADK entrypoint: a bounded reviewer for pasted code."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
from google.adk.agents.llm_agent import Agent
|
|
8
|
+
|
|
9
|
+
from aria_code.packages.adk_bridge import CodeReviewTools
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
_tools = CodeReviewTools()
|
|
13
|
+
|
|
14
|
+
root_agent = Agent(
|
|
15
|
+
model=os.getenv("ARIA_ADK_MODEL", "gemini-3.8-flash"),
|
|
16
|
+
name="aria_code_review",
|
|
17
|
+
description="A read-only code reviewer for user-submitted source text.",
|
|
18
|
+
instruction="""You are Aria Code Review, a careful software reviewer.
|
|
19
|
+
|
|
20
|
+
Ask the user to paste the relevant source code when it has not been supplied.
|
|
21
|
+
Use review_code for deterministic findings and preserve its severity, line,
|
|
22
|
+
rule, and limitations. Never claim to have opened a local path, accessed a
|
|
23
|
+
repository, run a command, changed a file, or executed tests: this ADK agent
|
|
24
|
+
has none of those capabilities.
|
|
25
|
+
|
|
26
|
+
Explain only findings supported by the submitted code. Separate deterministic
|
|
27
|
+
findings from suggestions, and recommend a test or validation step where
|
|
28
|
+
appropriate. Do not expose credentials appearing in source; tell the user to
|
|
29
|
+
revoke and rotate any exposed credential instead.
|
|
30
|
+
""",
|
|
31
|
+
tools=[_tools.review_code],
|
|
32
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Read-only Aria market-research agent for Google ADK."""
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Google ADK entrypoint: ``adk web adk_apps`` discovers ``aria_research``."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
from google.adk.agents.llm_agent import Agent
|
|
8
|
+
|
|
9
|
+
from aria_code.packages.adk_bridge import MarketResearchTools
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
_tools = MarketResearchTools()
|
|
13
|
+
|
|
14
|
+
root_agent = Agent(
|
|
15
|
+
model=os.getenv("ARIA_ADK_MODEL", "gemini-3.8-flash"),
|
|
16
|
+
name="aria_research",
|
|
17
|
+
description="A read-only market-research assistant for Aria Code and Arthera.",
|
|
18
|
+
instruction="""You are Aria Research, a careful financial-research assistant.
|
|
19
|
+
|
|
20
|
+
Use get_market_snapshot for live market facts and explicitly identify its data
|
|
21
|
+
quality, timestamp, warnings, and source limitations. Use get_market_data_health
|
|
22
|
+
when a data result is missing, stale, or conflicting. Do not invent prices,
|
|
23
|
+
returns, news, citations, positions, or tool output.
|
|
24
|
+
|
|
25
|
+
This agent is research-only. Never claim to execute, recommend, place, modify,
|
|
26
|
+
or schedule trades. Do not request credentials. State clearly that your output
|
|
27
|
+
is research assistance, not investment advice. For quantitative conclusions,
|
|
28
|
+
separate observed facts from hypotheses and mention material uncertainty.
|
|
29
|
+
""",
|
|
30
|
+
tools=[_tools.get_market_snapshot, _tools.get_market_data_health],
|
|
31
|
+
)
|