kon-coding-agent 0.3.3__tar.gz → 0.3.5__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.5/.github/workflows/test.yml +33 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/.kon/skills/kon-release-publish/SKILL.md +16 -9
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/AGENTS.md +1 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/CHANGELOG.md +64 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/PKG-INFO +1 -1
- kon_coding_agent-0.3.5/docs/local-models.md +80 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/pyproject.toml +1 -1
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/config.py +1 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/defaults/config.toml +3 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/base.py +1 -1
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/providers/openai_completions.py +31 -10
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/providers/openai_responses.py +3 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/session.py +148 -17
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/tools/edit.py +1 -1
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/app.py +22 -21
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/chat.py +17 -2
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/commands.py +26 -72
- kon_coding_agent-0.3.5/src/kon/ui/export.py +693 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/floating_list.py +70 -8
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/session_ui.py +14 -52
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/widgets.py +116 -42
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/context/test_skills.py +1 -1
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_handoff.py +4 -6
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_launch_warnings.py +1 -1
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_openai_compat.py +108 -1
- kon_coding_agent-0.3.5/tests/test_session_queries.py +61 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_session_resume.py +1 -5
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/tools/test_edit_display.py +2 -2
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/uv.lock +1 -1
- kon_coding_agent-0.3.3/docs/local-models.md +0 -42
- kon_coding_agent-0.3.3/src/kon/ui/export.py +0 -330
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/.gitignore +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/.kon/skills/kon-tmux-test/SKILL.md +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/.kon/skills/kon-tmux-test/run-e2e-tests.sh +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/.kon/skills/kon-tmux-test/setup-test-project.sh +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/.python-version +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/LICENSE +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/README.md +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/docs/architecture-review.md +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/docs/images/kon-screenshot.png +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/scripts/show_themes.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/__init__.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/async_utils.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/builtin_skills/init/SKILL.md +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/context/__init__.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/context/_xml.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/context/agent_mds.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/context/git.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/context/loader.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/context/skills.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/core/__init__.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/core/compaction.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/core/handoff.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/core/types.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/defaults/__init__.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/events.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/__init__.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/models.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/oauth/__init__.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/oauth/copilot.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/oauth/openai.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/providers/__init__.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/providers/anthropic.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/providers/azure_ai_foundry.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/providers/copilot.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/providers/copilot_anthropic.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/providers/github_copilot_headers.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/providers/mock.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/providers/openai_codex_responses.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/providers/openai_compat.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/providers/sanitize.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/loop.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/permissions.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/py.typed +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/themes.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/tools/__init__.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/tools/_read_image.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/tools/_tool_utils.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/tools/base.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/tools/bash.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/tools/find.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/tools/grep.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/tools/read.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/tools/web_fetch.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/tools/web_search.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/tools/write.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/tools_manager.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/turn.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/__init__.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/app_protocol.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/autocomplete.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/blocks.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/clipboard.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/formatting.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/input.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/path_complete.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/prompt_history.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/selection_mode.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/ui/styles.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/update_check.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/conftest.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/context/test_agents.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/llm/__init__.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/llm/test_anthropic_provider.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/llm/test_azure_ai_foundry_provider.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/llm/test_mock_provider.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/llm/test_openai_codex_provider_errors.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/llm/test_openai_oauth.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_agentic_loop.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_cli_auth_flags.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_cli_provider_resolution.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_compaction.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_config_binaries.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_config_error_fallback.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_config_injection.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_config_migration.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_handoff_link_interrupt.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_local_auth_config.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_model_provider_resolution.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_permissions.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_session_persistence.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_system_prompt.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_system_prompt_git_context.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_tools_manager.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_update_check.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/test_update_notice_behavior.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/tools/test_diff.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/tools/test_edit.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/tools/test_read.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/tools/test_read_image.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/tools/test_read_image_integration.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/tools/test_subprocess_cancellation.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/tools/test_write.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/ui/test_autocomplete.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/ui/test_floating_list.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/ui/test_input_handoff.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/ui/test_input_paste.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/ui/test_prompt_history.py +0 -0
- {kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/tests/ui/test_status_line.py +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.12","3.13", "3.14"]
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v3
|
|
16
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
17
|
+
uses: actions/setup-python@v4
|
|
18
|
+
with:
|
|
19
|
+
python-version: ${{ matrix.python-version }}
|
|
20
|
+
cache: pip
|
|
21
|
+
cache-dependency-path: pyproject.toml
|
|
22
|
+
- name: Cache models
|
|
23
|
+
uses: actions/cache@v3
|
|
24
|
+
with:
|
|
25
|
+
path: ~/.cache
|
|
26
|
+
key: ${{ runner.os }}-torch-
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: |
|
|
29
|
+
pip install . --group dev
|
|
30
|
+
- name: Run tests
|
|
31
|
+
run: |
|
|
32
|
+
python -m pytest -s
|
|
33
|
+
|
|
@@ -33,38 +33,44 @@ Use this skill when the user asks to cut a new Kon version, tag it, publish to P
|
|
|
33
33
|
- `git status --short --branch` must be clean (or confirm with user)
|
|
34
34
|
- `git tag --list` and `git log --oneline <prev_tag>..HEAD` to summarize changes
|
|
35
35
|
|
|
36
|
-
2. **
|
|
36
|
+
2. **Update CHANGELOG.md**
|
|
37
|
+
- Replace the `## [Unreleased]` section's `- No changes yet.` with a new versioned heading: `## <version> - YYYY-MM-DD`
|
|
38
|
+
- Use `git log --oneline <prev_tag>..HEAD` to categorize changes into `### Added`, `### Changed`, `### Fixed` sections
|
|
39
|
+
- Credit external contributors with `- @username`
|
|
40
|
+
- Commit message: `docs: update changelog for <version>`
|
|
41
|
+
|
|
42
|
+
3. **Version bump**
|
|
37
43
|
- Update version in all 3 files above
|
|
38
44
|
|
|
39
|
-
|
|
45
|
+
4. **Quality gates**
|
|
40
46
|
- `uv run ruff format .`
|
|
41
47
|
- `uv run ruff check .`
|
|
42
48
|
- `uv run pyright .`
|
|
43
49
|
- `uv run pytest`
|
|
44
50
|
|
|
45
|
-
|
|
51
|
+
5. **Commit**
|
|
46
52
|
- Commit message: `build: bump version to <version>`
|
|
47
53
|
|
|
48
|
-
|
|
54
|
+
6. **Tag**
|
|
49
55
|
- Annotated tag: `git tag -a v<version> -m "v<version> ..."`
|
|
50
|
-
- Include concise
|
|
56
|
+
- Include concise "changes since previous tag" bullets
|
|
51
57
|
|
|
52
|
-
|
|
58
|
+
7. **Push**
|
|
53
59
|
- `git push origin main`
|
|
54
60
|
- `git push origin v<version>`
|
|
55
61
|
|
|
56
|
-
|
|
62
|
+
8. **Build + verify artifacts**
|
|
57
63
|
- `rm -rf dist && uv build`
|
|
58
64
|
- `uv run python -m twine check dist/*`
|
|
59
65
|
|
|
60
|
-
|
|
66
|
+
9. **Publish to PyPI**
|
|
61
67
|
- Prefer token file if present (example `~/.pypi-token`):
|
|
62
68
|
- `TWINE_USERNAME=__token__ TWINE_PASSWORD="$(< ~/.pypi-token)" uv run python -m twine upload dist/*`
|
|
63
69
|
- Verify:
|
|
64
70
|
- `https://pypi.org/project/kon-coding-agent/<version>/`
|
|
65
71
|
- `https://pypi.org/pypi/kon-coding-agent/json` reports latest version
|
|
66
72
|
|
|
67
|
-
|
|
73
|
+
10. **Create GitHub release**
|
|
68
74
|
- If token exists at `~/.github-token`, call Releases API:
|
|
69
75
|
- `POST /repos/<owner>/<repo>/releases` with:
|
|
70
76
|
- `tag_name: v<version>`
|
|
@@ -83,6 +89,7 @@ Use this skill when the user asks to cut a new Kon version, tag it, publish to P
|
|
|
83
89
|
|
|
84
90
|
## Output checklist to report
|
|
85
91
|
|
|
92
|
+
- Changelog updated for `<version>`
|
|
86
93
|
- Version bumped in all files
|
|
87
94
|
- Checks passed
|
|
88
95
|
- Commit hash
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
- Don't add trivial docstrings. Only add docstrings when explaining complex functionality.
|
|
6
6
|
- This project uses `uv`. Run `uv run ruff format .` after editing or creating any files.
|
|
7
|
+
- If generating and running a Python script, use `uv run python` instead of `python`.
|
|
7
8
|
|
|
8
9
|
## Testing
|
|
9
10
|
|
|
@@ -6,6 +6,70 @@ All notable changes to this project will be documented in this file.
|
|
|
6
6
|
|
|
7
7
|
- No changes yet.
|
|
8
8
|
|
|
9
|
+
## 0.3.5 - 2026-04-18
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Standalone session HTML export with self-contained styling.
|
|
14
|
+
- Configurable request timeout for API calls - @jspruit.
|
|
15
|
+
- GitHub CI tests for Python 3.12–3.13 - @sukhbinder.
|
|
16
|
+
- Width-aware popup lists and queue display.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Highlight color applied to the second column in floating lists.
|
|
21
|
+
- Batch scroll during streaming, cache query_one lookups, pause spinner timer when idle.
|
|
22
|
+
- Diff line length capped at 200 characters.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Persist thinking level in session header and change all defaults to high.
|
|
27
|
+
- Normalize OpenAI provider imports.
|
|
28
|
+
- Widen resume popup labels.
|
|
29
|
+
- Remove unused UI app import.
|
|
30
|
+
|
|
31
|
+
### Performance
|
|
32
|
+
|
|
33
|
+
- Added `gc.freeze()` and `PAUSE_GC_ON_SCROLL` to reduce GC stutters.
|
|
34
|
+
|
|
35
|
+
## 0.3.4 - 2026-04-10
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- Fixed Windows UTF-8 encoding errors in file operations - @sukhbinder.
|
|
40
|
+
- Fixed local Gemma model thinking block compatibility.
|
|
41
|
+
- Removed duplicate force-include for builtin skills in build config.
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- Updated local model documentation.
|
|
46
|
+
|
|
47
|
+
## 0.3.3 - 2026-04-08
|
|
48
|
+
|
|
49
|
+
### Added
|
|
50
|
+
|
|
51
|
+
- Added queued agent steering between turns - @0xku.
|
|
52
|
+
- Added bundled `/init` slash command for project scaffolding - @0xku.
|
|
53
|
+
- Added help info for queue and steer queue commands.
|
|
54
|
+
- Added GLM-5.1 support for zai provider.
|
|
55
|
+
|
|
56
|
+
### Changed
|
|
57
|
+
|
|
58
|
+
- Improved read tool directory listings.
|
|
59
|
+
- Updated README with steer queue documentation.
|
|
60
|
+
- Added `$` icon for bash, `%` for web tools, and `←` for edit tool.
|
|
61
|
+
- Used muted color for shortcut key hints in exit/delete prompts.
|
|
62
|
+
|
|
63
|
+
### Fixed
|
|
64
|
+
|
|
65
|
+
- Let ESC interrupt retry backoff immediately - @0xku.
|
|
66
|
+
- Fixed OpenAI login stdin leak by removing orphaned thread - @Meltedd.
|
|
67
|
+
- Fixed OpenAI and Anthropic local compat with auth flags.
|
|
68
|
+
- Fixed interrupt handling before handoff thread switch.
|
|
69
|
+
- Fixed subprocess communication drain on cancellation/timeout.
|
|
70
|
+
- Added zipfile path traversal validation.
|
|
71
|
+
- Removed token throughput metrics.
|
|
72
|
+
|
|
9
73
|
## 0.3.2 - 2026-03-22
|
|
10
74
|
|
|
11
75
|
### Added
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Local Models
|
|
2
|
+
|
|
3
|
+
This document provides detailed information about running and configuring local models with Kon.
|
|
4
|
+
|
|
5
|
+
## Tested Models
|
|
6
|
+
|
|
7
|
+
> Tested on llama server build b8740
|
|
8
|
+
|
|
9
|
+
| Model | Quantization | Context Length | TPS | System Specs |
|
|
10
|
+
| ----- | -------------- | -------------- | --- | ------------ |
|
|
11
|
+
| `zai-org/glm-4.7-flash` | Q4_K_M | 65,536 | N/A | i7-14700F × 28, 64GB RAM, 24GB VRAM (RTX 3090) |
|
|
12
|
+
| `unsloth/Qwen3.5-27B-GGUF` | Q4_K_M | 32,768 | ~30 | i7-14700F × 28, 64GB RAM, 24GB VRAM (RTX 3090) |
|
|
13
|
+
| `unsloth/gemma-4-26B-A4B-it-GGUF` | UD-Q4_K_M | 32,768 | ~100 | i7-14700F × 28, 64GB RAM, 24GB VRAM (RTX 3090) |
|
|
14
|
+
|
|
15
|
+
Run Qwen3.5 27B on an RTX 3090 with a 32k context window using llama-server:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
/path-to-llama-server/llama-server \
|
|
19
|
+
--model /path-to-model/Qwen3.5-27B-Q4_K_M.gguf \
|
|
20
|
+
--port 5000 \
|
|
21
|
+
--ctx-size 32768 \
|
|
22
|
+
--gpu-layers all \
|
|
23
|
+
--threads 8 \
|
|
24
|
+
--threads-batch 8 \
|
|
25
|
+
--batch-size 1024 \
|
|
26
|
+
--ubatch-size 512 \
|
|
27
|
+
--flash-attn on
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
On this machine, that setup generates at roughly 30 tokens per second.
|
|
31
|
+
|
|
32
|
+
Then start Kon for a one-off local session:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
kon --model unsloth/Qwen3.5-27B-GGUF --provider openai \
|
|
36
|
+
--base-url http://localhost:5000/v1 \
|
|
37
|
+
--openai-compat-auth none
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Run Gemma 4 26B A4B on the same machine using llama-server:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
/path-to-llama-server/llama-server \
|
|
44
|
+
--model /path-to-model/gemma-4-26B-A4B-it-UD-Q4_K_M.gguf \
|
|
45
|
+
--port 5000 \
|
|
46
|
+
--ctx-size 32768 \
|
|
47
|
+
--gpu-layers all \
|
|
48
|
+
--threads 8 \
|
|
49
|
+
--threads-batch 8 \
|
|
50
|
+
--batch-size 1024 \
|
|
51
|
+
--ubatch-size 512 \
|
|
52
|
+
--flash-attn on \
|
|
53
|
+
--temperature 1.5
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Then start Kon against that local server:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
kon --model unsloth/gemma-4-26B-A4B-it-GGUF --provider openai \
|
|
60
|
+
--base-url http://localhost:5000/v1 \
|
|
61
|
+
--openai-compat-auth none
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
To avoid passing provider, model, and auth flags every time you start Kon, you can define your local setup in `~/.kon/config.toml`. This also allows you to tune compaction to trigger at a specific point relative to your model's context window.
|
|
65
|
+
|
|
66
|
+
If this is your default setup, put it in `~/.kon/config.toml` instead:
|
|
67
|
+
|
|
68
|
+
```toml
|
|
69
|
+
[llm]
|
|
70
|
+
default_provider = "openai"
|
|
71
|
+
default_model = "unsloth/gemma-4-26B-A4B-it-GGUF"
|
|
72
|
+
default_base_url = "http://localhost:5000/v1"
|
|
73
|
+
|
|
74
|
+
[llm.auth]
|
|
75
|
+
openai_compat = "none" # or "auto"
|
|
76
|
+
|
|
77
|
+
[compaction]
|
|
78
|
+
# Set this close to your model's context size (e.g., 30000 for a 32k window)
|
|
79
|
+
buffer_tokens = 27768 # 32768 - 5000 (safety margin)
|
|
80
|
+
```
|
|
@@ -11,6 +11,9 @@ default_thinking_level = "high"
|
|
|
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
|
|
14
|
+
# HTTP request timeout for LLM API calls (in seconds).
|
|
15
|
+
# Local models (e.g. llama.cpp) may need a higher value for long compaction requests.
|
|
16
|
+
request_timeout_seconds = 600
|
|
14
17
|
|
|
15
18
|
[llm.auth]
|
|
16
19
|
# Auth policy for OpenAI-compatible and Anthropic-compatible endpoints.
|
|
@@ -77,7 +77,7 @@ class ProviderConfig:
|
|
|
77
77
|
model: str = ""
|
|
78
78
|
max_tokens: int = 8192
|
|
79
79
|
temperature: float | None = None
|
|
80
|
-
thinking_level: str = "
|
|
80
|
+
thinking_level: str = "high"
|
|
81
81
|
provider: str | None = None
|
|
82
82
|
session_id: str | None = None
|
|
83
83
|
openai_compat_auth_mode: AuthMode = "auto"
|
{kon_coding_agent-0.3.3 → kon_coding_agent-0.3.5}/src/kon/llm/providers/openai_completions.py
RENAMED
|
@@ -10,6 +10,8 @@ from openai.types.chat import (
|
|
|
10
10
|
ChatCompletionToolParam,
|
|
11
11
|
)
|
|
12
12
|
|
|
13
|
+
from kon import config as kon_config
|
|
14
|
+
|
|
13
15
|
from ...core.types import (
|
|
14
16
|
AssistantMessage,
|
|
15
17
|
ImageContent,
|
|
@@ -30,7 +32,7 @@ from ...core.types import (
|
|
|
30
32
|
Usage,
|
|
31
33
|
UserMessage,
|
|
32
34
|
)
|
|
33
|
-
from ..base import BaseProvider, LLMStream, ProviderConfig, resolve_api_key
|
|
35
|
+
from ..base import BaseProvider, LLMStream, ProviderConfig, is_local_base_url, resolve_api_key
|
|
34
36
|
from .openai_compat import supports_developer_role
|
|
35
37
|
from .sanitize import sanitize_surrogates
|
|
36
38
|
|
|
@@ -41,12 +43,13 @@ class OpenAICompletionsCompat:
|
|
|
41
43
|
supports_developer_role: bool = True
|
|
42
44
|
supports_reasoning_effort: bool = True
|
|
43
45
|
max_tokens_field: Literal["max_tokens", "max_completion_tokens"] = "max_completion_tokens"
|
|
44
|
-
thinking_format: Literal["openai", "zai", "qwen"] = "openai"
|
|
46
|
+
thinking_format: Literal["openai", "zai", "qwen", "llama_gemma"] = "openai"
|
|
45
47
|
|
|
46
48
|
|
|
47
|
-
def _detect_compat(provider: str, base_url: str) -> OpenAICompletionsCompat:
|
|
49
|
+
def _detect_compat(provider: str, base_url: str, model: str = "") -> OpenAICompletionsCompat:
|
|
48
50
|
normalized_provider = provider.lower()
|
|
49
51
|
normalized_base_url = base_url.lower()
|
|
52
|
+
normalized_model = model.lower()
|
|
50
53
|
is_zai = (
|
|
51
54
|
normalized_provider == "zai"
|
|
52
55
|
or normalized_provider == "zhipu"
|
|
@@ -61,6 +64,13 @@ def _detect_compat(provider: str, base_url: str) -> OpenAICompletionsCompat:
|
|
|
61
64
|
thinking_format="zai",
|
|
62
65
|
)
|
|
63
66
|
|
|
67
|
+
if is_local_base_url(base_url) and "gemma" in normalized_model:
|
|
68
|
+
return OpenAICompletionsCompat(
|
|
69
|
+
supports_developer_role=supports_developer_role(provider, base_url),
|
|
70
|
+
supports_reasoning_effort=False,
|
|
71
|
+
thinking_format="llama_gemma",
|
|
72
|
+
)
|
|
73
|
+
|
|
64
74
|
return OpenAICompletionsCompat(
|
|
65
75
|
supports_developer_role=supports_developer_role(provider, base_url)
|
|
66
76
|
)
|
|
@@ -91,8 +101,14 @@ class OpenAICompletionsProvider(BaseProvider):
|
|
|
91
101
|
"Set OPENAI_API_KEY or ZAI_API_KEY environment variable, "
|
|
92
102
|
'or configure llm.auth.openai_compat = "auto"/"none" for local endpoints.'
|
|
93
103
|
)
|
|
94
|
-
self._client = AsyncOpenAI(
|
|
95
|
-
|
|
104
|
+
self._client = AsyncOpenAI(
|
|
105
|
+
api_key=api_key,
|
|
106
|
+
base_url=config.base_url,
|
|
107
|
+
timeout=kon_config.llm.request_timeout_seconds,
|
|
108
|
+
)
|
|
109
|
+
self._compat = _detect_compat(
|
|
110
|
+
config.provider or "", config.base_url or "", config.model or ""
|
|
111
|
+
)
|
|
96
112
|
|
|
97
113
|
async def _stream_impl(
|
|
98
114
|
self,
|
|
@@ -138,7 +154,7 @@ class OpenAICompletionsProvider(BaseProvider):
|
|
|
138
154
|
if compat.thinking_format == "zai":
|
|
139
155
|
if thinking_level and thinking_level != "none":
|
|
140
156
|
extra_body["thinking"] = {"type": "enabled"}
|
|
141
|
-
elif compat.thinking_format
|
|
157
|
+
elif compat.thinking_format in {"qwen", "llama_gemma"}:
|
|
142
158
|
extra_body["enable_thinking"] = bool(thinking_level and thinking_level != "none")
|
|
143
159
|
elif (
|
|
144
160
|
self.supports_reasoning_effort
|
|
@@ -238,11 +254,16 @@ class OpenAICompletionsProvider(BaseProvider):
|
|
|
238
254
|
|
|
239
255
|
if system_prompt:
|
|
240
256
|
role = "developer" if (compat and compat.supports_developer_role) else "system"
|
|
257
|
+
prompt_content = sanitize_surrogates(system_prompt)
|
|
258
|
+
if (
|
|
259
|
+
compat
|
|
260
|
+
and compat.thinking_format == "llama_gemma"
|
|
261
|
+
and self.config.thinking_level != "none"
|
|
262
|
+
and not prompt_content.startswith("<|think|>")
|
|
263
|
+
):
|
|
264
|
+
prompt_content = "<|think|>" + prompt_content
|
|
241
265
|
result.append(
|
|
242
|
-
cast(
|
|
243
|
-
ChatCompletionMessageParam,
|
|
244
|
-
{"role": role, "content": sanitize_surrogates(system_prompt)},
|
|
245
|
-
)
|
|
266
|
+
cast(ChatCompletionMessageParam, {"role": role, "content": prompt_content})
|
|
246
267
|
)
|
|
247
268
|
|
|
248
269
|
pending_images: list[ImageContent] = []
|
|
@@ -4,6 +4,8 @@ from typing import Any
|
|
|
4
4
|
|
|
5
5
|
from openai import APIStatusError, AsyncOpenAI, RateLimitError
|
|
6
6
|
|
|
7
|
+
from kon import config as kon_config
|
|
8
|
+
|
|
7
9
|
from ...core.types import (
|
|
8
10
|
AssistantMessage,
|
|
9
11
|
ImageContent,
|
|
@@ -51,6 +53,7 @@ class OpenAIResponsesProvider(BaseProvider):
|
|
|
51
53
|
api_key=self.config.api_key,
|
|
52
54
|
base_url=self.config.base_url,
|
|
53
55
|
default_headers=self._headers,
|
|
56
|
+
timeout=kon_config.llm.request_timeout_seconds,
|
|
54
57
|
)
|
|
55
58
|
return self._client
|
|
56
59
|
|