kon-coding-agent 0.3.4__tar.gz → 0.3.6__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.6/.github/workflows/test.yml +33 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/.kon/skills/kon-release-publish/SKILL.md +16 -9
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/AGENTS.md +1 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/CHANGELOG.md +86 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/PKG-INFO +4 -8
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/README.md +0 -6
- kon_coding_agent-0.3.6/docs/code-health-scan.md +144 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/pyproject.toml +9 -3
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/config.py +10 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/defaults/config.toml +8 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/base.py +1 -1
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/providers/openai_codex_responses.py +21 -5
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/providers/openai_completions.py +7 -1
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/providers/openai_responses.py +3 -0
- kon_coding_agent-0.3.6/src/kon/notify.py +30 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/session.py +144 -13
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/tools/edit.py +1 -1
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/tools/find.py +1 -3
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/tools/grep.py +1 -3
- kon_coding_agent-0.3.6/src/kon/tools/web_fetch.py +160 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/turn.py +4 -6
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/app.py +36 -21
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/blocks.py +13 -6
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/chat.py +83 -13
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/commands.py +33 -90
- kon_coding_agent-0.3.6/src/kon/ui/export.py +693 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/floating_list.py +70 -8
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/formatting.py +3 -0
- kon_coding_agent-0.3.6/src/kon/ui/latex.py +349 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/session_ui.py +14 -52
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/styles.py +19 -3
- kon_coding_agent-0.3.6/src/kon/ui/welcome.py +85 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/widgets.py +116 -42
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/context/test_skills.py +1 -1
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_handoff.py +4 -6
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_launch_warnings.py +1 -1
- kon_coding_agent-0.3.6/tests/test_notifications_config.py +64 -0
- kon_coding_agent-0.3.6/tests/test_notify.py +46 -0
- kon_coding_agent-0.3.6/tests/test_session_queries.py +61 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_session_resume.py +1 -5
- kon_coding_agent-0.3.6/tests/test_ui_notifications.py +32 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/tools/test_edit_display.py +2 -2
- kon_coding_agent-0.3.6/tests/ui/test_latex.py +60 -0
- kon_coding_agent-0.3.6/tests/ui/test_styles.py +16 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/uv.lock +122 -222
- kon_coding_agent-0.3.4/src/kon/tools/web_fetch.py +0 -79
- kon_coding_agent-0.3.4/src/kon/ui/export.py +0 -330
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/.gitignore +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/.kon/skills/kon-tmux-test/SKILL.md +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/.kon/skills/kon-tmux-test/run-e2e-tests.sh +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/.kon/skills/kon-tmux-test/setup-test-project.sh +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/.python-version +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/LICENSE +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/docs/architecture-review.md +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/docs/images/kon-screenshot.png +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/docs/local-models.md +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/scripts/show_themes.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/__init__.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/async_utils.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/builtin_skills/init/SKILL.md +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/context/__init__.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/context/_xml.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/context/agent_mds.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/context/git.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/context/loader.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/context/skills.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/core/__init__.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/core/compaction.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/core/handoff.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/core/types.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/defaults/__init__.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/events.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/__init__.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/models.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/oauth/__init__.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/oauth/copilot.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/oauth/openai.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/providers/__init__.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/providers/anthropic.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/providers/azure_ai_foundry.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/providers/copilot.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/providers/copilot_anthropic.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/providers/github_copilot_headers.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/providers/mock.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/providers/openai_compat.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/llm/providers/sanitize.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/loop.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/permissions.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/py.typed +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/themes.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/tools/__init__.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/tools/_read_image.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/tools/_tool_utils.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/tools/base.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/tools/bash.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/tools/read.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/tools/web_search.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/tools/write.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/tools_manager.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/__init__.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/app_protocol.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/autocomplete.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/clipboard.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/input.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/path_complete.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/prompt_history.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/ui/selection_mode.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/src/kon/update_check.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/conftest.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/context/test_agents.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/llm/__init__.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/llm/test_anthropic_provider.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/llm/test_azure_ai_foundry_provider.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/llm/test_mock_provider.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/llm/test_openai_codex_provider_errors.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/llm/test_openai_oauth.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_agentic_loop.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_cli_auth_flags.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_cli_provider_resolution.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_compaction.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_config_binaries.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_config_error_fallback.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_config_injection.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_config_migration.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_handoff_link_interrupt.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_local_auth_config.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_model_provider_resolution.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_openai_compat.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_permissions.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_session_persistence.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_system_prompt.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_system_prompt_git_context.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_tools_manager.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_update_check.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/test_update_notice_behavior.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/tools/test_diff.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/tools/test_edit.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/tools/test_read.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/tools/test_read_image.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/tools/test_read_image_integration.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/tools/test_subprocess_cancellation.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/tools/test_write.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/ui/test_autocomplete.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/ui/test_floating_list.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/ui/test_input_handoff.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/ui/test_input_paste.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/tests/ui/test_prompt_history.py +0 -0
- {kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/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,92 @@ All notable changes to this project will be documented in this file.
|
|
|
6
6
|
|
|
7
7
|
- No changes yet.
|
|
8
8
|
|
|
9
|
+
## 0.3.6 - 2026-04-23
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Configurable terminal bell notifications on response completion.
|
|
14
|
+
- Render LaTeX math as Unicode in markdown output - @toojays.
|
|
15
|
+
- Style approval popup with button-like controls and panel background.
|
|
16
|
+
- Permission popup title card and improved UI formatting.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Improved UI for approval popup.
|
|
21
|
+
- Reduce LaTeX preprocessing overhead.
|
|
22
|
+
- Improved Codex SSE error extraction and retry on transient errors.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Rewrite web_fetch to bypass bot-detection, preserve indentation, and harden against SSRF - @Meltedd (#28, #29).
|
|
27
|
+
- Remove unused turn streaming state.
|
|
28
|
+
- Remove unused tool imports.
|
|
29
|
+
- Remove empty blocks.
|
|
30
|
+
|
|
31
|
+
## 0.3.5 - 2026-04-18
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- Standalone session HTML export with self-contained styling.
|
|
36
|
+
- Configurable request timeout for API calls - @jspruit.
|
|
37
|
+
- GitHub CI tests for Python 3.12–3.13 - @sukhbinder.
|
|
38
|
+
- Width-aware popup lists and queue display.
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- Highlight color applied to the second column in floating lists.
|
|
43
|
+
- Batch scroll during streaming, cache query_one lookups, pause spinner timer when idle.
|
|
44
|
+
- Diff line length capped at 200 characters.
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
|
|
48
|
+
- Persist thinking level in session header and change all defaults to high.
|
|
49
|
+
- Normalize OpenAI provider imports.
|
|
50
|
+
- Widen resume popup labels.
|
|
51
|
+
- Remove unused UI app import.
|
|
52
|
+
|
|
53
|
+
### Performance
|
|
54
|
+
|
|
55
|
+
- Added `gc.freeze()` and `PAUSE_GC_ON_SCROLL` to reduce GC stutters.
|
|
56
|
+
|
|
57
|
+
## 0.3.4 - 2026-04-10
|
|
58
|
+
|
|
59
|
+
### Fixed
|
|
60
|
+
|
|
61
|
+
- Fixed Windows UTF-8 encoding errors in file operations - @sukhbinder.
|
|
62
|
+
- Fixed local Gemma model thinking block compatibility.
|
|
63
|
+
- Removed duplicate force-include for builtin skills in build config.
|
|
64
|
+
|
|
65
|
+
### Changed
|
|
66
|
+
|
|
67
|
+
- Updated local model documentation.
|
|
68
|
+
|
|
69
|
+
## 0.3.3 - 2026-04-08
|
|
70
|
+
|
|
71
|
+
### Added
|
|
72
|
+
|
|
73
|
+
- Added queued agent steering between turns - @0xku.
|
|
74
|
+
- Added bundled `/init` slash command for project scaffolding - @0xku.
|
|
75
|
+
- Added help info for queue and steer queue commands.
|
|
76
|
+
- Added GLM-5.1 support for zai provider.
|
|
77
|
+
|
|
78
|
+
### Changed
|
|
79
|
+
|
|
80
|
+
- Improved read tool directory listings.
|
|
81
|
+
- Updated README with steer queue documentation.
|
|
82
|
+
- Added `$` icon for bash, `%` for web tools, and `←` for edit tool.
|
|
83
|
+
- Used muted color for shortcut key hints in exit/delete prompts.
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
|
|
87
|
+
- Let ESC interrupt retry backoff immediately - @0xku.
|
|
88
|
+
- Fixed OpenAI login stdin leak by removing orphaned thread - @Meltedd.
|
|
89
|
+
- Fixed OpenAI and Anthropic local compat with auth flags.
|
|
90
|
+
- Fixed interrupt handling before handoff thread switch.
|
|
91
|
+
- Fixed subprocess communication drain on cancellation/timeout.
|
|
92
|
+
- Added zipfile path traversal validation.
|
|
93
|
+
- Removed token throughput metrics.
|
|
94
|
+
|
|
9
95
|
## 0.3.2 - 2026-03-22
|
|
10
96
|
|
|
11
97
|
### Added
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kon-coding-agent
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.6
|
|
4
4
|
Summary: Minimal coding agent
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Python: >=3.12
|
|
7
7
|
Requires-Dist: aiofiles>=25.1.0
|
|
8
8
|
Requires-Dist: aiohttp>=3.13.3
|
|
9
9
|
Requires-Dist: anthropic>=0.79.0
|
|
10
|
+
Requires-Dist: curl-cffi>=0.15.0
|
|
10
11
|
Requires-Dist: ddgs>=9.0.0
|
|
12
|
+
Requires-Dist: html-to-markdown>=3.1.0
|
|
11
13
|
Requires-Dist: openai>=2.21.0
|
|
12
14
|
Requires-Dist: pillow>=12.1.1
|
|
13
15
|
Requires-Dist: pydantic>=2.12.5
|
|
16
|
+
Requires-Dist: readability-lxml>=0.8.4
|
|
14
17
|
Requires-Dist: rich>=14.3.2
|
|
15
18
|
Requires-Dist: textual>=8.0.0
|
|
16
|
-
Requires-Dist: trafilatura>=2.0.0
|
|
17
19
|
Description-Content-Type: text/markdown
|
|
18
20
|
|
|
19
21
|
<h1 align="center">Kon</h1>
|
|
@@ -475,12 +477,6 @@ If `fd` or `rg` are missing, Kon can download them automatically.
|
|
|
475
477
|
|
|
476
478
|
---
|
|
477
479
|
|
|
478
|
-
## Documentation
|
|
479
|
-
|
|
480
|
-
- [Local models](docs/local-models.md) - Running Kon with local OpenAI-compatible models, plus tested setups and example commands.
|
|
481
|
-
|
|
482
|
-
---
|
|
483
|
-
|
|
484
480
|
## Acknowledgements
|
|
485
481
|
|
|
486
482
|
- Kon takes significant inspiration from [pi coding-agent](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent), especially around philosophy and UI direction.
|
|
@@ -457,12 +457,6 @@ If `fd` or `rg` are missing, Kon can download them automatically.
|
|
|
457
457
|
|
|
458
458
|
---
|
|
459
459
|
|
|
460
|
-
## Documentation
|
|
461
|
-
|
|
462
|
-
- [Local models](docs/local-models.md) - Running Kon with local OpenAI-compatible models, plus tested setups and example commands.
|
|
463
|
-
|
|
464
|
-
---
|
|
465
|
-
|
|
466
460
|
## Acknowledgements
|
|
467
461
|
|
|
468
462
|
- Kon takes significant inspiration from [pi coding-agent](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent), especially around philosophy and UI direction.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Code Health Scan: Additional Notable Issues
|
|
2
|
+
|
|
3
|
+
This note captures only the additional issues found in a fresh repo scan that are **not** the same as the already-known architectural concerns in `docs/architecture-review.md`.
|
|
4
|
+
|
|
5
|
+
The baseline conclusion from the earlier review still stands:
|
|
6
|
+
|
|
7
|
+
- the core runtime is strong
|
|
8
|
+
- the TUI still owns too much runtime/session orchestration
|
|
9
|
+
- the large controller/runtime-manager refactor is deferred for now
|
|
10
|
+
|
|
11
|
+
This document is intentionally narrower. It records only the standout issue and the smaller cleanup opportunities found in the current repo state after the recent cleanup pass.
|
|
12
|
+
|
|
13
|
+
## Overall verdict
|
|
14
|
+
|
|
15
|
+
Aside from the already-documented UI/runtime orchestration boundary issue, the repo looks to be in decent shape overall.
|
|
16
|
+
|
|
17
|
+
Notable signals:
|
|
18
|
+
|
|
19
|
+
- test suite passed cleanly
|
|
20
|
+
- pyright passed cleanly
|
|
21
|
+
- only a few lint issues remained
|
|
22
|
+
|
|
23
|
+
So this is **not** a case where the repo appears to have multiple additional architectural problems lurking elsewhere. The main new thing worth tracking is a state-consistency problem around provider/model transitions, plus a few smaller cleanup items.
|
|
24
|
+
|
|
25
|
+
## Major issue
|
|
26
|
+
|
|
27
|
+
### Provider/model transition paths are not transactional
|
|
28
|
+
|
|
29
|
+
The main additional issue is that some provider/model/session transition flows update app state before it is certain that the replacement provider/runtime state can be constructed successfully.
|
|
30
|
+
|
|
31
|
+
Relevant files:
|
|
32
|
+
|
|
33
|
+
- `src/kon/ui/commands.py`
|
|
34
|
+
- `src/kon/ui/session_ui.py`
|
|
35
|
+
|
|
36
|
+
### Where it shows up
|
|
37
|
+
|
|
38
|
+
#### `src/kon/ui/commands.py::_select_model`
|
|
39
|
+
|
|
40
|
+
This path updates:
|
|
41
|
+
|
|
42
|
+
- `self._model`
|
|
43
|
+
- `self._model_provider`
|
|
44
|
+
|
|
45
|
+
before provider recreation is guaranteed to succeed.
|
|
46
|
+
|
|
47
|
+
If `_create_provider(...)` fails, the UI reports the error, but some selected-model state may already have been changed while the active provider/agent runtime is still using the old provider instance.
|
|
48
|
+
|
|
49
|
+
#### `src/kon/ui/session_ui.py::_load_session`
|
|
50
|
+
|
|
51
|
+
This path loads session metadata and updates model/provider-related state while also trying to reconcile the active provider.
|
|
52
|
+
|
|
53
|
+
If provider recreation fails during session load, the code reports the error, but can still leave partially updated state behind:
|
|
54
|
+
|
|
55
|
+
- loaded session state may now be active
|
|
56
|
+
- selected model/provider values may reflect the resumed session
|
|
57
|
+
- the provider instance may still be the old one or only partially reconfigured
|
|
58
|
+
|
|
59
|
+
### Why this matters
|
|
60
|
+
|
|
61
|
+
This is not a large-architecture problem, but it is a real correctness risk.
|
|
62
|
+
|
|
63
|
+
It can produce subtle mismatches between:
|
|
64
|
+
|
|
65
|
+
- selected model/provider UI state
|
|
66
|
+
- active provider config
|
|
67
|
+
- agent runtime state
|
|
68
|
+
- resumed session metadata
|
|
69
|
+
|
|
70
|
+
Those failures are harder to reason about than a simple hard error because the app can continue running in a partially updated state.
|
|
71
|
+
|
|
72
|
+
### Suggested direction
|
|
73
|
+
|
|
74
|
+
Without doing the large architecture refactor, the safer short-term fix would be to make these transitions more atomic:
|
|
75
|
+
|
|
76
|
+
1. compute the target model/provider/session state first
|
|
77
|
+
2. build or validate the replacement provider first
|
|
78
|
+
3. only commit the new state to `self._model`, `self._model_provider`, `self._provider`, `self._session`, and `self._agent` after success
|
|
79
|
+
4. otherwise leave the old runtime state untouched
|
|
80
|
+
|
|
81
|
+
Even a small helper that stages the new state before assignment would reduce the sync-risk significantly.
|
|
82
|
+
|
|
83
|
+
## Small cleanup opportunities
|
|
84
|
+
|
|
85
|
+
### 1. `CompactionEntry.first_kept_entry_id` is currently misleading
|
|
86
|
+
|
|
87
|
+
Relevant file:
|
|
88
|
+
|
|
89
|
+
- `src/kon/session.py`
|
|
90
|
+
|
|
91
|
+
`CompactionEntry` stores `first_kept_entry_id`, and comments imply that the compacted view depends on it.
|
|
92
|
+
|
|
93
|
+
However, `Session.messages` currently reconstructs the compacted view by:
|
|
94
|
+
|
|
95
|
+
- finding the last compaction entry
|
|
96
|
+
- inserting the synthetic summary pair
|
|
97
|
+
- including message entries after the compaction entry itself
|
|
98
|
+
|
|
99
|
+
It does **not** currently use `first_kept_entry_id` to decide what to retain.
|
|
100
|
+
|
|
101
|
+
This is not a functional bug in current usage because existing callers/tests append compaction entries in a way that still makes the behavior correct. But the data model and implementation intent are slightly out of sync, which makes the field more confusing than helpful right now.
|
|
102
|
+
|
|
103
|
+
Small fix options:
|
|
104
|
+
|
|
105
|
+
- actually use `first_kept_entry_id` in `Session.messages`, or
|
|
106
|
+
- simplify the field/comment contract if the compaction-entry position is the real source of truth
|
|
107
|
+
|
|
108
|
+
### 2. System-prompt fallback logic is still duplicated across UI mixins
|
|
109
|
+
|
|
110
|
+
Relevant files:
|
|
111
|
+
|
|
112
|
+
- `src/kon/ui/commands.py`
|
|
113
|
+
- `src/kon/ui/session_ui.py`
|
|
114
|
+
|
|
115
|
+
Both files define the same `_resolve_system_prompt(...)` helper:
|
|
116
|
+
|
|
117
|
+
- use persisted `session.system_prompt` when available
|
|
118
|
+
- otherwise rebuild with `build_system_prompt(...)`
|
|
119
|
+
|
|
120
|
+
This is a small issue, not a major design problem, but it means the recent centralization is still only partial. If the fallback behavior changes again, both copies will need to stay in sync.
|
|
121
|
+
|
|
122
|
+
Small fix option:
|
|
123
|
+
|
|
124
|
+
- move the helper to one shared non-duplicated location used by both mixins/app paths
|
|
125
|
+
|
|
126
|
+
### 3. Lint cleanup remains in a few tool modules
|
|
127
|
+
|
|
128
|
+
Relevant files:
|
|
129
|
+
|
|
130
|
+
- `src/kon/tools/find.py`
|
|
131
|
+
- `src/kon/tools/grep.py`
|
|
132
|
+
- `src/kon/tools/web_fetch.py`
|
|
133
|
+
|
|
134
|
+
Current lint output shows unused imports of `truncate_text` in these files.
|
|
135
|
+
|
|
136
|
+
This is only a hygiene issue, but it is a useful signal that a full lint pass likely did not happen after some recent edits.
|
|
137
|
+
|
|
138
|
+
## Final assessment
|
|
139
|
+
|
|
140
|
+
The repo looks fine overall.
|
|
141
|
+
|
|
142
|
+
Aside from the already-known concerns in `docs/architecture-review.md`, the only additional issue that really stands out is the non-transactional provider/model/session transition behavior.
|
|
143
|
+
|
|
144
|
+
The other findings are small cleanup opportunities rather than signs of deeper architectural trouble.
|
|
@@ -14,7 +14,7 @@ default = true
|
|
|
14
14
|
|
|
15
15
|
[project]
|
|
16
16
|
name = "kon-coding-agent"
|
|
17
|
-
version = "0.3.
|
|
17
|
+
version = "0.3.6"
|
|
18
18
|
description = "Minimal coding agent"
|
|
19
19
|
readme = "README.md"
|
|
20
20
|
requires-python = ">=3.12"
|
|
@@ -22,13 +22,15 @@ dependencies = [
|
|
|
22
22
|
"aiofiles>=25.1.0",
|
|
23
23
|
"aiohttp>=3.13.3",
|
|
24
24
|
"anthropic>=0.79.0",
|
|
25
|
+
"curl-cffi>=0.15.0",
|
|
26
|
+
"ddgs>=9.0.0",
|
|
27
|
+
"html-to-markdown>=3.1.0",
|
|
25
28
|
"openai>=2.21.0",
|
|
26
29
|
"pillow>=12.1.1",
|
|
27
30
|
"pydantic>=2.12.5",
|
|
31
|
+
"readability-lxml>=0.8.4",
|
|
28
32
|
"rich>=14.3.2",
|
|
29
33
|
"textual>=8.0.0",
|
|
30
|
-
"ddgs>=9.0.0",
|
|
31
|
-
"trafilatura>=2.0.0",
|
|
32
34
|
]
|
|
33
35
|
|
|
34
36
|
[dependency-groups]
|
|
@@ -60,6 +62,10 @@ select = [
|
|
|
60
62
|
"RUF", # ruff-specific rules
|
|
61
63
|
]
|
|
62
64
|
|
|
65
|
+
[tool.ruff.lint.per-file-ignores]
|
|
66
|
+
"src/kon/ui/latex.py" = ["RUF001"]
|
|
67
|
+
"tests/ui/test_latex.py" = ["RUF001"]
|
|
68
|
+
|
|
63
69
|
[tool.ruff.lint.isort]
|
|
64
70
|
split-on-trailing-comma = false
|
|
65
71
|
|
|
@@ -76,6 +76,7 @@ class LLMConfig(BaseModel):
|
|
|
76
76
|
default_thinking_level: str
|
|
77
77
|
system_prompt: SystemPromptConfig
|
|
78
78
|
tool_call_idle_timeout_seconds: float = 180
|
|
79
|
+
request_timeout_seconds: float = 600
|
|
79
80
|
auth: AuthConfig = AuthConfig()
|
|
80
81
|
|
|
81
82
|
|
|
@@ -97,6 +98,10 @@ class ToolsConfig(BaseModel):
|
|
|
97
98
|
extra: list[str] = []
|
|
98
99
|
|
|
99
100
|
|
|
101
|
+
class NotificationsConfig(BaseModel):
|
|
102
|
+
enabled: bool = False
|
|
103
|
+
|
|
104
|
+
|
|
100
105
|
class ConfigSchema(BaseModel):
|
|
101
106
|
meta: MetaConfig
|
|
102
107
|
llm: LLMConfig
|
|
@@ -105,6 +110,7 @@ class ConfigSchema(BaseModel):
|
|
|
105
110
|
agent: AgentConfig
|
|
106
111
|
tools: ToolsConfig = ToolsConfig()
|
|
107
112
|
permissions: PermissionsConfig
|
|
113
|
+
notifications: NotificationsConfig = NotificationsConfig()
|
|
108
114
|
|
|
109
115
|
|
|
110
116
|
# =================================================================================================
|
|
@@ -193,6 +199,10 @@ class Config:
|
|
|
193
199
|
def tools(self) -> ToolsConfig:
|
|
194
200
|
return self._parsed.tools
|
|
195
201
|
|
|
202
|
+
@property
|
|
203
|
+
def notifications(self) -> NotificationsConfig:
|
|
204
|
+
return self._parsed.notifications
|
|
205
|
+
|
|
196
206
|
@property
|
|
197
207
|
def binaries(self) -> _BinariesConfig:
|
|
198
208
|
return _BinariesConfig(AVAILABLE_BINARIES)
|
|
@@ -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.
|
|
@@ -70,3 +73,8 @@ collapse_thinking = true
|
|
|
70
73
|
# "prompt" asks before edits/writes and other mutating actions.
|
|
71
74
|
# "auto" allows tool calls without approval prompts.
|
|
72
75
|
mode = "prompt" # "prompt" or "auto"
|
|
76
|
+
|
|
77
|
+
[notifications]
|
|
78
|
+
# Ring the terminal bell when kon finishes a task or waits for tool approval.
|
|
79
|
+
# Disabled by default.
|
|
80
|
+
enabled = false
|
|
@@ -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.4 → kon_coding_agent-0.3.6}/src/kon/llm/providers/openai_codex_responses.py
RENAMED
|
@@ -279,11 +279,26 @@ class OpenAICodexResponsesProvider(BaseProvider):
|
|
|
279
279
|
yield StreamDone(stop_reason=stop_reason)
|
|
280
280
|
return
|
|
281
281
|
|
|
282
|
-
elif event_type
|
|
282
|
+
elif event_type == "error":
|
|
283
|
+
code = event.get("code")
|
|
283
284
|
message = event.get("message")
|
|
284
|
-
if
|
|
285
|
-
|
|
286
|
-
|
|
285
|
+
if isinstance(message, str) and message:
|
|
286
|
+
yield StreamError(error=f"Codex error: {message}")
|
|
287
|
+
elif isinstance(code, str) and code:
|
|
288
|
+
yield StreamError(error=f"Codex error: {code}")
|
|
289
|
+
else:
|
|
290
|
+
yield StreamError(error=f"Codex error: {json.dumps(event)}")
|
|
291
|
+
return
|
|
292
|
+
|
|
293
|
+
elif event_type == "response.failed":
|
|
294
|
+
response_obj = event.get("response")
|
|
295
|
+
msg = None
|
|
296
|
+
if isinstance(response_obj, dict):
|
|
297
|
+
err = response_obj.get("error")
|
|
298
|
+
if isinstance(err, dict):
|
|
299
|
+
msg = err.get("message")
|
|
300
|
+
err_msg = msg if isinstance(msg, str) and msg else "Codex response failed"
|
|
301
|
+
yield StreamError(error=err_msg)
|
|
287
302
|
return
|
|
288
303
|
finally:
|
|
289
304
|
await session.close()
|
|
@@ -321,7 +336,8 @@ class OpenAICodexResponsesProvider(BaseProvider):
|
|
|
321
336
|
return StopReason.STOP
|
|
322
337
|
|
|
323
338
|
def should_retry_for_error(self, error: Exception) -> bool:
|
|
324
|
-
|
|
339
|
+
msg = str(error).lower()
|
|
340
|
+
return any(kw in msg for kw in ("429", "rate_limit", "server_error", "502", "503", "504"))
|
|
325
341
|
|
|
326
342
|
|
|
327
343
|
def is_openai_logged_in() -> bool:
|
{kon_coding_agent-0.3.4 → kon_coding_agent-0.3.6}/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,
|
|
@@ -99,7 +101,11 @@ class OpenAICompletionsProvider(BaseProvider):
|
|
|
99
101
|
"Set OPENAI_API_KEY or ZAI_API_KEY environment variable, "
|
|
100
102
|
'or configure llm.auth.openai_compat = "auto"/"none" for local endpoints.'
|
|
101
103
|
)
|
|
102
|
-
self._client = AsyncOpenAI(
|
|
104
|
+
self._client = AsyncOpenAI(
|
|
105
|
+
api_key=api_key,
|
|
106
|
+
base_url=config.base_url,
|
|
107
|
+
timeout=kon_config.llm.request_timeout_seconds,
|
|
108
|
+
)
|
|
103
109
|
self._compat = _detect_compat(
|
|
104
110
|
config.provider or "", config.base_url or "", config.model or ""
|
|
105
111
|
)
|
|
@@ -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
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
_BELL_DEBOUNCE_S = 0.5
|
|
5
|
+
_last_bell_time: float = 0.0
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _raw_write(data: bytes) -> None:
|
|
9
|
+
try:
|
|
10
|
+
fd = os.open("/dev/tty", os.O_WRONLY | os.O_NOCTTY)
|
|
11
|
+
try:
|
|
12
|
+
os.write(fd, data)
|
|
13
|
+
finally:
|
|
14
|
+
os.close(fd)
|
|
15
|
+
except OSError:
|
|
16
|
+
os.write(2, data)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _bell() -> None:
|
|
20
|
+
global _last_bell_time
|
|
21
|
+
now = time.monotonic()
|
|
22
|
+
if now - _last_bell_time < _BELL_DEBOUNCE_S:
|
|
23
|
+
return
|
|
24
|
+
_last_bell_time = now
|
|
25
|
+
_raw_write(b"\a")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def notify(title: str, message: str) -> None:
|
|
29
|
+
del title, message
|
|
30
|
+
_bell()
|