alysis-code 0.13.3__tar.gz → 0.13.4__tar.gz
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.
- {alysis_code-0.13.3 → alysis_code-0.13.4}/PKG-INFO +1 -1
- {alysis_code-0.13.3 → alysis_code-0.13.4}/docs/CHANGELOG.md +29 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/pyproject.toml +1 -1
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/__init__.py +1 -1
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/config_flow.py +82 -2
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/content.py +21 -5
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/gemini_generate_content.py +234 -2
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/openai_compat.py +19 -1
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/model_registry.py +888 -73
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/profile_presets.py +442 -234
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/reasoning_contracts.py +162 -20
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/web_search.py +3 -2
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/web_search_provider_adapters.py +83 -17
- {alysis_code-0.13.3 → alysis_code-0.13.4}/.gitignore +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/LICENSE +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/NOTICE +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/README.md +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/__main__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/_build_info.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/account_login.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/README.md +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/acceptance_contract.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/blast_radius.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/cache_keepalive.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/completion_certificate.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/completion_gate.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/empty_response_stall.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/errors.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/llm_calls.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/mutation_classification.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/prompt_context.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/read_ledger.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/regression_baseline.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/reproduction_first.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/sensitive_output.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/session.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/steering.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/subagent_execution.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/subagent_workspace.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/tools_assembly.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/turn/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/turn/core.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/turn/events.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/turn/exploration.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/turn/interventions.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/turn/read_cache.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/turn/snapshot.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/turn_contract.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/turn_path.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/verification.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/verification_commands.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent/verification_evidence.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent_loop.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent_runtimes/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent_runtimes/base.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent_runtimes/builtins.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent_runtimes/codex_cli.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent_runtimes/host.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent_runtimes/registry.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agent_runtimes/service.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agentbox_client.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/agentbox_integration.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/alysis_cloud.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/approval_scope.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/README.md +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/asset_read_core.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/budget_allocator.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/comprehender.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/index.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/ingestion.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/legacy_migration.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/models.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/ocr.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-000.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-001.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-002.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-003.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-004.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-005.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-006.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-007.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-008.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-009.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-010.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-011.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-012.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-013.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-014.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-015.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-016.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-017.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-018.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-019.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/ascii/f-020.txt +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/index.html +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/owl/show-owl.sh +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/paths.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/plan_binding.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/planner_context.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/planner_tools.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/prompts.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/replanner_context.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/surface.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/untrusted_content.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/usage_logger.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/worker_mirror.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/worker_section.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/assets/worker_tools.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/atomic_io.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/auth_diagnostics.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/background_runner.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/branding.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/budget_policy.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/build_identity.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/builtin_hooks/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/builtin_hooks/notify_done_windows.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/bwrap_etc.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cancellation.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/capabilities.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/chatgpt_codex_static_provider.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/assets_cli.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/assets_modal.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/chat/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/chat/commands.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/chat/loop.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/chat/mid_turn_policy.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/chat/rendering.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/chat/state.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/chat_resume.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/chat_slash_completer.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/_shared.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/auth.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/chat_resume_helpers.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/chat_state.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/chat_status.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/chat_terminal.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/chat_tui_panels.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/cli_common.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/cli_surface.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/config.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/conventions.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/execution_helpers.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/extensions.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/forge.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/forge_asset_view.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/forge_helpers.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/hooks.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/ide_bridge.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/mcp.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/profile.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/prompt_helpers.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/report.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/root.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/sandbox.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/server.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/sessions.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/skills.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/startup.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/tools.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/update.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/commands/welcome.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/config_menu.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/forge.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/forge_recovery.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/setup_wizard.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/app.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/config.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/config_overlay.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/footer.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/forge_status.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/markdown.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/owl.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/plan_meta.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/selection_bindings.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/setup_app.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/setup_flow.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/state.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/subagent_identity.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/subagent_panel.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/surface.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/transcript.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/update_prompt.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/cli_impl/tui/workspace_guard.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/clipboard.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/code_review.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/compaction/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/compaction/conversation_compactor.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/compaction/importance.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/compaction/settings.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/compaction/tool_output_offload.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/config.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/conflict_auto_resolver.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/context/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/context/tool_schema_budgeter.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/crash_diagnostics.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/custom_tools/README.md +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/custom_tools/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/custom_tools/discovery.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/custom_tools/runtime.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/custom_tools/session.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/custom_tools/trust.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/diff_paths.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/direction_change.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/dispatch_timing.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/durable_service_manager.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/edit_discipline.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/error_text.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/execution_budget.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/execution_context.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/execution_deadline.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/execution_shared.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/extensions/README.md +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/extensions/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/extensions/activation.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/extensions/install.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/extensions/manifest.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/extensions/models.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/extensions/paths.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/extensions/registry.json +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/extensions/registry.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/extensions/state.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/extensions/workspace_trust.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/failed_task_evidence.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/failure_category.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/feedback_report.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/file_classification.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/forge.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/forge_completion.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/forge_events.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/frontmatter_utils.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/git_evidence.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/git_ops.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/git_safe.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/git_worktrees.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/hooks/README.md +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/hooks/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/hooks/audit.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/hooks/config.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/hooks/dispatcher.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/hooks/models.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/hooks/trust.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/host_actions.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/host_browser.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/activity_events.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/approvals.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/artifacts.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/browser_egress_proxy.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/cdp_websocket_transport.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/change_ledger.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/context_blocks.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/event_stream.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/forge_protocol.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/forge_request_ledger.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/health.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/managed_browser.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/management_protocol.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/mcp_oauth_coordinator.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/mcp_oauth_lifecycle.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/prompt_queue.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/protocol.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/resumable_swarm.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/session_search.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/stdio_bridge.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/structured_state.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/ide/swarm_protocol.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/integration_gate.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/interactive_input_guard.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/interactive_plan_mode.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/internal_artifacts.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/knowledge_base.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/knowledge_capture.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/knowledge_librarian.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/language_policy.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/litellm_static_provider.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/anthropic_messages.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/base.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/cache_capabilities.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/cache_control_blocks.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/cache_policy.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/factory.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/gemini_interactions.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/metadata.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/openai_responses.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/protocols.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/provider_limits.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/request_plan.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/request_shape.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/streaming.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/temperature_compat.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/types.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm/usage_normalization.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/llm_error_display.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/logging_redaction.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/managed_host_deadline.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/README.md +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/client.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/config.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/errors.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/forge_scope.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/jsonrpc.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/manager.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/models.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/oauth.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/oauth_runtime.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/oauth_store.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/prompts.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/resources.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/roots.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/server_requests.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/token_store.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/transport_http.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/transport_stdio.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/mcp/untrusted_content.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/merge_conflict_reviewer.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/model_catalog/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/model_catalog/chatgpt_codex_subscription_snapshot.json +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/model_catalog/litellm_model_prices_snapshot.json +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/model_catalog/litellm_model_prices_snapshot.meta.json +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/model_metadata_policy.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/model_metadata_utils.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/model_router.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/permission_policy.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/personas.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/pipeline_facts.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/plan_assistant.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/plan_mode.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/plan_reconciliation.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/plan_repair.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/plan_validation.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/planning_constraints.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/policy.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/preview_server.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/process_reaping.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/profiles.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/provider_auth/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/provider_auth/base.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/provider_auth/openai_codex.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/provider_auth/registry.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/provider_auth/store.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/provider_diagnostics.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/provider_model_catalog.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/provider_telemetry.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/provider_url.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/remote_sync.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/replanning.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/repo_scan.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/request_estimation.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/review_gate.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/run_lock.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/run_outcome.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/run_provenance.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/run_state.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/runtime_artifacts.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/runtime_context_features.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/runtime_kind.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/safety/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/safety/mcp_sanitize.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/safety/safe_http.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/safety/subagent_report.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/sandbox_doctor.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/sandbox_runner.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/sandbox_settings.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/serialized_paths.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/server/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/server/app.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/server/auth.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/server/job_config.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/server/settings.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/server/store.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/server/worker_runner.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/service_persistence.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/session_artifacts.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/session_metrics.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/session_store.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/README.md +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/conventions.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/discovery.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/eval_models.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/eval_runner.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/evals.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/install.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/loader.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/matching.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/models.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/paths.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/prompting.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/scaffold.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/state.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/transactions.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/skills/validation.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/step_budget.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/subagent_labels.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/subagents.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/surface/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/surface/base.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/surface/console.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/surface/events.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/surface/hidden_surface.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/surface/noop_surface.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/surface/rich_surface.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/surface/styles.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/surface/theme.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/surface/types.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/swarm_backend.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/swarm_orchestrator.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/swarm_scheduler.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/swarm_trace.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/swarm_worker.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/swarm_write_guard.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/task_dependencies.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/task_readiness.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/task_scope.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/terminal_manager.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/terminal_ownership.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/text_normalization.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/token_budget.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/README.md +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/__init__.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/artifacts.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/availability.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/fs.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/git.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/history.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/http_timeout.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/image_generation.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/registry.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/repo_map.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/search.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/shell.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/symbols.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/test_discovery.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/web.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/web_search_dashscope.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/web_search_ddgs.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/tools/web_search_tavily.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/transport_retry.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/updates.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/usage_tracker.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/verification_command_analysis.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/verification_contract.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/verification_failure_summary.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/verification_repair.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/verify_gate.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/web_research.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/web_search_adapters.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/web_search_policy.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/workspace_binding.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/workspace_binding_ui.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/workspace_context.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/workspace_isolation.py +0 -0
- {alysis_code-0.13.3 → alysis_code-0.13.4}/src/alysis_code/workspace_provisioning.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: alysis-code
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.4
|
|
4
4
|
Summary: Local CLI coding agent powered by any API.
|
|
5
5
|
Project-URL: Changelog, https://github.com/AlysisAi/alysis-code/blob/main/docs/CHANGELOG.md
|
|
6
6
|
Project-URL: Documentation, https://github.com/AlysisAi/alysis-code/tree/main/docs
|
|
@@ -408,6 +408,35 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
408
408
|
Workspace-target extraction also keeps extensionless dotfiles such as `.npmrc` available to
|
|
409
409
|
verification selection.
|
|
410
410
|
|
|
411
|
+
## [0.13.4] - 2026-09-05
|
|
412
|
+
|
|
413
|
+
Model-catalog and TUI-access refresh.
|
|
414
|
+
|
|
415
|
+
### Added
|
|
416
|
+
|
|
417
|
+
- Added GPT-6 Astra as the default OpenAI model, with aliases, pricing, context-window,
|
|
418
|
+
reasoning, OpenRouter, and ChatGPT-subscription metadata.
|
|
419
|
+
- Added newly available first-party and gateway routes for Claude Fable 5.1, Gemini 3.8
|
|
420
|
+
Flash, Qwen 3.8, GLM-5.3, Kimi K3, Doubao Seed 2.1, DeepSeek V4 snapshots, Grok 4.6,
|
|
421
|
+
and related hosted variants.
|
|
422
|
+
|
|
423
|
+
### Changed
|
|
424
|
+
|
|
425
|
+
- Refreshed every hosted preset's model picker, aliases, validation model, retirement
|
|
426
|
+
mappings, pricing, context limits, and reasoning contracts against provider catalogs.
|
|
427
|
+
- Updated TUI model labels to preserve vendor naming and made profile pickers show each
|
|
428
|
+
profile's model, host, active state, retired-model state, and duplicates.
|
|
429
|
+
- Migrated the Perplexity preset from the retiring Sonar Chat Completions endpoint to the
|
|
430
|
+
Agent API, including hosted web search and saved-profile migration.
|
|
431
|
+
- Replaced the OpenAI economy and validation model with GPT-5.6 Luna and kept
|
|
432
|
+
GPT-5.3 Codex limited to the Responses preset.
|
|
433
|
+
|
|
434
|
+
### Fixed
|
|
435
|
+
|
|
436
|
+
- OpenAI Chat Completions now uses `max_completion_tokens` for GPT-5 and newer models.
|
|
437
|
+
- Native Gemini tool and response schemas are projected onto Gemini's supported OpenAPI
|
|
438
|
+
subset before requests are sent.
|
|
439
|
+
|
|
411
440
|
## [0.13.3] - 2026-08-28
|
|
412
441
|
|
|
413
442
|
### Fixed
|
|
@@ -37,6 +37,8 @@ from ...config import (
|
|
|
37
37
|
from ...llm.protocols import validate_reasoning_trace_adapter_for_protocol
|
|
38
38
|
from ...profile_presets import (
|
|
39
39
|
PROFILE_PRESETS,
|
|
40
|
+
canonical_model_alias_for_preset,
|
|
41
|
+
find_preset_for_profile,
|
|
40
42
|
make_profile_from_preset,
|
|
41
43
|
preset_selection_label,
|
|
42
44
|
)
|
|
@@ -184,6 +186,75 @@ def _short_preset_description(preset: Any) -> str:
|
|
|
184
186
|
return host or "any OpenAI-compatible base URL"
|
|
185
187
|
|
|
186
188
|
|
|
189
|
+
def _profile_identity(raw: Any) -> tuple[str, str, str]:
|
|
190
|
+
"""(protocol, normalized base URL, casefolded model) for duplicate detection."""
|
|
191
|
+
profile = raw if isinstance(raw, dict) else {}
|
|
192
|
+
protocol = str(profile.get("protocol") or "openai_compat").strip()
|
|
193
|
+
base_url = str(profile.get("base_url") or "").strip().rstrip("/")
|
|
194
|
+
model = str(profile.get("default_model") or "").strip().casefold()
|
|
195
|
+
return protocol, base_url, model
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def _profile_retired_model_replacement(name: str, raw: Any) -> str:
|
|
199
|
+
"""The catalog's replacement id when a saved profile pins a retired model id.
|
|
200
|
+
|
|
201
|
+
Empty when the model is current, unknown, or the profile matches no
|
|
202
|
+
preset (custom endpoints cannot be judged offline).
|
|
203
|
+
"""
|
|
204
|
+
profile = raw if isinstance(raw, dict) else {}
|
|
205
|
+
model = str(profile.get("default_model") or "").strip()
|
|
206
|
+
if not model:
|
|
207
|
+
return ""
|
|
208
|
+
try:
|
|
209
|
+
spec = ProfileSpec(
|
|
210
|
+
name=name,
|
|
211
|
+
protocol=str(profile.get("protocol") or "openai_compat").strip(),
|
|
212
|
+
base_url=str(profile.get("base_url") or "").strip(),
|
|
213
|
+
default_model=model,
|
|
214
|
+
)
|
|
215
|
+
preset = find_preset_for_profile(spec)
|
|
216
|
+
except Exception: # noqa: BLE001 - a malformed saved profile must not break the picker
|
|
217
|
+
return ""
|
|
218
|
+
if preset is None:
|
|
219
|
+
return ""
|
|
220
|
+
canonical = canonical_model_alias_for_preset(preset, model)
|
|
221
|
+
return canonical if canonical != model else ""
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def _profile_row_descriptions(profiles: dict[str, Any], *, active: str | None) -> dict[str, str]:
|
|
225
|
+
"""One summary line per saved profile: ``model · host`` plus what needs attention.
|
|
226
|
+
|
|
227
|
+
The bare name list hid everything that matters when choosing or pruning a
|
|
228
|
+
profile — which model it pins, which endpoint it hits, whether that model
|
|
229
|
+
id has been retired (the catalog will remap it, but the profile should be
|
|
230
|
+
updated), and whether it duplicates another profile.
|
|
231
|
+
"""
|
|
232
|
+
identities: dict[tuple[str, str, str], list[str]] = {}
|
|
233
|
+
for name in sorted(profiles):
|
|
234
|
+
identities.setdefault(_profile_identity(profiles[name]), []).append(name)
|
|
235
|
+
|
|
236
|
+
descriptions: dict[str, str] = {}
|
|
237
|
+
for name in sorted(profiles):
|
|
238
|
+
raw = profiles[name]
|
|
239
|
+
profile = raw if isinstance(raw, dict) else {}
|
|
240
|
+
model = str(profile.get("default_model") or "").strip()
|
|
241
|
+
host = urlparse(str(profile.get("base_url") or "").strip()).netloc
|
|
242
|
+
parts: list[str] = []
|
|
243
|
+
if name == active:
|
|
244
|
+
parts.append("active")
|
|
245
|
+
parts.append(model or "no model")
|
|
246
|
+
if host:
|
|
247
|
+
parts.append(host)
|
|
248
|
+
replacement = _profile_retired_model_replacement(name, raw)
|
|
249
|
+
if replacement:
|
|
250
|
+
parts.append(f"retired → {replacement}")
|
|
251
|
+
twins = [other for other in identities.get(_profile_identity(raw), []) if other != name]
|
|
252
|
+
if twins and model:
|
|
253
|
+
parts.append(f"same as {twins[0]}")
|
|
254
|
+
descriptions[name] = " · ".join(parts)
|
|
255
|
+
return descriptions
|
|
256
|
+
|
|
257
|
+
|
|
187
258
|
# stage → interaction mode, so the overlay's key-binding filters don't have to
|
|
188
259
|
# build a full :class:`Screen` on every repaint.
|
|
189
260
|
_STAGE_MODE: dict[str, Mode] = {
|
|
@@ -1479,10 +1550,13 @@ class ConfigFlow:
|
|
|
1479
1550
|
)
|
|
1480
1551
|
|
|
1481
1552
|
def _screen_provider_switch(self) -> Screen:
|
|
1553
|
+
descriptions = _profile_row_descriptions(
|
|
1554
|
+
self.state.profiles, active=self.state.active_profile
|
|
1555
|
+
)
|
|
1482
1556
|
rows = [
|
|
1483
1557
|
Row(
|
|
1484
1558
|
label=name,
|
|
1485
|
-
description=
|
|
1559
|
+
description=descriptions.get(name, ""),
|
|
1486
1560
|
value=name,
|
|
1487
1561
|
current=name == self.state.active_profile,
|
|
1488
1562
|
)
|
|
@@ -1609,7 +1683,13 @@ class ConfigFlow:
|
|
|
1609
1683
|
)
|
|
1610
1684
|
|
|
1611
1685
|
def _screen_provider_remove(self) -> Screen:
|
|
1612
|
-
|
|
1686
|
+
descriptions = _profile_row_descriptions(
|
|
1687
|
+
self.state.profiles, active=self.state.active_profile
|
|
1688
|
+
)
|
|
1689
|
+
rows = [
|
|
1690
|
+
Row(label=name, description=descriptions.get(name, ""), value=name)
|
|
1691
|
+
for name in sorted(self.state.profiles)
|
|
1692
|
+
]
|
|
1613
1693
|
return Screen(
|
|
1614
1694
|
stage="provider_remove",
|
|
1615
1695
|
mode="list",
|
|
@@ -35,11 +35,18 @@ _ACRONYMS = {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
|
|
38
|
+
# Families whose vendors hyphenate the version onto the name ("GPT-6 Astra",
|
|
39
|
+
# "GPT-5.6 Terra", "GLM-5.3"). Everything else keeps a space ("Gemini 3.8
|
|
40
|
+
# Flash", "Claude Opus 5", "Kimi K3"), which matches those vendors' naming.
|
|
41
|
+
_HYPHENATED_VERSION_FAMILIES = frozenset({"GPT", "GLM"})
|
|
42
|
+
|
|
43
|
+
|
|
38
44
|
def pretty_model_label(model: str | None) -> str:
|
|
39
45
|
"""Turn a raw model id into a friendly footer label.
|
|
40
46
|
|
|
41
|
-
``deepseek-chat`` -> ``DeepSeek Chat``; ``gpt-
|
|
42
|
-
to the raw id when there is nothing
|
|
47
|
+
``deepseek-chat`` -> ``DeepSeek Chat``; ``gpt-6-astra`` -> ``GPT-6 Astra``;
|
|
48
|
+
``gpt-4o`` -> ``GPT-4o``. Falls back to the raw id when there is nothing
|
|
49
|
+
sensible to do.
|
|
43
50
|
"""
|
|
44
51
|
raw = (model or "").strip()
|
|
45
52
|
if not raw:
|
|
@@ -50,11 +57,20 @@ def pretty_model_label(model: str | None) -> str:
|
|
|
50
57
|
for token in tokens:
|
|
51
58
|
low = token.lower()
|
|
52
59
|
if low in _ACRONYMS:
|
|
53
|
-
|
|
60
|
+
word = _ACRONYMS[low]
|
|
54
61
|
elif token.isupper():
|
|
55
|
-
|
|
62
|
+
word = token
|
|
56
63
|
else:
|
|
57
|
-
|
|
64
|
+
word = token[:1].upper() + token[1:]
|
|
65
|
+
if out and out[-1] in _HYPHENATED_VERSION_FAMILIES and word[:1].isdigit():
|
|
66
|
+
out[-1] = f"{out[-1]}-{word}"
|
|
67
|
+
continue
|
|
68
|
+
# Ids that cannot carry a dot spell "5.1" as "5-1" (claude-fable-5-1,
|
|
69
|
+
# doubao-seed-2-1-pro): two adjacent bare numbers are one version.
|
|
70
|
+
if out and out[-1].isdigit() and word.isdigit():
|
|
71
|
+
out[-1] = f"{out[-1]}.{word}"
|
|
72
|
+
continue
|
|
73
|
+
out.append(word)
|
|
58
74
|
return " ".join(out) or raw
|
|
59
75
|
|
|
60
76
|
|
|
@@ -447,6 +447,232 @@ class _GeminiToolMapping:
|
|
|
447
447
|
include_server_side_tool_invocations: bool
|
|
448
448
|
|
|
449
449
|
|
|
450
|
+
# Gemini's ``Schema`` message is an OpenAPI 3.0 subset, not JSON Schema. Any
|
|
451
|
+
# other keyword is a hard 400 ("Unknown name ... Cannot find field"), and the
|
|
452
|
+
# tool registry, MCP servers and custom tools all emit plain JSON Schema
|
|
453
|
+
# (``additionalProperties``, ``uniqueItems``, ``$ref`` ...). Everything not in
|
|
454
|
+
# this set is dropped or rewritten before the declaration leaves the client.
|
|
455
|
+
_GEMINI_SCHEMA_FIELDS: frozenset[str] = frozenset(
|
|
456
|
+
{
|
|
457
|
+
"type",
|
|
458
|
+
"format",
|
|
459
|
+
"title",
|
|
460
|
+
"description",
|
|
461
|
+
"nullable",
|
|
462
|
+
"enum",
|
|
463
|
+
"maxItems",
|
|
464
|
+
"minItems",
|
|
465
|
+
"properties",
|
|
466
|
+
"required",
|
|
467
|
+
"minProperties",
|
|
468
|
+
"maxProperties",
|
|
469
|
+
"minLength",
|
|
470
|
+
"maxLength",
|
|
471
|
+
"pattern",
|
|
472
|
+
"example",
|
|
473
|
+
"anyOf",
|
|
474
|
+
"propertyOrdering",
|
|
475
|
+
"default",
|
|
476
|
+
"items",
|
|
477
|
+
"minimum",
|
|
478
|
+
"maximum",
|
|
479
|
+
}
|
|
480
|
+
)
|
|
481
|
+
# ``format`` is validated per type; unknown values are rejected outright.
|
|
482
|
+
_GEMINI_SCHEMA_FORMATS: dict[str, frozenset[str]] = {
|
|
483
|
+
"string": frozenset({"date-time", "enum"}),
|
|
484
|
+
"number": frozenset({"float", "double"}),
|
|
485
|
+
"integer": frozenset({"int32", "int64"}),
|
|
486
|
+
}
|
|
487
|
+
_GEMINI_SCHEMA_TYPES: frozenset[str] = frozenset(
|
|
488
|
+
{"string", "number", "integer", "boolean", "array", "object", "null"}
|
|
489
|
+
)
|
|
490
|
+
_GEMINI_SCHEMA_MAX_DEPTH = 32
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
def _resolve_local_schema_ref(ref: str, root: dict[str, Any]) -> dict[str, Any] | None:
|
|
494
|
+
"""Resolve ``#/$defs/x`` / ``#/definitions/x`` style pointers inside ``root``."""
|
|
495
|
+
if not ref.startswith("#/"):
|
|
496
|
+
return None
|
|
497
|
+
node: Any = root
|
|
498
|
+
for raw_part in ref[2:].split("/"):
|
|
499
|
+
part = raw_part.replace("~1", "/").replace("~0", "~")
|
|
500
|
+
if not isinstance(node, dict) or part not in node:
|
|
501
|
+
return None
|
|
502
|
+
node = node[part]
|
|
503
|
+
return node if isinstance(node, dict) else None
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
def _gemini_schema(
|
|
507
|
+
schema: Any,
|
|
508
|
+
*,
|
|
509
|
+
root: dict[str, Any] | None = None,
|
|
510
|
+
depth: int = 0,
|
|
511
|
+
) -> dict[str, Any]:
|
|
512
|
+
"""Project an arbitrary JSON Schema onto Gemini's ``Schema`` subset.
|
|
513
|
+
|
|
514
|
+
Unknown keywords are dropped; ``const`` becomes a one-value ``enum``;
|
|
515
|
+
``oneOf`` becomes ``anyOf``; a single-branch ``allOf`` is merged; union
|
|
516
|
+
``type`` lists become ``nullable`` + ``anyOf``; local ``$ref`` pointers are
|
|
517
|
+
inlined; ``required`` is trimmed to declared properties; ``format`` values
|
|
518
|
+
Gemini does not validate are removed.
|
|
519
|
+
"""
|
|
520
|
+
if not isinstance(schema, dict):
|
|
521
|
+
return {}
|
|
522
|
+
if depth > _GEMINI_SCHEMA_MAX_DEPTH:
|
|
523
|
+
return {}
|
|
524
|
+
root_schema = root if root is not None else schema
|
|
525
|
+
|
|
526
|
+
ref = schema.get("$ref")
|
|
527
|
+
if isinstance(ref, str):
|
|
528
|
+
target = _resolve_local_schema_ref(ref, root_schema)
|
|
529
|
+
merged: dict[str, Any] = dict(target or {})
|
|
530
|
+
merged.update({key: value for key, value in schema.items() if key != "$ref"})
|
|
531
|
+
if target is None and len(merged) == 0:
|
|
532
|
+
return {}
|
|
533
|
+
return _gemini_schema(merged, root=root_schema, depth=depth + 1)
|
|
534
|
+
|
|
535
|
+
working: dict[str, Any] = dict(schema)
|
|
536
|
+
all_of = working.pop("allOf", None)
|
|
537
|
+
if isinstance(all_of, list):
|
|
538
|
+
branches = [branch for branch in all_of if isinstance(branch, dict)]
|
|
539
|
+
if len(branches) == 1:
|
|
540
|
+
merged_all = dict(branches[0])
|
|
541
|
+
merged_all.update(working)
|
|
542
|
+
working = merged_all
|
|
543
|
+
one_of = working.pop("oneOf", None)
|
|
544
|
+
if isinstance(one_of, list) and "anyOf" not in working:
|
|
545
|
+
working["anyOf"] = one_of
|
|
546
|
+
if "const" in working and "enum" not in working:
|
|
547
|
+
working["enum"] = [working["const"]]
|
|
548
|
+
working.pop("const", None)
|
|
549
|
+
|
|
550
|
+
out: dict[str, Any] = {}
|
|
551
|
+
raw_type = working.get("type")
|
|
552
|
+
nullable = bool(working.get("nullable"))
|
|
553
|
+
resolved_type: str | None = None
|
|
554
|
+
if isinstance(raw_type, list):
|
|
555
|
+
candidates = [str(item).strip().lower() for item in raw_type if isinstance(item, str)]
|
|
556
|
+
if "null" in candidates:
|
|
557
|
+
nullable = True
|
|
558
|
+
non_null = [item for item in candidates if item != "null" and item in _GEMINI_SCHEMA_TYPES]
|
|
559
|
+
if len(non_null) == 1:
|
|
560
|
+
resolved_type = non_null[0]
|
|
561
|
+
elif len(non_null) > 1 and "anyOf" not in working:
|
|
562
|
+
working["anyOf"] = [{"type": item} for item in non_null]
|
|
563
|
+
elif isinstance(raw_type, str):
|
|
564
|
+
candidate = raw_type.strip().lower()
|
|
565
|
+
if candidate == "null":
|
|
566
|
+
nullable = True
|
|
567
|
+
elif candidate in _GEMINI_SCHEMA_TYPES:
|
|
568
|
+
resolved_type = candidate
|
|
569
|
+
if resolved_type is not None:
|
|
570
|
+
out["type"] = resolved_type
|
|
571
|
+
if nullable:
|
|
572
|
+
out["nullable"] = True
|
|
573
|
+
|
|
574
|
+
for key in ("title", "description", "pattern"):
|
|
575
|
+
value = working.get(key)
|
|
576
|
+
if isinstance(value, str) and value:
|
|
577
|
+
out[key] = value
|
|
578
|
+
for key in (
|
|
579
|
+
"minItems",
|
|
580
|
+
"maxItems",
|
|
581
|
+
"minProperties",
|
|
582
|
+
"maxProperties",
|
|
583
|
+
"minLength",
|
|
584
|
+
"maxLength",
|
|
585
|
+
):
|
|
586
|
+
value = working.get(key)
|
|
587
|
+
if isinstance(value, int) and not isinstance(value, bool) and value >= 0:
|
|
588
|
+
out[key] = value
|
|
589
|
+
for key in ("minimum", "maximum"):
|
|
590
|
+
value = working.get(key)
|
|
591
|
+
if isinstance(value, (int, float)) and not isinstance(value, bool):
|
|
592
|
+
out[key] = value
|
|
593
|
+
if "default" in working and working["default"] is not None:
|
|
594
|
+
out["default"] = copy.deepcopy(working["default"])
|
|
595
|
+
if "example" in working and working["example"] is not None:
|
|
596
|
+
out["example"] = copy.deepcopy(working["example"])
|
|
597
|
+
|
|
598
|
+
fmt = working.get("format")
|
|
599
|
+
if isinstance(fmt, str) and resolved_type in _GEMINI_SCHEMA_FORMATS:
|
|
600
|
+
if fmt in _GEMINI_SCHEMA_FORMATS[resolved_type]:
|
|
601
|
+
out["format"] = fmt
|
|
602
|
+
|
|
603
|
+
enum_values = working.get("enum")
|
|
604
|
+
if isinstance(enum_values, list) and enum_values:
|
|
605
|
+
if resolved_type in {None, "string"}:
|
|
606
|
+
out["enum"] = [str(value) for value in enum_values]
|
|
607
|
+
out["type"] = "string"
|
|
608
|
+
else:
|
|
609
|
+
# Gemini only validates enums on strings; keep the value list
|
|
610
|
+
# visible to the model through the description instead.
|
|
611
|
+
rendered = ", ".join(str(value) for value in enum_values)
|
|
612
|
+
hint = f"Allowed values: {rendered}"
|
|
613
|
+
out["description"] = (
|
|
614
|
+
f"{out['description']} ({hint})" if out.get("description") else hint
|
|
615
|
+
)
|
|
616
|
+
|
|
617
|
+
properties = working.get("properties")
|
|
618
|
+
if isinstance(properties, dict):
|
|
619
|
+
clean_properties: dict[str, Any] = {}
|
|
620
|
+
for prop_name, prop_schema in properties.items():
|
|
621
|
+
if not isinstance(prop_name, str) or not prop_name:
|
|
622
|
+
continue
|
|
623
|
+
clean_properties[prop_name] = _gemini_schema(
|
|
624
|
+
prop_schema if isinstance(prop_schema, dict) else {},
|
|
625
|
+
root=root_schema,
|
|
626
|
+
depth=depth + 1,
|
|
627
|
+
)
|
|
628
|
+
if clean_properties:
|
|
629
|
+
out["properties"] = clean_properties
|
|
630
|
+
required = working.get("required")
|
|
631
|
+
if isinstance(required, list):
|
|
632
|
+
kept = [
|
|
633
|
+
name for name in required if isinstance(name, str) and name in clean_properties
|
|
634
|
+
]
|
|
635
|
+
if kept:
|
|
636
|
+
out["required"] = kept
|
|
637
|
+
ordering = working.get("propertyOrdering")
|
|
638
|
+
if isinstance(ordering, list):
|
|
639
|
+
kept_order = [
|
|
640
|
+
name for name in ordering if isinstance(name, str) and name in clean_properties
|
|
641
|
+
]
|
|
642
|
+
if kept_order:
|
|
643
|
+
out["propertyOrdering"] = kept_order
|
|
644
|
+
|
|
645
|
+
items = working.get("items")
|
|
646
|
+
if isinstance(items, list):
|
|
647
|
+
items = items[0] if items and isinstance(items[0], dict) else None
|
|
648
|
+
if isinstance(items, dict):
|
|
649
|
+
out["items"] = _gemini_schema(items, root=root_schema, depth=depth + 1)
|
|
650
|
+
elif out.get("type") == "array":
|
|
651
|
+
# Gemini requires ``items`` on arrays; an untyped item schema is the
|
|
652
|
+
# closest expression of JSON Schema's "anything".
|
|
653
|
+
out["items"] = {}
|
|
654
|
+
|
|
655
|
+
any_of = working.get("anyOf")
|
|
656
|
+
if isinstance(any_of, list):
|
|
657
|
+
branches = [
|
|
658
|
+
_gemini_schema(branch, root=root_schema, depth=depth + 1)
|
|
659
|
+
for branch in any_of
|
|
660
|
+
if isinstance(branch, dict)
|
|
661
|
+
]
|
|
662
|
+
# A ``{"type": "null"}`` branch is Gemini's ``nullable`` flag.
|
|
663
|
+
if any(branch == {"nullable": True} for branch in branches):
|
|
664
|
+
out["nullable"] = True
|
|
665
|
+
branches = [branch for branch in branches if branch != {"nullable": True}]
|
|
666
|
+
if len(branches) == 1:
|
|
667
|
+
single = branches[0]
|
|
668
|
+
for key, value in single.items():
|
|
669
|
+
out.setdefault(key, value)
|
|
670
|
+
elif branches:
|
|
671
|
+
out["anyOf"] = branches
|
|
672
|
+
|
|
673
|
+
return {key: value for key, value in out.items() if key in _GEMINI_SCHEMA_FIELDS}
|
|
674
|
+
|
|
675
|
+
|
|
450
676
|
def _gemini_function_declaration_from_chat_tool(tool: dict[str, Any]) -> dict[str, Any] | None:
|
|
451
677
|
if not isinstance(tool, dict):
|
|
452
678
|
return None
|
|
@@ -460,9 +686,13 @@ def _gemini_function_declaration_from_chat_tool(tool: dict[str, Any]) -> dict[st
|
|
|
460
686
|
name = str(source.get("name") or "").strip()
|
|
461
687
|
if not name:
|
|
462
688
|
return None
|
|
689
|
+
raw_parameters = source.get("parameters")
|
|
690
|
+
parameters = _gemini_schema(raw_parameters) if isinstance(raw_parameters, dict) else {}
|
|
691
|
+
if not parameters.get("type"):
|
|
692
|
+
parameters["type"] = "object"
|
|
463
693
|
declaration: dict[str, Any] = {
|
|
464
694
|
"name": name,
|
|
465
|
-
"parameters":
|
|
695
|
+
"parameters": parameters,
|
|
466
696
|
}
|
|
467
697
|
description = str(source.get("description") or "").strip()
|
|
468
698
|
if description:
|
|
@@ -2574,7 +2804,9 @@ def _gemini_response_format(response_format: dict[str, Any] | None) -> dict[str,
|
|
|
2574
2804
|
)
|
|
2575
2805
|
return {
|
|
2576
2806
|
"responseMimeType": "application/json",
|
|
2577
|
-
|
|
2807
|
+
# responseSchema is the same OpenAPI-subset ``Schema`` message as
|
|
2808
|
+
# function parameters, so it needs the same projection.
|
|
2809
|
+
"responseSchema": _gemini_schema(schema),
|
|
2578
2810
|
}
|
|
2579
2811
|
if response_type == "text":
|
|
2580
2812
|
return {}
|
|
@@ -421,6 +421,24 @@ def _is_moonshot_provider(provider_key: str | None) -> bool:
|
|
|
421
421
|
return _normalize_provider_key(provider_key) in {_MOONSHOT_PROVIDER_KEY, "kimi_code"}
|
|
422
422
|
|
|
423
423
|
|
|
424
|
+
# Routes whose Chat Completions surface wants ``max_completion_tokens``.
|
|
425
|
+
# OpenAI's gpt-5 / o-series reject the legacy ``max_tokens`` outright
|
|
426
|
+
# ("Unsupported parameter: 'max_tokens' is not supported with this model"),
|
|
427
|
+
# and OpenAI accepts ``max_completion_tokens`` on every chat model, so the
|
|
428
|
+
# first-party host (and Azure, which mirrors it) always uses the new field.
|
|
429
|
+
# The decision is keyed on the endpoint host, not on a provider inferred from
|
|
430
|
+
# a ``gpt-*`` model name: an unknown OpenAI-compatible gateway serving such a
|
|
431
|
+
# model may only implement ``max_tokens``.
|
|
432
|
+
_MAX_COMPLETION_TOKENS_HOST_PROVIDERS = frozenset({"openai", "azure"})
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
def _uses_max_completion_tokens(provider_key: str | None, *, base_url: str | None) -> bool:
|
|
436
|
+
if _is_moonshot_provider(provider_key):
|
|
437
|
+
return True
|
|
438
|
+
host_provider = _normalize_provider_key(_provider_key_from_base_url(base_url))
|
|
439
|
+
return host_provider in _MAX_COMPLETION_TOKENS_HOST_PROVIDERS
|
|
440
|
+
|
|
441
|
+
|
|
424
442
|
def _is_nvidia_provider(provider_key: str | None) -> bool:
|
|
425
443
|
return _normalize_provider_key(provider_key) == _NVIDIA_PROVIDER_KEY
|
|
426
444
|
|
|
@@ -2130,7 +2148,7 @@ class OpenAICompatClient:
|
|
|
2130
2148
|
if max_tokens is not None:
|
|
2131
2149
|
output_limit_field = (
|
|
2132
2150
|
"max_completion_tokens"
|
|
2133
|
-
if
|
|
2151
|
+
if _uses_max_completion_tokens(transport_provider_key, base_url=self.base_url)
|
|
2134
2152
|
else "max_tokens"
|
|
2135
2153
|
)
|
|
2136
2154
|
payload[output_limit_field] = int(max_tokens)
|