kon-coding-agent 0.3.2__tar.gz → 0.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/AGENTS.md +2 -2
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/CHANGELOG.md +0 -1
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/PKG-INFO +11 -68
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/README.md +10 -67
- kon_coding_agent-0.3.4/docs/local-models.md +80 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/pyproject.toml +2 -1
- kon_coding_agent-0.3.4/src/kon/async_utils.py +40 -0
- kon_coding_agent-0.3.4/src/kon/builtin_skills/init/SKILL.md +73 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/config.py +35 -5
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/context/skills.py +62 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/core/types.py +1 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/defaults/config.toml +9 -1
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/events.py +0 -1
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/base.py +53 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/models.py +3 -3
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/oauth/openai.py +7 -2
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/providers/anthropic.py +9 -3
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/providers/openai_completions.py +31 -13
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/loop.py +10 -1
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/session.py +4 -4
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/tools/_tool_utils.py +21 -36
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/tools/bash.py +30 -25
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/tools/edit.py +1 -1
- kon_coding_agent-0.3.4/src/kon/tools/read.py +237 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/tools/web_fetch.py +1 -1
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/tools/web_search.py +1 -1
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/tools_manager.py +6 -14
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/turn.py +31 -20
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/app.py +87 -59
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/chat.py +2 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/commands.py +5 -9
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/input.py +19 -3
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/session_ui.py +4 -1
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/widgets.py +18 -14
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/conftest.py +0 -9
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/context/test_skills.py +59 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/llm/test_anthropic_provider.py +28 -0
- kon_coding_agent-0.3.4/tests/llm/test_openai_oauth.py +14 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_agentic_loop.py +52 -4
- kon_coding_agent-0.3.4/tests/test_cli_auth_flags.py +26 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_config_binaries.py +1 -3
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_config_migration.py +2 -0
- kon_coding_agent-0.3.4/tests/test_handoff_link_interrupt.py +74 -0
- kon_coding_agent-0.3.4/tests/test_local_auth_config.py +67 -0
- kon_coding_agent-0.3.4/tests/test_openai_compat.py +241 -0
- kon_coding_agent-0.3.4/tests/test_tools_manager.py +18 -0
- kon_coding_agent-0.3.4/tests/tools/test_read.py +180 -0
- kon_coding_agent-0.3.4/tests/tools/test_subprocess_cancellation.py +87 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/ui/test_input_paste.py +21 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/ui/test_status_line.py +0 -12
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/uv.lock +28 -1
- kon_coding_agent-0.3.2/docs/local-models.md +0 -28
- kon_coding_agent-0.3.2/src/kon/metrics.py +0 -37
- kon_coding_agent-0.3.2/src/kon/tools/read.py +0 -136
- kon_coding_agent-0.3.2/tests/test_metrics.py +0 -50
- kon_coding_agent-0.3.2/tests/test_openai_compat.py +0 -87
- kon_coding_agent-0.3.2/tests/tools/test_read.py +0 -80
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/.gitignore +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/.kon/skills/kon-release-publish/SKILL.md +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/.kon/skills/kon-tmux-test/SKILL.md +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/.kon/skills/kon-tmux-test/run-e2e-tests.sh +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/.kon/skills/kon-tmux-test/setup-test-project.sh +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/.python-version +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/LICENSE +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/docs/architecture-review.md +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/docs/images/kon-screenshot.png +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/scripts/show_themes.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/__init__.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/context/__init__.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/context/_xml.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/context/agent_mds.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/context/git.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/context/loader.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/core/__init__.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/core/compaction.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/core/handoff.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/defaults/__init__.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/__init__.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/oauth/__init__.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/oauth/copilot.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/providers/__init__.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/providers/azure_ai_foundry.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/providers/copilot.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/providers/copilot_anthropic.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/providers/github_copilot_headers.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/providers/mock.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/providers/openai_codex_responses.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/providers/openai_compat.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/providers/openai_responses.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/llm/providers/sanitize.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/permissions.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/py.typed +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/themes.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/tools/__init__.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/tools/_read_image.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/tools/base.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/tools/find.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/tools/grep.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/tools/write.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/__init__.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/app_protocol.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/autocomplete.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/blocks.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/clipboard.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/export.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/floating_list.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/formatting.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/path_complete.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/prompt_history.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/selection_mode.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/ui/styles.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/src/kon/update_check.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/context/test_agents.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/llm/__init__.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/llm/test_azure_ai_foundry_provider.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/llm/test_mock_provider.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/llm/test_openai_codex_provider_errors.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_cli_provider_resolution.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_compaction.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_config_error_fallback.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_config_injection.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_handoff.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_launch_warnings.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_model_provider_resolution.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_permissions.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_session_persistence.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_session_resume.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_system_prompt.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_system_prompt_git_context.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_update_check.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/test_update_notice_behavior.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/tools/test_diff.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/tools/test_edit.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/tools/test_edit_display.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/tools/test_read_image.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/tools/test_read_image_integration.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/tools/test_write.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/ui/test_autocomplete.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/ui/test_floating_list.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/ui/test_input_handoff.py +0 -0
- {kon_coding_agent-0.3.2 → kon_coding_agent-0.3.4}/tests/ui/test_prompt_history.py +0 -0
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
## Testing
|
|
9
9
|
|
|
10
|
-
- Use `uv run pytest` for testing in general; after edits/writes
|
|
10
|
+
- Use `uv run python -m pytest` for testing in general; after edits/writes
|
|
11
11
|
- If the user asks for e2e tests then run the kon-tmux e2e test if available
|
|
12
12
|
|
|
13
13
|
## Committing code
|
|
@@ -17,5 +17,5 @@
|
|
|
17
17
|
|
|
18
18
|
## Pushing
|
|
19
19
|
|
|
20
|
-
- If the user asks you to push code, run these first before doing so: `uv run ruff format .`, `uv run ruff check .`, `uv run pyright .` and `uv run pytest` in parallel (same tool call)
|
|
20
|
+
- If the user asks you to push code, run these first before doing so: `uv run ruff format .`, `uv run ruff check .`, `uv run python -m pyright .` and `uv run python -m pytest` in parallel (same tool call)
|
|
21
21
|
- Only if these all pass without issues should you push otherwise report the warnings/errors back to user and ask for next steps
|
|
@@ -30,7 +30,6 @@ All notable changes to this project will be documented in this file.
|
|
|
30
30
|
- Added tool permission controls with bash safety analysis - @Meltedd.
|
|
31
31
|
- Added popular built-in themes.
|
|
32
32
|
- Added tool previews in approval prompts.
|
|
33
|
-
- Added run token throughput metrics.
|
|
34
33
|
|
|
35
34
|
### Changed
|
|
36
35
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kon-coding-agent
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: Minimal coding agent
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Python: >=3.12
|
|
@@ -167,7 +167,7 @@ Here is the full config shape:
|
|
|
167
167
|
|
|
168
168
|
```toml
|
|
169
169
|
[meta]
|
|
170
|
-
config_version =
|
|
170
|
+
config_version = 4
|
|
171
171
|
|
|
172
172
|
[llm]
|
|
173
173
|
default_provider = "openai-codex"
|
|
@@ -176,6 +176,10 @@ default_base_url = ""
|
|
|
176
176
|
default_thinking_level = "high"
|
|
177
177
|
tool_call_idle_timeout_seconds = 180
|
|
178
178
|
|
|
179
|
+
[llm.auth]
|
|
180
|
+
openai_compat = "auto"
|
|
181
|
+
anthropic_compat = "auto"
|
|
182
|
+
|
|
179
183
|
[llm.system_prompt]
|
|
180
184
|
git_context = true
|
|
181
185
|
content = """You are an expert coding assistant called Kon.
|
|
@@ -248,8 +252,9 @@ Kon is built around a terminal UI that stays simple but practical.
|
|
|
248
252
|
| --- | --- |
|
|
249
253
|
| File reference | Type `@` to fuzzy-search files and folders in the current project |
|
|
250
254
|
| Path completion | Press **Tab** to complete paths like `./`, `../`, `~`, quoted paths, and absolute paths |
|
|
251
|
-
| Queued prompts |
|
|
252
|
-
|
|
|
255
|
+
| Queued prompts | Press **Enter** while the agent is running to queue a follow-up prompt |
|
|
256
|
+
| Steer queue | Press **Alt+Enter** to queue a steer message that is processed before normal queued prompts |
|
|
257
|
+
| Queue limit | Up to **5** normal queued prompts and **5** steer messages |
|
|
253
258
|
| Model switching | Use `/model` to switch interactively |
|
|
254
259
|
| Session browsing | Use `/resume` to browse prior sessions |
|
|
255
260
|
|
|
@@ -437,73 +442,12 @@ kon --provider openai --model some-model --api-key "$OPENAI_API_KEY"
|
|
|
437
442
|
|
|
438
443
|
### Local models
|
|
439
444
|
|
|
440
|
-
Kon works well with local models served through an OpenAI-compatible endpoint.
|
|
441
|
-
|
|
442
|
-
Example with `llama-server`:
|
|
443
|
-
|
|
444
|
-
```bash
|
|
445
|
-
./llama-server -m <models-dir>/GLM-4.7-Flash-GGUF/GLM-4.7-Flash-Q4_K_M.gguf \
|
|
446
|
-
-n 8192 \
|
|
447
|
-
-c 64000
|
|
448
|
-
|
|
449
|
-
kon --model zai-org/glm-4.7-flash \
|
|
450
|
-
--provider openai \
|
|
451
|
-
--base-url http://localhost:8080/v1 \
|
|
452
|
-
--api-key ""
|
|
453
|
-
```
|
|
445
|
+
Kon works well with local models served through an OpenAI-compatible endpoint. For one-off launches, you can force unauthenticated local behavior with `--openai-compat-auth none` or `--anthropic-compat-auth none`. To make that persistent across sessions, set `[llm.auth] openai_compat = "auto"|"none"` and/or `anthropic_compat = "auto"|"none"` in `~/.kon/config.toml`.
|
|
454
446
|
|
|
455
447
|
More notes, tested models, and examples live in [docs/local-models.md](docs/local-models.md).
|
|
456
448
|
|
|
457
449
|
---
|
|
458
450
|
|
|
459
|
-
### Configuration
|
|
460
|
-
|
|
461
|
-
Kon stores config at:
|
|
462
|
-
|
|
463
|
-
```text
|
|
464
|
-
~/.kon/config.toml
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
It is created automatically on first run, and old schemas are migrated forward automatically when needed.
|
|
468
|
-
|
|
469
|
-
Users are recommended to customize this config based on their model, workflow, safety preferences, and UI taste.
|
|
470
|
-
|
|
471
|
-
Here is the full config shape:
|
|
472
|
-
|
|
473
|
-
```toml
|
|
474
|
-
[meta]
|
|
475
|
-
config_version = 3
|
|
476
|
-
|
|
477
|
-
[llm]
|
|
478
|
-
default_provider = "openai-codex"
|
|
479
|
-
default_model = "gpt-5.4"
|
|
480
|
-
default_base_url = ""
|
|
481
|
-
default_thinking_level = "high"
|
|
482
|
-
tool_call_idle_timeout_seconds = 180
|
|
483
|
-
|
|
484
|
-
[llm.system_prompt]
|
|
485
|
-
git_context = true
|
|
486
|
-
content = """You are an expert coding assistant called Kon.
|
|
487
|
-
..."""
|
|
488
|
-
|
|
489
|
-
[compaction]
|
|
490
|
-
on_overflow = "continue"
|
|
491
|
-
buffer_tokens = 20000
|
|
492
|
-
|
|
493
|
-
[agent]
|
|
494
|
-
max_turns = 500
|
|
495
|
-
default_context_window = 200000
|
|
496
|
-
|
|
497
|
-
[tools]
|
|
498
|
-
extra = ["web_search", "web_fetch"]
|
|
499
|
-
|
|
500
|
-
[ui]
|
|
501
|
-
theme = "gruvbox-dark"
|
|
502
|
-
|
|
503
|
-
[permissions]
|
|
504
|
-
mode = "prompt"
|
|
505
|
-
```
|
|
506
|
-
|
|
507
451
|
### Permissions
|
|
508
452
|
|
|
509
453
|
Kon supports two permission modes:
|
|
@@ -526,9 +470,8 @@ Kon depends on a few fast CLI tools for file discovery and search:
|
|
|
526
470
|
|
|
527
471
|
- **[`fd`](https://github.com/sharkdp/fd)** - required for fast file discovery
|
|
528
472
|
- **[`ripgrep`](https://github.com/BurntSushi/ripgrep)** - required for fast content search
|
|
529
|
-
- **[`eza`](https://github.com/eza-community/eza)** - optional
|
|
530
473
|
|
|
531
|
-
If `fd` or `rg` are missing, Kon can download them automatically.
|
|
474
|
+
If `fd` or `rg` are missing, Kon can download them automatically.
|
|
532
475
|
|
|
533
476
|
---
|
|
534
477
|
|
|
@@ -149,7 +149,7 @@ Here is the full config shape:
|
|
|
149
149
|
|
|
150
150
|
```toml
|
|
151
151
|
[meta]
|
|
152
|
-
config_version =
|
|
152
|
+
config_version = 4
|
|
153
153
|
|
|
154
154
|
[llm]
|
|
155
155
|
default_provider = "openai-codex"
|
|
@@ -158,6 +158,10 @@ default_base_url = ""
|
|
|
158
158
|
default_thinking_level = "high"
|
|
159
159
|
tool_call_idle_timeout_seconds = 180
|
|
160
160
|
|
|
161
|
+
[llm.auth]
|
|
162
|
+
openai_compat = "auto"
|
|
163
|
+
anthropic_compat = "auto"
|
|
164
|
+
|
|
161
165
|
[llm.system_prompt]
|
|
162
166
|
git_context = true
|
|
163
167
|
content = """You are an expert coding assistant called Kon.
|
|
@@ -230,8 +234,9 @@ Kon is built around a terminal UI that stays simple but practical.
|
|
|
230
234
|
| --- | --- |
|
|
231
235
|
| File reference | Type `@` to fuzzy-search files and folders in the current project |
|
|
232
236
|
| Path completion | Press **Tab** to complete paths like `./`, `../`, `~`, quoted paths, and absolute paths |
|
|
233
|
-
| Queued prompts |
|
|
234
|
-
|
|
|
237
|
+
| Queued prompts | Press **Enter** while the agent is running to queue a follow-up prompt |
|
|
238
|
+
| Steer queue | Press **Alt+Enter** to queue a steer message that is processed before normal queued prompts |
|
|
239
|
+
| Queue limit | Up to **5** normal queued prompts and **5** steer messages |
|
|
235
240
|
| Model switching | Use `/model` to switch interactively |
|
|
236
241
|
| Session browsing | Use `/resume` to browse prior sessions |
|
|
237
242
|
|
|
@@ -419,73 +424,12 @@ kon --provider openai --model some-model --api-key "$OPENAI_API_KEY"
|
|
|
419
424
|
|
|
420
425
|
### Local models
|
|
421
426
|
|
|
422
|
-
Kon works well with local models served through an OpenAI-compatible endpoint.
|
|
423
|
-
|
|
424
|
-
Example with `llama-server`:
|
|
425
|
-
|
|
426
|
-
```bash
|
|
427
|
-
./llama-server -m <models-dir>/GLM-4.7-Flash-GGUF/GLM-4.7-Flash-Q4_K_M.gguf \
|
|
428
|
-
-n 8192 \
|
|
429
|
-
-c 64000
|
|
430
|
-
|
|
431
|
-
kon --model zai-org/glm-4.7-flash \
|
|
432
|
-
--provider openai \
|
|
433
|
-
--base-url http://localhost:8080/v1 \
|
|
434
|
-
--api-key ""
|
|
435
|
-
```
|
|
427
|
+
Kon works well with local models served through an OpenAI-compatible endpoint. For one-off launches, you can force unauthenticated local behavior with `--openai-compat-auth none` or `--anthropic-compat-auth none`. To make that persistent across sessions, set `[llm.auth] openai_compat = "auto"|"none"` and/or `anthropic_compat = "auto"|"none"` in `~/.kon/config.toml`.
|
|
436
428
|
|
|
437
429
|
More notes, tested models, and examples live in [docs/local-models.md](docs/local-models.md).
|
|
438
430
|
|
|
439
431
|
---
|
|
440
432
|
|
|
441
|
-
### Configuration
|
|
442
|
-
|
|
443
|
-
Kon stores config at:
|
|
444
|
-
|
|
445
|
-
```text
|
|
446
|
-
~/.kon/config.toml
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
It is created automatically on first run, and old schemas are migrated forward automatically when needed.
|
|
450
|
-
|
|
451
|
-
Users are recommended to customize this config based on their model, workflow, safety preferences, and UI taste.
|
|
452
|
-
|
|
453
|
-
Here is the full config shape:
|
|
454
|
-
|
|
455
|
-
```toml
|
|
456
|
-
[meta]
|
|
457
|
-
config_version = 3
|
|
458
|
-
|
|
459
|
-
[llm]
|
|
460
|
-
default_provider = "openai-codex"
|
|
461
|
-
default_model = "gpt-5.4"
|
|
462
|
-
default_base_url = ""
|
|
463
|
-
default_thinking_level = "high"
|
|
464
|
-
tool_call_idle_timeout_seconds = 180
|
|
465
|
-
|
|
466
|
-
[llm.system_prompt]
|
|
467
|
-
git_context = true
|
|
468
|
-
content = """You are an expert coding assistant called Kon.
|
|
469
|
-
..."""
|
|
470
|
-
|
|
471
|
-
[compaction]
|
|
472
|
-
on_overflow = "continue"
|
|
473
|
-
buffer_tokens = 20000
|
|
474
|
-
|
|
475
|
-
[agent]
|
|
476
|
-
max_turns = 500
|
|
477
|
-
default_context_window = 200000
|
|
478
|
-
|
|
479
|
-
[tools]
|
|
480
|
-
extra = ["web_search", "web_fetch"]
|
|
481
|
-
|
|
482
|
-
[ui]
|
|
483
|
-
theme = "gruvbox-dark"
|
|
484
|
-
|
|
485
|
-
[permissions]
|
|
486
|
-
mode = "prompt"
|
|
487
|
-
```
|
|
488
|
-
|
|
489
433
|
### Permissions
|
|
490
434
|
|
|
491
435
|
Kon supports two permission modes:
|
|
@@ -508,9 +452,8 @@ Kon depends on a few fast CLI tools for file discovery and search:
|
|
|
508
452
|
|
|
509
453
|
- **[`fd`](https://github.com/sharkdp/fd)** - required for fast file discovery
|
|
510
454
|
- **[`ripgrep`](https://github.com/BurntSushi/ripgrep)** - required for fast content search
|
|
511
|
-
- **[`eza`](https://github.com/eza-community/eza)** - optional
|
|
512
455
|
|
|
513
|
-
If `fd` or `rg` are missing, Kon can download them automatically.
|
|
456
|
+
If `fd` or `rg` are missing, Kon can download them automatically.
|
|
514
457
|
|
|
515
458
|
---
|
|
516
459
|
|
|
@@ -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
|
+
```
|
|
@@ -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.4"
|
|
18
18
|
description = "Minimal coding agent"
|
|
19
19
|
readme = "README.md"
|
|
20
20
|
requires-python = ">=3.12"
|
|
@@ -36,6 +36,7 @@ dev = [
|
|
|
36
36
|
"pyright>=1.1.408",
|
|
37
37
|
"pytest>=9.0.2",
|
|
38
38
|
"pytest-asyncio>=1.3.0",
|
|
39
|
+
"ruff>=0.15.8",
|
|
39
40
|
"twine>=5.1.1",
|
|
40
41
|
]
|
|
41
42
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from contextlib import suppress
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class OperationCancelledError(Exception):
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
async def cancel_and_await(task: asyncio.Future[Any]) -> None:
|
|
11
|
+
if task.done():
|
|
12
|
+
return
|
|
13
|
+
task.cancel()
|
|
14
|
+
with suppress(asyncio.CancelledError):
|
|
15
|
+
await task
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
async def await_or_cancel[T](work: asyncio.Future[T], cancel_event: asyncio.Event | None) -> T:
|
|
19
|
+
if not cancel_event:
|
|
20
|
+
return await work
|
|
21
|
+
|
|
22
|
+
if cancel_event.is_set():
|
|
23
|
+
await cancel_and_await(work)
|
|
24
|
+
raise OperationCancelledError
|
|
25
|
+
|
|
26
|
+
cancel = asyncio.create_task(cancel_event.wait())
|
|
27
|
+
try:
|
|
28
|
+
done, pending = await asyncio.wait({work, cancel}, return_when=asyncio.FIRST_COMPLETED)
|
|
29
|
+
|
|
30
|
+
for task in pending:
|
|
31
|
+
await cancel_and_await(task)
|
|
32
|
+
|
|
33
|
+
if cancel in done and cancel_event.is_set():
|
|
34
|
+
if not work.done():
|
|
35
|
+
await cancel_and_await(work)
|
|
36
|
+
raise OperationCancelledError
|
|
37
|
+
|
|
38
|
+
return work.result()
|
|
39
|
+
finally:
|
|
40
|
+
await cancel_and_await(cancel)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: init
|
|
3
|
+
description: Create or update AGENTS.md for this repository
|
|
4
|
+
register_cmd: true
|
|
5
|
+
cmd_info: Guided AGENTS.md setup
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Create or update `AGENTS.md` for this repository.
|
|
9
|
+
|
|
10
|
+
The goal is a compact instruction file that helps future Kon sessions avoid mistakes and ramp up quickly. Every line should answer: "Would an agent likely miss this without help?" If not, leave it out.
|
|
11
|
+
|
|
12
|
+
User-provided focus or constraints (honor these):
|
|
13
|
+
$ARGUMENTS
|
|
14
|
+
|
|
15
|
+
## How to investigate
|
|
16
|
+
|
|
17
|
+
Read the highest-value sources first:
|
|
18
|
+
- `README*`, root manifests, workspace config, lockfiles
|
|
19
|
+
- build, test, lint, formatter, typecheck, and codegen config
|
|
20
|
+
- CI workflows and pre-commit / task runner config
|
|
21
|
+
- existing instruction files (`AGENTS.md`, `CLAUDE.md`, `.cursor/rules/`, `.cursorrules`, `.github/copilot-instructions.md`)
|
|
22
|
+
- repo-local Kon config and conventions
|
|
23
|
+
|
|
24
|
+
If architecture is still unclear after reading config and docs, inspect a small number of representative code files to find the real entrypoints, package boundaries, and execution flow. Prefer reading the files that explain how the system is wired together over random leaf files.
|
|
25
|
+
|
|
26
|
+
Prefer executable sources of truth over prose. If docs conflict with config or scripts, trust the executable source and only keep what you can verify.
|
|
27
|
+
|
|
28
|
+
## What to extract
|
|
29
|
+
|
|
30
|
+
Look for the highest-signal facts for an agent working in this repo:
|
|
31
|
+
- exact developer commands, especially non-obvious ones
|
|
32
|
+
- how to run a single test, a single package, or a focused verification step
|
|
33
|
+
- required command order when it matters, such as `lint -> typecheck -> test`
|
|
34
|
+
- monorepo or multi-package boundaries, ownership of major directories, and the real app/library entrypoints
|
|
35
|
+
- framework or toolchain quirks: generated code, migrations, codegen, build artifacts, special env loading, dev servers, infra deploy flow
|
|
36
|
+
- repo-specific style or workflow conventions that differ from defaults
|
|
37
|
+
- testing quirks: fixtures, integration test prerequisites, snapshot workflows, required services, flaky or expensive suites
|
|
38
|
+
- important constraints from existing instruction files worth preserving
|
|
39
|
+
|
|
40
|
+
Good `AGENTS.md` content is usually hard-earned context that took reading multiple files to infer.
|
|
41
|
+
|
|
42
|
+
## Questions
|
|
43
|
+
|
|
44
|
+
Only ask the user questions if the repo cannot answer something important. Use the question tool for one short batch at most.
|
|
45
|
+
|
|
46
|
+
Good questions:
|
|
47
|
+
- undocumented team conventions
|
|
48
|
+
- branch / PR / release expectations
|
|
49
|
+
- missing setup or test prerequisites that are known but not written down
|
|
50
|
+
|
|
51
|
+
Do not ask about anything the repo already makes clear.
|
|
52
|
+
|
|
53
|
+
## Writing rules
|
|
54
|
+
|
|
55
|
+
Include only high-signal, repo-specific guidance such as:
|
|
56
|
+
- exact commands and shortcuts the agent would otherwise guess wrong
|
|
57
|
+
- architecture notes that are not obvious from filenames
|
|
58
|
+
- conventions that differ from language or framework defaults
|
|
59
|
+
- setup requirements, environment quirks, and operational gotchas
|
|
60
|
+
- references to existing instruction sources that matter
|
|
61
|
+
|
|
62
|
+
Exclude:
|
|
63
|
+
- generic software advice
|
|
64
|
+
- long tutorials or exhaustive file trees
|
|
65
|
+
- obvious language conventions
|
|
66
|
+
- speculative claims or anything you could not verify
|
|
67
|
+
- content better stored in another file referenced via Kon config or another instruction file
|
|
68
|
+
|
|
69
|
+
When in doubt, omit.
|
|
70
|
+
|
|
71
|
+
Prefer short sections and bullets. If the repo is simple, keep the file simple. If the repo is large, summarize the few structural facts that actually change how an agent should work.
|
|
72
|
+
|
|
73
|
+
If `AGENTS.md` already exists, improve it in place rather than rewriting blindly. Preserve verified useful guidance, delete fluff or stale claims, and reconcile it with the current codebase.
|
|
@@ -18,6 +18,7 @@ from .themes import ColorsConfig, get_theme, get_theme_ids
|
|
|
18
18
|
CONFIG_DIR_NAME: str = ".kon"
|
|
19
19
|
|
|
20
20
|
OnOverflowMode = Literal["continue", "pause"]
|
|
21
|
+
AuthMode = Literal["auto", "required", "none"]
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
# =================================================================================================
|
|
@@ -63,6 +64,11 @@ class SystemPromptConfig(BaseModel):
|
|
|
63
64
|
git_context: bool = False
|
|
64
65
|
|
|
65
66
|
|
|
67
|
+
class AuthConfig(BaseModel):
|
|
68
|
+
openai_compat: AuthMode = "auto"
|
|
69
|
+
anthropic_compat: AuthMode = "auto"
|
|
70
|
+
|
|
71
|
+
|
|
66
72
|
class LLMConfig(BaseModel):
|
|
67
73
|
default_provider: str
|
|
68
74
|
default_model: str
|
|
@@ -70,6 +76,7 @@ class LLMConfig(BaseModel):
|
|
|
70
76
|
default_thinking_level: str
|
|
71
77
|
system_prompt: SystemPromptConfig
|
|
72
78
|
tool_call_idle_timeout_seconds: float = 180
|
|
79
|
+
auth: AuthConfig = AuthConfig()
|
|
73
80
|
|
|
74
81
|
|
|
75
82
|
class CompactionConfig(BaseModel):
|
|
@@ -120,10 +127,6 @@ class _BinariesConfig:
|
|
|
120
127
|
def fd(self) -> bool:
|
|
121
128
|
return "fd" in self._binaries
|
|
122
129
|
|
|
123
|
-
@property
|
|
124
|
-
def eza(self) -> bool:
|
|
125
|
-
return "eza" in self._binaries
|
|
126
|
-
|
|
127
130
|
|
|
128
131
|
class Config:
|
|
129
132
|
def __init__(self, data: dict[str, Any]) -> None:
|
|
@@ -227,7 +230,7 @@ def consume_config_warnings() -> list[str]:
|
|
|
227
230
|
|
|
228
231
|
|
|
229
232
|
def _detect_available_binaries() -> set[str]:
|
|
230
|
-
binaries = {"rg", "fd"
|
|
233
|
+
binaries = {"rg", "fd"}
|
|
231
234
|
available = set()
|
|
232
235
|
bin_dir = Path.home() / CONFIG_DIR_NAME / "bin"
|
|
233
236
|
|
|
@@ -286,6 +289,29 @@ def _migrate_v2_to_v3(data: dict[str, Any]) -> dict[str, Any]:
|
|
|
286
289
|
return migrated
|
|
287
290
|
|
|
288
291
|
|
|
292
|
+
def _migrate_v3_to_v4(data: dict[str, Any]) -> dict[str, Any]:
|
|
293
|
+
migrated = Config._apply_legacy_key_shims(data)
|
|
294
|
+
llm = migrated.get("llm")
|
|
295
|
+
if not isinstance(llm, dict):
|
|
296
|
+
llm = {}
|
|
297
|
+
migrated["llm"] = llm
|
|
298
|
+
|
|
299
|
+
auth = llm.get("auth")
|
|
300
|
+
if not isinstance(auth, dict):
|
|
301
|
+
auth = {}
|
|
302
|
+
llm["auth"] = auth
|
|
303
|
+
|
|
304
|
+
auth.setdefault("openai_compat", "auto")
|
|
305
|
+
auth.setdefault("anthropic_compat", "auto")
|
|
306
|
+
|
|
307
|
+
meta = migrated.get("meta")
|
|
308
|
+
if not isinstance(meta, dict):
|
|
309
|
+
migrated["meta"] = {"config_version": 4}
|
|
310
|
+
else:
|
|
311
|
+
meta["config_version"] = 4
|
|
312
|
+
return migrated
|
|
313
|
+
|
|
314
|
+
|
|
289
315
|
def _migrate_config_data(data: dict[str, Any]) -> tuple[dict[str, Any], int, int, bool]:
|
|
290
316
|
original = deepcopy(data)
|
|
291
317
|
current_version = _get_config_version(original)
|
|
@@ -304,6 +330,10 @@ def _migrate_config_data(data: dict[str, Any]) -> tuple[dict[str, Any], int, int
|
|
|
304
330
|
migrated = _migrate_v2_to_v3(migrated)
|
|
305
331
|
current_version = 3
|
|
306
332
|
continue
|
|
333
|
+
if current_version == 3:
|
|
334
|
+
migrated = _migrate_v3_to_v4(migrated)
|
|
335
|
+
current_version = 4
|
|
336
|
+
continue
|
|
307
337
|
break
|
|
308
338
|
|
|
309
339
|
migrated_version = _get_config_version(migrated)
|
|
@@ -12,6 +12,7 @@ Discovery locations:
|
|
|
12
12
|
import os
|
|
13
13
|
import re
|
|
14
14
|
from dataclasses import dataclass
|
|
15
|
+
from importlib import resources
|
|
15
16
|
from pathlib import Path
|
|
16
17
|
from typing import Any
|
|
17
18
|
|
|
@@ -47,6 +48,7 @@ class Skill:
|
|
|
47
48
|
description: str
|
|
48
49
|
register_cmd: bool = False
|
|
49
50
|
cmd_info: str = ""
|
|
51
|
+
bundled: bool = False
|
|
50
52
|
|
|
51
53
|
|
|
52
54
|
@dataclass
|
|
@@ -228,6 +230,66 @@ def load_skills(cwd: str | None = None) -> LoadSkillsResult:
|
|
|
228
230
|
return LoadSkillsResult(skills=list(skill_map.values()), warnings=all_warnings)
|
|
229
231
|
|
|
230
232
|
|
|
233
|
+
def load_builtin_cmd_skills() -> LoadSkillsResult:
|
|
234
|
+
try:
|
|
235
|
+
builtin_resource = resources.files("kon").joinpath("builtin_skills")
|
|
236
|
+
with resources.as_file(builtin_resource) as builtin_root:
|
|
237
|
+
result = _load_skills_from_dir(builtin_root)
|
|
238
|
+
except Exception:
|
|
239
|
+
return LoadSkillsResult(skills=[], warnings=[])
|
|
240
|
+
return LoadSkillsResult(
|
|
241
|
+
skills=[
|
|
242
|
+
Skill(
|
|
243
|
+
path=skill.path,
|
|
244
|
+
name=skill.name,
|
|
245
|
+
description=skill.description,
|
|
246
|
+
register_cmd=skill.register_cmd,
|
|
247
|
+
cmd_info=skill.cmd_info,
|
|
248
|
+
bundled=True,
|
|
249
|
+
)
|
|
250
|
+
for skill in result.skills
|
|
251
|
+
],
|
|
252
|
+
warnings=result.warnings,
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def strip_frontmatter(content: str) -> str:
|
|
257
|
+
if not content.startswith("---"):
|
|
258
|
+
return content.strip()
|
|
259
|
+
end_match = re.search(r"\n---\s*\n", content[3:])
|
|
260
|
+
if not end_match:
|
|
261
|
+
return content.strip()
|
|
262
|
+
return content[end_match.end() + 3 :].strip()
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def render_skill_prompt(skill: Skill, query: str) -> str:
|
|
266
|
+
try:
|
|
267
|
+
content = Path(skill.path).read_text(encoding="utf-8")
|
|
268
|
+
except Exception:
|
|
269
|
+
return _build_fallback_skill_prompt(skill.description, query)
|
|
270
|
+
template = strip_frontmatter(content)
|
|
271
|
+
rendered = template.replace("$ARGUMENTS", query)
|
|
272
|
+
return rendered.strip()
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def _build_fallback_skill_prompt(description: str, query: str) -> str:
|
|
276
|
+
query = query.strip()
|
|
277
|
+
if not query:
|
|
278
|
+
return description
|
|
279
|
+
return f"{description}\n\n{query}"
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def merge_registered_skills(primary: list[Skill], secondary: list[Skill]) -> list[Skill]:
|
|
283
|
+
seen = {skill.name for skill in primary}
|
|
284
|
+
merged = list(primary)
|
|
285
|
+
for skill in secondary:
|
|
286
|
+
if skill.name in seen:
|
|
287
|
+
continue
|
|
288
|
+
merged.append(skill)
|
|
289
|
+
seen.add(skill.name)
|
|
290
|
+
return merged
|
|
291
|
+
|
|
292
|
+
|
|
231
293
|
def formatted_skills(skills: list[Skill]) -> str:
|
|
232
294
|
if not skills:
|
|
233
295
|
return ""
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[meta]
|
|
2
|
-
config_version =
|
|
2
|
+
config_version = 4
|
|
3
3
|
|
|
4
4
|
[llm]
|
|
5
5
|
default_provider = "openai-codex" # "zhipu", "github-copilot", "openai-codex"
|
|
@@ -12,6 +12,14 @@ default_thinking_level = "high"
|
|
|
12
12
|
# Helps prevent stalled tool executions from hanging the agent loop.
|
|
13
13
|
tool_call_idle_timeout_seconds = 180
|
|
14
14
|
|
|
15
|
+
[llm.auth]
|
|
16
|
+
# Auth policy for OpenAI-compatible and Anthropic-compatible endpoints.
|
|
17
|
+
# "auto" injects a placeholder key for local/self-hosted endpoints when no key is set.
|
|
18
|
+
# "required" keeps strict API key requirements.
|
|
19
|
+
# "none" always injects a placeholder key for that protocol family.
|
|
20
|
+
openai_compat = "auto" # "auto", "required", or "none"
|
|
21
|
+
anthropic_compat = "auto" # "auto", "required", or "none"
|
|
22
|
+
|
|
15
23
|
[llm.system_prompt]
|
|
16
24
|
git_context = true
|
|
17
25
|
content = """You are an expert coding assistant called Kon. You help users by reading, searching, executing commands, editing code, and writing new files.
|
|
@@ -41,7 +41,6 @@ class TurnEndEvent:
|
|
|
41
41
|
assistant_message: AssistantMessage | None = None
|
|
42
42
|
tool_results: list[ToolResultMessage] = field(default_factory=list)
|
|
43
43
|
stop_reason: StopReason = StopReason.STOP
|
|
44
|
-
generation_seconds: float | None = None
|
|
45
44
|
tool_call_count: int = 0
|
|
46
45
|
|
|
47
46
|
|