kon-coding-agent 0.3.10__tar.gz → 0.3.11__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.
- {kon_coding_agent-0.3.10/.kon → kon_coding_agent-0.3.11/.agents}/skills/kon-tmux-test/SKILL.md +1 -1
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/CHANGELOG.md +32 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/PKG-INFO +1 -1
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/pyproject.toml +1 -1
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/scripts/show_themes.py +1 -1
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/__init__.py +8 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/builtin_skills/init/SKILL.md +1 -1
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/config.py +66 -3
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/context/agent_mds.py +15 -13
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/context/skills.py +42 -12
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/defaults/config.toml +12 -4
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/__init__.py +2 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/base.py +20 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/models.py +10 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/oauth/__init__.py +2 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/oauth/copilot.py +3 -1
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/oauth/openai.py +10 -5
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/anthropic.py +65 -37
- kon_coding_agent-0.3.11/src/kon/llm/providers/anthropic_capabilities.py +121 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/azure_ai_foundry.py +4 -2
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/copilot_anthropic.py +24 -20
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/openai_codex_responses.py +366 -32
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/openai_completions.py +9 -1
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/openai_responses.py +2 -1
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/runtime.py +20 -18
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/session.py +2 -3
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/themes.py +240 -6
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools_manager.py +5 -9
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/turn.py +21 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/app.py +80 -33
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/blocks.py +4 -1
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/chat.py +41 -37
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/commands.py +112 -59
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/export.py +2 -2
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/floating_list.py +21 -27
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/formatting.py +82 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/prompt_history.py +2 -2
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/styles.py +5 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/conftest.py +7 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/context/test_skills.py +10 -9
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/llm/test_anthropic_provider.py +75 -2
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/llm/test_openai_codex_provider_errors.py +334 -3
- kon_coding_agent-0.3.11/tests/llm/test_openai_oauth.py +86 -0
- kon_coding_agent-0.3.11/tests/llm/test_tls_verify.py +44 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_cli_auth_flags.py +9 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_cli_provider_resolution.py +1 -8
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_compaction.py +10 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_config_error_fallback.py +6 -5
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_config_migration.py +7 -9
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_local_auth_config.py +1 -1
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_notifications_config.py +1 -1
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_openai_compat.py +1 -1
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_runtime_switch_model.py +44 -1
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_system_prompt.py +1 -1
- kon_coding_agent-0.3.11/tests/test_tools_manager.py +42 -0
- kon_coding_agent-0.3.11/tests/ui/test_completion_chrome.py +486 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_floating_list.py +17 -0
- kon_coding_agent-0.3.11/tests/ui/test_login_command.py +189 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_permission_selection_status.py +3 -2
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_permissions_command.py +18 -1
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_styles.py +9 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_thinking_notifications_commands.py +18 -1
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/uv.lock +1 -1
- kon_coding_agent-0.3.10/tests/llm/test_openai_oauth.py +0 -14
- kon_coding_agent-0.3.10/tests/test_tools_manager.py +0 -18
- {kon_coding_agent-0.3.10/.kon → kon_coding_agent-0.3.11/.agents}/skills/kon-release-publish/SKILL.md +0 -0
- {kon_coding_agent-0.3.10/.kon → kon_coding_agent-0.3.11/.agents}/skills/kon-tmux-test/run-e2e-tests.sh +0 -0
- {kon_coding_agent-0.3.10/.kon → kon_coding_agent-0.3.11/.agents}/skills/kon-tmux-test/setup-test-project.sh +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/.github/workflows/test.yml +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/.gitignore +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/.python-version +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/AGENTS.md +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/LICENSE +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/README.md +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/docs/e2e-test-coverage-review.md +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/docs/images/kon-screenshot.png +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/docs/local-models.md +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/async_utils.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/context/__init__.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/context/_xml.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/context/git.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/context/loader.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/core/__init__.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/core/compaction.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/core/handoff.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/core/types.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/defaults/__init__.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/events.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/git_branch.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/__init__.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/copilot.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/github_copilot_headers.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/mock.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/openai_compat.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/llm/providers/sanitize.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/loop.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/notify.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/permissions.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/py.typed +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/sounds/completion.wav +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/sounds/error.wav +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/sounds/permission.wav +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/__init__.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/_read_image.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/_tool_utils.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/base.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/bash.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/edit.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/find.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/grep.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/read.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/web_fetch.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/web_search.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/tools/write.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/__init__.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/app_protocol.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/autocomplete.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/clipboard.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/input.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/latex.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/path_complete.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/selection_mode.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/session_ui.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/tool_output.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/tree.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/welcome.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/ui/widgets.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/src/kon/update_check.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/context/test_agents.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/llm/__init__.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/llm/test_azure_ai_foundry_provider.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/llm/test_mock_provider.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_agentic_loop.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_config_binaries.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_config_injection.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_git_branch.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_handoff.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_handoff_link_interrupt.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_launch_warnings.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_llm_lazy_imports.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_model_provider_resolution.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_notify.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_permissions.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_session_persistence.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_session_queries.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_session_resume.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_session_tree.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_system_prompt_git_context.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_themes.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_ui_notifications.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_update_check.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/test_update_notice_behavior.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_bash_truncation.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_diff.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_edit.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_edit_display.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_read.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_read_image.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_read_image_integration.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_read_image_resize.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_subprocess_cancellation.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_web_fetch.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/tools/test_write.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_app_approval_keys.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_autocomplete.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_info_bar_clicks.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_info_bar_permissions.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_input_approval_submit.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_input_cursor_theme.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_input_handoff.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_input_paste.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_input_shell_style.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_keybindings.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_latex.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_prompt_history.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_queue_editing.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_shell_command_detection.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_status_line.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_streaming_blocks.py +0 -0
- {kon_coding_agent-0.3.10 → kon_coding_agent-0.3.11}/tests/ui/test_tool_output_expansion.py +0 -0
{kon_coding_agent-0.3.10/.kon → kon_coding_agent-0.3.11/.agents}/skills/kon-tmux-test/SKILL.md
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: kon-tmux-test
|
|
3
|
-
description: E2E testing of kon using tmux sessions; IMPORTANT: only trigger this skill when user asks for e2e testing of kon
|
|
3
|
+
description: "E2E testing of kon using tmux sessions; IMPORTANT: only trigger this skill when user asks for e2e testing of kon"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Kon Tmux E2E Testing
|
|
@@ -6,6 +6,38 @@ All notable changes to this project will be documented in this file.
|
|
|
6
6
|
|
|
7
7
|
- No changes yet.
|
|
8
8
|
|
|
9
|
+
## 0.3.11 - 2026-05-29
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Added `insecure_skip_verify` for local providers using self-signed certificates - @s3rj1k.
|
|
14
|
+
- Added per-model Anthropic capability registry and thinking config improvements.
|
|
15
|
+
- Added Claude Opus 4.7 Azure model entry.
|
|
16
|
+
- Added migration of user data from `~/.kon` to `~/.config/kon` and `~/.agents`.
|
|
17
|
+
- Added bash command header highlighting.
|
|
18
|
+
- Added persisted UI settings toggles.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Migrated context system paths for skills and `AGENTS.md` to `.agents`.
|
|
23
|
+
- Centralized internal path handling and removed legacy Kon path migration.
|
|
24
|
+
- Updated default Codex model and authentication guidance.
|
|
25
|
+
- Refined `/init`, `/resume`, thinking UI, and theme styling.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- Honored `request_timeout_seconds` in insecure-skip-verify HTTP clients - @s3rj1k.
|
|
30
|
+
- Fixed loaded resource display before agent initialization.
|
|
31
|
+
- Fixed OpenAI Codex transport, websocket interrupt handling, and SSE fallback behavior.
|
|
32
|
+
- Fixed UI completion path handling.
|
|
33
|
+
- Fixed empty thinking block handling and empty-compaction error display.
|
|
34
|
+
- Fixed duplicate home skill loading and skill frontmatter parsing.
|
|
35
|
+
- Fixed stale OAuth login state and completion popup info bar behavior - @Meltedd.
|
|
36
|
+
|
|
37
|
+
### Tests
|
|
38
|
+
|
|
39
|
+
- Updated config, login, migration, and compaction test coverage.
|
|
40
|
+
|
|
9
41
|
## 0.3.10 - 2026-05-21
|
|
10
42
|
|
|
11
43
|
### Added
|
|
@@ -51,7 +51,7 @@ def parse_args() -> argparse.Namespace:
|
|
|
51
51
|
parser.add_argument(
|
|
52
52
|
"--kon-config",
|
|
53
53
|
type=Path,
|
|
54
|
-
default=Path.home() / ".kon/config.toml",
|
|
54
|
+
default=Path.home() / ".config" / "kon" / "config.toml",
|
|
55
55
|
help="Kon config file to rewrite during previews.",
|
|
56
56
|
)
|
|
57
57
|
parser.add_argument(
|
|
@@ -3,11 +3,15 @@ from kon.config import (
|
|
|
3
3
|
CONFIG_DIR_NAME,
|
|
4
4
|
Config,
|
|
5
5
|
consume_config_warnings,
|
|
6
|
+
get_agents_dir,
|
|
6
7
|
get_config,
|
|
7
8
|
get_config_dir,
|
|
8
9
|
reload_config,
|
|
9
10
|
reset_config,
|
|
10
11
|
set_config,
|
|
12
|
+
set_notifications_enabled,
|
|
13
|
+
set_permissions_mode,
|
|
14
|
+
set_show_welcome_shortcuts,
|
|
11
15
|
set_theme,
|
|
12
16
|
update_available_binaries,
|
|
13
17
|
)
|
|
@@ -30,11 +34,15 @@ __all__ = [
|
|
|
30
34
|
"config",
|
|
31
35
|
"consume_config_warnings",
|
|
32
36
|
"escape_xml",
|
|
37
|
+
"get_agents_dir",
|
|
33
38
|
"get_config",
|
|
34
39
|
"get_config_dir",
|
|
35
40
|
"reload_config",
|
|
36
41
|
"reset_config",
|
|
37
42
|
"set_config",
|
|
43
|
+
"set_notifications_enabled",
|
|
44
|
+
"set_permissions_mode",
|
|
45
|
+
"set_show_welcome_shortcuts",
|
|
38
46
|
"set_theme",
|
|
39
47
|
"update_available_binaries",
|
|
40
48
|
]
|
|
@@ -15,7 +15,7 @@ from pydantic import BaseModel, Field, ValidationError, field_validator
|
|
|
15
15
|
|
|
16
16
|
from .themes import ColorsConfig, get_theme, get_theme_ids
|
|
17
17
|
|
|
18
|
-
CONFIG_DIR_NAME: str = "
|
|
18
|
+
CONFIG_DIR_NAME: str = "kon"
|
|
19
19
|
|
|
20
20
|
OnOverflowMode = Literal["continue", "pause"]
|
|
21
21
|
AuthMode = Literal["auto", "required", "none"]
|
|
@@ -50,6 +50,9 @@ class UIConfig(BaseModel):
|
|
|
50
50
|
# When true, finalized thinking blocks are collapsed to a single line summary.
|
|
51
51
|
# Set to false to always show the full thinking content.
|
|
52
52
|
collapse_thinking: bool = True
|
|
53
|
+
# Show the list of keyboard shortcuts in the welcome section on launch.
|
|
54
|
+
# Set to false to hide the shortcuts panel.
|
|
55
|
+
show_welcome_shortcuts: bool = True
|
|
53
56
|
|
|
54
57
|
@field_validator("theme")
|
|
55
58
|
@classmethod
|
|
@@ -73,6 +76,10 @@ class AuthConfig(BaseModel):
|
|
|
73
76
|
anthropic_compat: AuthMode = "auto"
|
|
74
77
|
|
|
75
78
|
|
|
79
|
+
class TLSConfig(BaseModel):
|
|
80
|
+
insecure_skip_verify: bool = False
|
|
81
|
+
|
|
82
|
+
|
|
76
83
|
class LLMConfig(BaseModel):
|
|
77
84
|
default_provider: str
|
|
78
85
|
default_model: str
|
|
@@ -82,6 +89,7 @@ class LLMConfig(BaseModel):
|
|
|
82
89
|
tool_call_idle_timeout_seconds: float = 180
|
|
83
90
|
request_timeout_seconds: float = 600
|
|
84
91
|
auth: AuthConfig = AuthConfig()
|
|
92
|
+
tls: TLSConfig = TLSConfig()
|
|
85
93
|
|
|
86
94
|
|
|
87
95
|
class CompactionConfig(BaseModel):
|
|
@@ -219,7 +227,14 @@ class Config:
|
|
|
219
227
|
|
|
220
228
|
|
|
221
229
|
def get_config_dir() -> Path:
|
|
222
|
-
|
|
230
|
+
base = os.environ.get("XDG_CONFIG_HOME")
|
|
231
|
+
if base:
|
|
232
|
+
return Path(base) / CONFIG_DIR_NAME
|
|
233
|
+
return Path.home() / ".config" / CONFIG_DIR_NAME
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def get_agents_dir() -> Path:
|
|
237
|
+
return Path.home() / ".agents"
|
|
223
238
|
|
|
224
239
|
|
|
225
240
|
def _ensure_config_file() -> Path:
|
|
@@ -247,7 +262,7 @@ def consume_config_warnings() -> list[str]:
|
|
|
247
262
|
def _detect_available_binaries() -> set[str]:
|
|
248
263
|
binaries = {"rg", "fd"}
|
|
249
264
|
available = set()
|
|
250
|
-
bin_dir =
|
|
265
|
+
bin_dir = get_config_dir() / "bin"
|
|
251
266
|
|
|
252
267
|
for binary in binaries:
|
|
253
268
|
if shutil.which(binary) or (bin_dir / binary).exists():
|
|
@@ -584,6 +599,54 @@ def set_theme(theme: str) -> Config:
|
|
|
584
599
|
return reload_config()
|
|
585
600
|
|
|
586
601
|
|
|
602
|
+
def set_show_welcome_shortcuts(enabled: bool) -> Config:
|
|
603
|
+
config_file = _ensure_config_file()
|
|
604
|
+
data = _read_config_data(config_file)
|
|
605
|
+
|
|
606
|
+
ui = data.get("ui")
|
|
607
|
+
if not isinstance(ui, dict):
|
|
608
|
+
ui = {}
|
|
609
|
+
data["ui"] = ui
|
|
610
|
+
|
|
611
|
+
ui["show_welcome_shortcuts"] = enabled
|
|
612
|
+
_set_config_version(data)
|
|
613
|
+
|
|
614
|
+
_atomic_write_text(config_file, _serialize_config_toml(data))
|
|
615
|
+
return reload_config()
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
def set_permissions_mode(mode: PermissionMode) -> Config:
|
|
619
|
+
config_file = _ensure_config_file()
|
|
620
|
+
data = _read_config_data(config_file)
|
|
621
|
+
|
|
622
|
+
perms = data.get("permissions")
|
|
623
|
+
if not isinstance(perms, dict):
|
|
624
|
+
perms = {}
|
|
625
|
+
data["permissions"] = perms
|
|
626
|
+
|
|
627
|
+
perms["mode"] = mode
|
|
628
|
+
_set_config_version(data)
|
|
629
|
+
|
|
630
|
+
_atomic_write_text(config_file, _serialize_config_toml(data))
|
|
631
|
+
return reload_config()
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
def set_notifications_enabled(enabled: bool) -> Config:
|
|
635
|
+
config_file = _ensure_config_file()
|
|
636
|
+
data = _read_config_data(config_file)
|
|
637
|
+
|
|
638
|
+
notifications = data.get("notifications")
|
|
639
|
+
if not isinstance(notifications, dict):
|
|
640
|
+
notifications = {}
|
|
641
|
+
data["notifications"] = notifications
|
|
642
|
+
|
|
643
|
+
notifications["enabled"] = enabled
|
|
644
|
+
_set_config_version(data)
|
|
645
|
+
|
|
646
|
+
_atomic_write_text(config_file, _serialize_config_toml(data))
|
|
647
|
+
return reload_config()
|
|
648
|
+
|
|
649
|
+
|
|
587
650
|
def reset_config() -> None:
|
|
588
651
|
"""Reset config to uninitialized state (next get_config() will reload from file)."""
|
|
589
652
|
_config_var.set(None)
|
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
AGENTS.md discovery and loading.
|
|
3
3
|
|
|
4
4
|
Discovers AGENTS.md (or CLAUDE.md) files from:
|
|
5
|
-
1. Global
|
|
6
|
-
2. Ancestor directories from cwd up to git root or home directory (closest last)
|
|
5
|
+
1. Global agents dir (~/.agents/)
|
|
6
|
+
2. Ancestor .agents directories from cwd up to git root or home directory (closest last)
|
|
7
|
+
3. Root-level AGENTS.md/CLAUDE.md files for compatibility
|
|
7
8
|
"""
|
|
8
9
|
|
|
9
10
|
from dataclasses import dataclass
|
|
10
11
|
from pathlib import Path
|
|
11
12
|
|
|
12
|
-
from .. import get_config_dir
|
|
13
|
+
from .. import get_agents_dir as get_config_dir
|
|
13
14
|
from ._xml import escape_xml
|
|
14
15
|
|
|
15
16
|
CONTEXT_FILE_CANDIDATES = ["AGENTS.md", "CLAUDE.md"]
|
|
@@ -62,8 +63,8 @@ def load_agent_mds(cwd: str | None = None) -> list[ContextFile]:
|
|
|
62
63
|
Load all AGENTS.md files from config dir and ancestor directories.
|
|
63
64
|
|
|
64
65
|
Discovery order:
|
|
65
|
-
1. Global
|
|
66
|
-
2. Ancestor directories from stop dir down to cwd - closest to cwd loaded last
|
|
66
|
+
1. Global agents dir (~/.agents/) - loaded first
|
|
67
|
+
2. Ancestor .agents/root directories from stop dir down to cwd - closest to cwd loaded last
|
|
67
68
|
|
|
68
69
|
Stop directory is determined by:
|
|
69
70
|
- Git root (if cwd is inside a git repository)
|
|
@@ -77,10 +78,10 @@ def load_agent_mds(cwd: str | None = None) -> list[ContextFile]:
|
|
|
77
78
|
context_files: list[ContextFile] = []
|
|
78
79
|
seen_paths: set[str] = set()
|
|
79
80
|
|
|
80
|
-
# 1. Load from global
|
|
81
|
-
|
|
82
|
-
if
|
|
83
|
-
global_context = _load_context_from_dir(
|
|
81
|
+
# 1. Load from global agents dir
|
|
82
|
+
agents_dir = get_config_dir()
|
|
83
|
+
if agents_dir.exists():
|
|
84
|
+
global_context = _load_context_from_dir(agents_dir)
|
|
84
85
|
if global_context:
|
|
85
86
|
context_files.append(global_context)
|
|
86
87
|
seen_paths.add(global_context.path)
|
|
@@ -93,10 +94,11 @@ def load_agent_mds(cwd: str | None = None) -> list[ContextFile]:
|
|
|
93
94
|
current = resolved_cwd
|
|
94
95
|
|
|
95
96
|
while True:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
for candidate_dir in (current / ".agents", current):
|
|
98
|
+
context_file = _load_context_from_dir(candidate_dir)
|
|
99
|
+
if context_file and context_file.path not in seen_paths:
|
|
100
|
+
ancestor_files.insert(0, context_file)
|
|
101
|
+
seen_paths.add(context_file.path)
|
|
100
102
|
if current == stop_dir:
|
|
101
103
|
break
|
|
102
104
|
current = current.parent
|
|
@@ -5,8 +5,8 @@ Skills are directories containing a SKILL.md file with frontmatter.
|
|
|
5
5
|
They provide specialized instructions that the model can read on-demand.
|
|
6
6
|
|
|
7
7
|
Discovery locations:
|
|
8
|
-
1.
|
|
9
|
-
2. Project: <cwd>/.
|
|
8
|
+
1. User: ~/.agents/skills/
|
|
9
|
+
2. Project: <cwd-or-ancestor>/.agents/skills/
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
import os
|
|
@@ -16,7 +16,7 @@ from importlib import resources
|
|
|
16
16
|
from pathlib import Path
|
|
17
17
|
from typing import Any
|
|
18
18
|
|
|
19
|
-
from .. import
|
|
19
|
+
from .. import get_agents_dir as get_config_dir
|
|
20
20
|
from ._xml import escape_xml
|
|
21
21
|
|
|
22
22
|
MAX_NAME_LENGTH = 64
|
|
@@ -165,13 +165,18 @@ def _load_skill_from_dir(skill_dir: Path) -> tuple[Skill | None, list[SkillWarni
|
|
|
165
165
|
return None, [SkillWarning(file_path, str(e))]
|
|
166
166
|
|
|
167
167
|
|
|
168
|
-
def _load_skills_from_dir(
|
|
168
|
+
def _load_skills_from_dir(
|
|
169
|
+
directory: Path, *, legacy_warning: str | None = None
|
|
170
|
+
) -> LoadSkillsResult:
|
|
169
171
|
skills: list[Skill] = []
|
|
170
172
|
warnings: list[SkillWarning] = []
|
|
171
173
|
|
|
172
174
|
if not directory.exists():
|
|
173
175
|
return LoadSkillsResult(skills=skills, warnings=warnings)
|
|
174
176
|
|
|
177
|
+
if legacy_warning:
|
|
178
|
+
warnings.append(SkillWarning(str(directory), legacy_warning))
|
|
179
|
+
|
|
175
180
|
try:
|
|
176
181
|
for entry in directory.iterdir():
|
|
177
182
|
if entry.name.startswith("."):
|
|
@@ -190,13 +195,37 @@ def _load_skills_from_dir(directory: Path) -> LoadSkillsResult:
|
|
|
190
195
|
return LoadSkillsResult(skills=skills, warnings=warnings)
|
|
191
196
|
|
|
192
197
|
|
|
198
|
+
def _find_git_root(start: Path) -> Path | None:
|
|
199
|
+
current = start
|
|
200
|
+
while True:
|
|
201
|
+
if (current / ".git").is_dir():
|
|
202
|
+
return current
|
|
203
|
+
parent = current.parent
|
|
204
|
+
if parent == current:
|
|
205
|
+
return None
|
|
206
|
+
current = parent
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _project_skill_dirs(cwd: Path) -> list[Path]:
|
|
210
|
+
git_root = _find_git_root(cwd)
|
|
211
|
+
stop_dir = git_root or cwd
|
|
212
|
+
dirs: list[Path] = []
|
|
213
|
+
current = cwd
|
|
214
|
+
while True:
|
|
215
|
+
dirs.append((current / ".agents" / "skills").resolve(strict=False))
|
|
216
|
+
if current == stop_dir:
|
|
217
|
+
break
|
|
218
|
+
current = current.parent
|
|
219
|
+
return dirs
|
|
220
|
+
|
|
221
|
+
|
|
193
222
|
def load_skills(cwd: str | None = None) -> LoadSkillsResult:
|
|
194
223
|
"""
|
|
195
|
-
Load skills from
|
|
224
|
+
Load skills from ~/.agents and project .agents locations.
|
|
196
225
|
|
|
197
226
|
Discovery:
|
|
198
|
-
1. <cwd>/.
|
|
199
|
-
2. ~/.
|
|
227
|
+
1. <cwd-or-ancestor>/.agents/skills/ - each subdirectory with SKILL.md is a skill
|
|
228
|
+
2. ~/.agents/skills/ - each subdirectory with SKILL.md is a skill
|
|
200
229
|
|
|
201
230
|
Local skills take precedence over global skills with the same name.
|
|
202
231
|
"""
|
|
@@ -220,12 +249,13 @@ def load_skills(cwd: str | None = None) -> LoadSkillsResult:
|
|
|
220
249
|
else:
|
|
221
250
|
skill_map[skill.name] = skill
|
|
222
251
|
|
|
223
|
-
|
|
224
|
-
|
|
252
|
+
project_skills_dirs = _project_skill_dirs(resolved_cwd)
|
|
253
|
+
for skills_dir in project_skills_dirs:
|
|
254
|
+
add_skills(_load_skills_from_dir(skills_dir))
|
|
225
255
|
|
|
226
|
-
|
|
227
|
-
if
|
|
228
|
-
add_skills(_load_skills_from_dir(
|
|
256
|
+
user_skills_dir = (get_config_dir() / "skills").resolve(strict=False)
|
|
257
|
+
if user_skills_dir not in project_skills_dirs:
|
|
258
|
+
add_skills(_load_skills_from_dir(user_skills_dir))
|
|
229
259
|
|
|
230
260
|
return LoadSkillsResult(skills=list(skill_map.values()), warnings=all_warnings)
|
|
231
261
|
|
|
@@ -3,11 +3,11 @@ config_version = 6
|
|
|
3
3
|
|
|
4
4
|
[llm]
|
|
5
5
|
default_provider = "openai-codex" # "zhipu", "github-copilot", "openai-codex"
|
|
6
|
-
default_model = "gpt-5.
|
|
6
|
+
default_model = "gpt-5.5"
|
|
7
7
|
# Optional API base URL override for the selected provider or local/self-hosted endpoint.
|
|
8
8
|
# Leave empty to use the provider's default URL.
|
|
9
9
|
default_base_url = ""
|
|
10
|
-
default_thinking_level = "
|
|
10
|
+
default_thinking_level = "low"
|
|
11
11
|
# Abort a tool call if it stays idle for this long during a turn.
|
|
12
12
|
# Helps prevent stalled tool executions from hanging the agent loop.
|
|
13
13
|
tool_call_idle_timeout_seconds = 180
|
|
@@ -23,6 +23,11 @@ request_timeout_seconds = 600
|
|
|
23
23
|
openai_compat = "auto" # "auto", "required", or "none"
|
|
24
24
|
anthropic_compat = "auto" # "auto", "required", or "none"
|
|
25
25
|
|
|
26
|
+
[llm.tls]
|
|
27
|
+
# Skip TLS verification for LLM HTTP requests. Enables self-signed certs
|
|
28
|
+
# on local providers.
|
|
29
|
+
insecure_skip_verify = false
|
|
30
|
+
|
|
26
31
|
[llm.system_prompt]
|
|
27
32
|
git_context = true
|
|
28
33
|
content = """You are an expert coding assistant called Kon. You help users by reading, searching, executing commands, editing code, and writing new files.
|
|
@@ -32,8 +37,8 @@ content = """You are an expert coding assistant called Kon. You help users by re
|
|
|
32
37
|
- Be concise in your responses
|
|
33
38
|
- Show file paths clearly when working with files
|
|
34
39
|
- When summarizing your actions, output plain text directly DO NOT use cat or bash to display
|
|
35
|
-
- Kon session logs are JSONL files in ~/.kon/sessions; If the user references recent sessions or a particular session, look there
|
|
36
|
-
- If the user mentions adding a new skill
|
|
40
|
+
- Kon session logs are JSONL files in ~/.config/kon/sessions; If the user references recent sessions or a particular session, look there
|
|
41
|
+
- If the user mentions adding a new skill, use ~/.agents/skills for user skills and .agents/skills for project skills"""
|
|
37
42
|
|
|
38
43
|
[compaction]
|
|
39
44
|
# What kon should do after compacting history on context overflow.
|
|
@@ -58,6 +63,9 @@ theme = "gruvbox-dark"
|
|
|
58
63
|
# When true, finalized thinking blocks are collapsed to a single line summary.
|
|
59
64
|
# Set to false to always show the full thinking content.
|
|
60
65
|
collapse_thinking = true
|
|
66
|
+
# Show the list of keyboard shortcuts in the welcome section on launch.
|
|
67
|
+
# Set to false to hide the shortcuts panel.
|
|
68
|
+
show_welcome_shortcuts = true
|
|
61
69
|
|
|
62
70
|
[permissions]
|
|
63
71
|
# Approval behavior for mutating tools.
|
|
@@ -10,6 +10,7 @@ from .models import (
|
|
|
10
10
|
from .oauth import clear_credentials as clear_copilot_credentials
|
|
11
11
|
from .oauth import (
|
|
12
12
|
clear_openai_credentials,
|
|
13
|
+
get_valid_openai_credentials,
|
|
13
14
|
is_copilot_logged_in,
|
|
14
15
|
is_openai_logged_in,
|
|
15
16
|
load_openai_credentials,
|
|
@@ -39,6 +40,7 @@ __all__ = [
|
|
|
39
40
|
"get_models_by_provider",
|
|
40
41
|
"get_openai_token",
|
|
41
42
|
"get_provider_class",
|
|
43
|
+
"get_valid_openai_credentials",
|
|
42
44
|
"is_copilot_logged_in",
|
|
43
45
|
"is_openai_logged_in",
|
|
44
46
|
"load_copilot_credentials",
|
|
@@ -6,6 +6,10 @@ from ipaddress import ip_address
|
|
|
6
6
|
from typing import Literal
|
|
7
7
|
from urllib.parse import urlparse
|
|
8
8
|
|
|
9
|
+
import httpx
|
|
10
|
+
|
|
11
|
+
from kon import config as kon_config
|
|
12
|
+
|
|
9
13
|
from ..core.types import Message, StreamPart, ToolDefinition, Usage
|
|
10
14
|
|
|
11
15
|
DEFAULT_THINKING_LEVELS: list[str] = ["none", "minimal", "low", "medium", "high", "xhigh"]
|
|
@@ -48,6 +52,15 @@ def is_local_base_url(base_url: str | None) -> bool:
|
|
|
48
52
|
return addr.is_loopback or addr.is_private or addr.is_link_local
|
|
49
53
|
|
|
50
54
|
|
|
55
|
+
def make_http_client() -> httpx.AsyncClient | None:
|
|
56
|
+
# Returns None when verify is required so the SDK uses its own default client.
|
|
57
|
+
if not kon_config.llm.tls.insecure_skip_verify:
|
|
58
|
+
return None
|
|
59
|
+
return httpx.AsyncClient(
|
|
60
|
+
verify=False, timeout=httpx.Timeout(kon_config.llm.request_timeout_seconds)
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
51
64
|
def resolve_api_key(
|
|
52
65
|
explicit_api_key: str | None,
|
|
53
66
|
*,
|
|
@@ -121,6 +134,13 @@ class LLMStream(AsyncIterator["StreamPart"]):
|
|
|
121
134
|
raise StopAsyncIteration
|
|
122
135
|
return await self._iterator.__anext__()
|
|
123
136
|
|
|
137
|
+
async def aclose(self) -> None:
|
|
138
|
+
if self._iterator is None:
|
|
139
|
+
return
|
|
140
|
+
close = getattr(self._iterator, "aclose", None)
|
|
141
|
+
if close is not None:
|
|
142
|
+
await close()
|
|
143
|
+
|
|
124
144
|
@property
|
|
125
145
|
def usage(self) -> Usage | None:
|
|
126
146
|
return self._usage
|
|
@@ -169,6 +169,16 @@ MODELS: dict[str, Model] = {
|
|
|
169
169
|
supports_images=True,
|
|
170
170
|
supports_thinking=True,
|
|
171
171
|
),
|
|
172
|
+
# Azure AI Foundry - Opus 4.7
|
|
173
|
+
"claude-opus-4.7-azure": Model(
|
|
174
|
+
id="claude-opus-4.7",
|
|
175
|
+
provider="azure-ai-foundry",
|
|
176
|
+
api=ApiType.AZURE_AI_FOUNDRY,
|
|
177
|
+
base_url="", # resolved from AZURE_AI_FOUNDRY_BASE_URL env var
|
|
178
|
+
max_tokens=8192 * 2,
|
|
179
|
+
supports_images=True,
|
|
180
|
+
supports_thinking=True,
|
|
181
|
+
),
|
|
172
182
|
}
|
|
173
183
|
|
|
174
184
|
|
|
@@ -13,6 +13,7 @@ from .openai import (
|
|
|
13
13
|
OpenAICredentials,
|
|
14
14
|
clear_openai_credentials,
|
|
15
15
|
get_openai_auth_path,
|
|
16
|
+
get_valid_openai_credentials,
|
|
16
17
|
get_valid_openai_token,
|
|
17
18
|
is_openai_logged_in,
|
|
18
19
|
load_openai_credentials,
|
|
@@ -28,6 +29,7 @@ __all__ = [
|
|
|
28
29
|
"get_base_url_from_token",
|
|
29
30
|
"get_copilot_auth_path",
|
|
30
31
|
"get_openai_auth_path",
|
|
32
|
+
"get_valid_openai_credentials",
|
|
31
33
|
"get_valid_openai_token",
|
|
32
34
|
"get_valid_token",
|
|
33
35
|
"is_copilot_logged_in",
|
|
@@ -14,6 +14,8 @@ from typing import Any
|
|
|
14
14
|
|
|
15
15
|
import aiohttp
|
|
16
16
|
|
|
17
|
+
from kon import get_config_dir
|
|
18
|
+
|
|
17
19
|
# GitHub OAuth client ID (same as VS Code Copilot extension)
|
|
18
20
|
_CLIENT_ID = b64decode("SXYxLmI1MDdhMDhjODdlY2ZlOTg=").decode()
|
|
19
21
|
|
|
@@ -44,7 +46,7 @@ class DeviceCodeResponse:
|
|
|
44
46
|
|
|
45
47
|
|
|
46
48
|
def get_copilot_auth_path() -> Path:
|
|
47
|
-
return
|
|
49
|
+
return get_config_dir() / "copilot_auth.json"
|
|
48
50
|
|
|
49
51
|
|
|
50
52
|
def load_credentials() -> CopilotCredentials | None:
|
|
@@ -18,6 +18,8 @@ from urllib.parse import parse_qs, urlencode, urlparse
|
|
|
18
18
|
|
|
19
19
|
import aiohttp
|
|
20
20
|
|
|
21
|
+
from kon import get_config_dir
|
|
22
|
+
|
|
21
23
|
_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann"
|
|
22
24
|
_AUTHORIZE_URL = "https://auth.openai.com/oauth/authorize"
|
|
23
25
|
_TOKEN_URL = "https://auth.openai.com/oauth/token"
|
|
@@ -40,7 +42,7 @@ class OpenAICredentials:
|
|
|
40
42
|
|
|
41
43
|
|
|
42
44
|
def get_openai_auth_path() -> Path:
|
|
43
|
-
return
|
|
45
|
+
return get_config_dir() / "openai_auth.json"
|
|
44
46
|
|
|
45
47
|
|
|
46
48
|
def load_openai_credentials() -> OpenAICredentials | None:
|
|
@@ -379,9 +381,7 @@ async def login(
|
|
|
379
381
|
await server.wait_closed()
|
|
380
382
|
|
|
381
383
|
|
|
382
|
-
async def
|
|
383
|
-
import time
|
|
384
|
-
|
|
384
|
+
async def get_valid_openai_credentials() -> OpenAICredentials | None:
|
|
385
385
|
creds = load_openai_credentials()
|
|
386
386
|
if not creds:
|
|
387
387
|
return None
|
|
@@ -392,4 +392,9 @@ async def get_valid_openai_token() -> str | None:
|
|
|
392
392
|
except Exception:
|
|
393
393
|
return None
|
|
394
394
|
|
|
395
|
-
return creds
|
|
395
|
+
return creds
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
async def get_valid_openai_token() -> str | None:
|
|
399
|
+
creds = await get_valid_openai_credentials()
|
|
400
|
+
return creds.access if creds else None
|