kward 0.67.1 → 0.69.0
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.
- checksums.yaml +4 -4
- data/.github/workflows/pages.yml +48 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +54 -0
- data/Gemfile.lock +8 -2
- data/README.md +37 -30
- data/Rakefile +14 -1
- data/doc/authentication.md +84 -43
- data/doc/code-search.md +55 -28
- data/doc/configuration.md +27 -2
- data/doc/extensibility.md +90 -129
- data/doc/getting-started.md +53 -57
- data/doc/memory.md +51 -118
- data/doc/personas.md +417 -0
- data/doc/plugins.md +55 -99
- data/doc/releasing.md +10 -9
- data/doc/rpc.md +7 -7
- data/doc/usage.md +125 -141
- data/doc/web-search.md +80 -14
- data/exe/kward +2 -0
- data/kward.gemspec +4 -0
- data/lib/kward/agent.rb +30 -3
- data/lib/kward/ansi.rb +3 -0
- data/lib/kward/auth/anthropic_oauth.rb +291 -0
- data/lib/kward/auth/file.rb +2 -0
- data/lib/kward/auth/github_oauth.rb +3 -0
- data/lib/kward/auth/openai_oauth.rb +4 -0
- data/lib/kward/auth/openrouter_api_key.rb +2 -0
- data/lib/kward/cancellation.rb +3 -0
- data/lib/kward/cli/auth_commands.rb +82 -0
- data/lib/kward/cli/commands.rb +229 -0
- data/lib/kward/cli/compaction.rb +25 -0
- data/lib/kward/cli/doctor.rb +121 -0
- data/lib/kward/cli/interactive_turn.rb +227 -0
- data/lib/kward/cli/memory_commands.rb +133 -0
- data/lib/kward/cli/plugins.rb +112 -0
- data/lib/kward/cli/prompt_interface.rb +134 -0
- data/lib/kward/cli/rendering.rb +378 -0
- data/lib/kward/cli/runtime_helpers.rb +170 -0
- data/lib/kward/cli/sessions.rb +376 -0
- data/lib/kward/cli/settings.rb +669 -0
- data/lib/kward/cli/slash_commands.rb +114 -0
- data/lib/kward/cli/stats.rb +64 -0
- data/lib/kward/cli/sysprompt.rb +57 -0
- data/lib/kward/cli/tool_summaries.rb +157 -0
- data/lib/kward/cli.rb +52 -2792
- data/lib/kward/cli_transcript_formatter.rb +40 -12
- data/lib/kward/clipboard.rb +1 -0
- data/lib/kward/compaction/file_operation_tracker.rb +3 -0
- data/lib/kward/compactor.rb +31 -9
- data/lib/kward/config_files.rb +78 -34
- data/lib/kward/conversation.rb +110 -13
- data/lib/kward/events.rb +2 -0
- data/lib/kward/export_path.rb +2 -0
- data/lib/kward/image_attachments.rb +2 -0
- data/lib/kward/markdown_transcript.rb +2 -0
- data/lib/kward/memory/manager.rb +144 -14
- data/lib/kward/message_access.rb +29 -2
- data/lib/kward/message_text.rb +45 -0
- data/lib/kward/model/chat_invocation.rb +2 -0
- data/lib/kward/model/client.rb +295 -77
- data/lib/kward/model/context_overflow.rb +2 -0
- data/lib/kward/model/context_usage.rb +14 -10
- data/lib/kward/model/model_info.rb +160 -4
- data/lib/kward/model/payloads.rb +254 -22
- data/lib/kward/model/retry_message.rb +2 -0
- data/lib/kward/model/stream_parser.rb +387 -25
- data/lib/kward/pan/server.rb +3 -1
- data/lib/kward/plugin_registry.rb +12 -0
- data/lib/kward/private_file.rb +2 -0
- data/lib/kward/prompt_interface/banner.rb +3 -0
- data/lib/kward/prompt_interface/composer_controller.rb +262 -0
- data/lib/kward/prompt_interface/composer_renderer.rb +172 -0
- data/lib/kward/prompt_interface/composer_state.rb +221 -0
- data/lib/kward/prompt_interface/key_handler.rb +365 -0
- data/lib/kward/prompt_interface/layout.rb +31 -0
- data/lib/kward/prompt_interface/overlay_renderer.rb +111 -0
- data/lib/kward/prompt_interface/prompt_renderer.rb +91 -0
- data/lib/kward/prompt_interface/question_prompt.rb +328 -0
- data/lib/kward/prompt_interface/runtime_state.rb +59 -0
- data/lib/kward/prompt_interface/screen.rb +186 -0
- data/lib/kward/prompt_interface/selection_prompt.rb +242 -0
- data/lib/kward/prompt_interface/slash_overlay.rb +102 -0
- data/lib/kward/prompt_interface/stream_state.rb +65 -0
- data/lib/kward/prompt_interface/transcript_buffer.rb +85 -0
- data/lib/kward/prompt_interface/transcript_renderer.rb +151 -0
- data/lib/kward/prompt_interface.rb +69 -1832
- data/lib/kward/prompts/commands.rb +2 -0
- data/lib/kward/prompts/templates.rb +3 -0
- data/lib/kward/prompts.rb +63 -7
- data/lib/kward/question_contract.rb +66 -0
- data/lib/kward/resources/avatar_kward_logo.rb +2 -0
- data/lib/kward/resources/pixel_logo.rb +2 -0
- data/lib/kward/rpc/attachment_normalizer.rb +60 -0
- data/lib/kward/rpc/auth_manager.rb +65 -11
- data/lib/kward/rpc/config_manager.rb +11 -0
- data/lib/kward/rpc/prompt_bridge.rb +5 -26
- data/lib/kward/rpc/redactor.rb +3 -0
- data/lib/kward/rpc/runtime_payloads.rb +4 -1
- data/lib/kward/rpc/server.rb +43 -11
- data/lib/kward/rpc/session_manager.rb +139 -347
- data/lib/kward/rpc/session_metrics.rb +68 -0
- data/lib/kward/rpc/session_tree.rb +48 -0
- data/lib/kward/rpc/session_tree_rows.rb +208 -0
- data/lib/kward/rpc/tool_event_normalizer.rb +3 -0
- data/lib/kward/rpc/tool_metadata.rb +3 -0
- data/lib/kward/rpc/transcript_normalizer.rb +50 -0
- data/lib/kward/rpc/transport.rb +3 -0
- data/lib/kward/session_diff.rb +2 -0
- data/lib/kward/session_store.rb +154 -25
- data/lib/kward/session_trash.rb +1 -0
- data/lib/kward/session_tree_renderer.rb +8 -41
- data/lib/kward/session_tree_tool_display.rb +56 -0
- data/lib/kward/skills/registry.rb +3 -0
- data/lib/kward/starter_pack_installer.rb +3 -2
- data/lib/kward/steering.rb +2 -0
- data/lib/kward/telemetry/logger.rb +3 -0
- data/lib/kward/telemetry/stats.rb +3 -0
- data/lib/kward/tools/ask_user_question.rb +20 -32
- data/lib/kward/tools/base.rb +8 -0
- data/lib/kward/tools/code_search.rb +5 -0
- data/lib/kward/tools/edit_file.rb +5 -0
- data/lib/kward/tools/fetch_content.rb +41 -0
- data/lib/kward/tools/fetch_raw.rb +40 -0
- data/lib/kward/tools/list_directory.rb +5 -0
- data/lib/kward/tools/read_file.rb +5 -0
- data/lib/kward/tools/read_skill.rb +5 -0
- data/lib/kward/tools/registry.rb +42 -4
- data/lib/kward/tools/run_shell_command.rb +5 -0
- data/lib/kward/tools/search/code.rb +7 -0
- data/lib/kward/tools/search/web.rb +20 -17
- data/lib/kward/tools/search/web_fetch.rb +202 -0
- data/lib/kward/tools/tool_call.rb +27 -5
- data/lib/kward/tools/web_search.rb +7 -1
- data/lib/kward/tools/write_file.rb +5 -0
- data/lib/kward/transcript_export.rb +2 -0
- data/lib/kward/version.rb +2 -1
- data/lib/kward/workspace.rb +45 -5
- data/templates/default/fulldoc/html/css/kward.css +1501 -0
- data/templates/default/fulldoc/html/images/kward_logo.png +0 -0
- data/templates/default/fulldoc/html/js/kward.js +296 -0
- data/templates/default/fulldoc/html/setup.rb +8 -0
- data/templates/default/layout/html/breadcrumb.erb +11 -0
- data/templates/default/layout/html/layout.erb +141 -0
- data/templates/default/layout/html/setup.rb +139 -0
- metadata +56 -1
data/doc/usage.md
CHANGED
|
@@ -1,214 +1,198 @@
|
|
|
1
1
|
# Usage
|
|
2
2
|
|
|
3
|
-
Kward
|
|
3
|
+
Kward has two main modes:
|
|
4
|
+
|
|
5
|
+
- **Interactive chat** for ongoing work in a project.
|
|
6
|
+
- **One-shot prompts** for quick questions, reviews, and summaries.
|
|
7
|
+
|
|
8
|
+
Run Kward from the workspace you want it to inspect:
|
|
4
9
|
|
|
5
10
|
```bash
|
|
6
|
-
|
|
7
|
-
kward
|
|
8
|
-
kward "Explain this project" # one-shot prompt
|
|
9
|
-
kward init # optional first-time setup
|
|
10
|
-
kward doctor # check local setup
|
|
11
|
-
kward auth status # show saved credential status
|
|
12
|
-
kward pan # Pan mode web UI
|
|
13
|
-
kward rpc # experimental JSON-RPC backend
|
|
11
|
+
cd ~/code/project
|
|
12
|
+
kward
|
|
14
13
|
```
|
|
15
14
|
|
|
16
15
|
When running from source, replace `kward` with `ruby lib/main.rb`.
|
|
17
16
|
|
|
18
|
-
##
|
|
17
|
+
## Common workflows
|
|
19
18
|
|
|
20
|
-
|
|
19
|
+
### Understand a new project
|
|
21
20
|
|
|
22
|
-
```
|
|
23
|
-
|
|
21
|
+
```text
|
|
22
|
+
Explain the project structure and point out the main entry points.
|
|
24
23
|
```
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
Useful follow-ups:
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
```text
|
|
28
|
+
Where is configuration loaded?
|
|
29
|
+
Which files would I read first to understand authentication?
|
|
30
|
+
Summarize the test strategy.
|
|
31
|
+
```
|
|
29
32
|
|
|
30
|
-
|
|
33
|
+
### Review changes before committing
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
```bash
|
|
36
|
+
git diff | kward "Review this diff for bugs, missing tests, and confusing naming"
|
|
37
|
+
```
|
|
33
38
|
|
|
34
|
-
|
|
39
|
+
For larger reviews, use interactive mode so Kward can inspect related files:
|
|
35
40
|
|
|
36
41
|
```text
|
|
37
|
-
|
|
42
|
+
Review the current git diff. If something looks risky, inspect the relevant files before recommending changes.
|
|
38
43
|
```
|
|
39
44
|
|
|
40
|
-
|
|
45
|
+
### Make a small code change
|
|
41
46
|
|
|
42
|
-
|
|
47
|
+
```text
|
|
48
|
+
Add a --json option to the status command. Keep the text output unchanged and add focused tests.
|
|
49
|
+
```
|
|
43
50
|
|
|
44
|
-
|
|
51
|
+
Kward must read an existing file in the current conversation before editing it. This guardrail helps prevent accidental overwrites.
|
|
45
52
|
|
|
46
|
-
|
|
53
|
+
### Run local checks
|
|
47
54
|
|
|
48
|
-
|
|
49
|
-
kward --working-directory ~/code/project
|
|
50
|
-
kward --working-directory ~/code/project "Summarize this project"
|
|
51
|
-
kward --working-directory ~/code/project pan
|
|
52
|
-
kward --working-directory ~/code/project rpc
|
|
53
|
-
```
|
|
55
|
+
Inside interactive mode, ask Kward to run a command:
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
```text
|
|
58
|
+
Run the focused test for the CLI status command.
|
|
59
|
+
```
|
|
56
60
|
|
|
57
|
-
|
|
61
|
+
Or run a shell command yourself from the composer by prefixing it with `!`:
|
|
58
62
|
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
kward Summarize the changes in this repository
|
|
63
|
+
```text
|
|
64
|
+
!git status --short
|
|
62
65
|
```
|
|
63
66
|
|
|
64
|
-
|
|
67
|
+
## Shell commands
|
|
68
|
+
|
|
69
|
+
Useful shell commands:
|
|
65
70
|
|
|
66
71
|
```bash
|
|
67
|
-
kward
|
|
68
|
-
kward
|
|
72
|
+
kward # start interactive chat
|
|
73
|
+
kward "Explain this project" # ask one question and exit
|
|
74
|
+
kward help # show commands and examples
|
|
75
|
+
kward doctor # check local setup
|
|
76
|
+
kward login # sign in or save credentials
|
|
77
|
+
kward auth status # show credential status without secrets
|
|
78
|
+
kward sysprompt # inspect assembled instructions
|
|
79
|
+
kward rpc # start the experimental RPC backend
|
|
69
80
|
```
|
|
70
81
|
|
|
71
|
-
|
|
82
|
+
Use another workspace without changing directories:
|
|
72
83
|
|
|
73
84
|
```bash
|
|
74
|
-
|
|
85
|
+
kward --working-directory ~/code/project
|
|
86
|
+
kward --working-directory ~/code/project "Summarize this repository"
|
|
75
87
|
```
|
|
76
88
|
|
|
77
|
-
|
|
89
|
+
## Interactive slash commands
|
|
78
90
|
|
|
79
|
-
|
|
91
|
+
Use slash commands for local actions that should not go to the model:
|
|
80
92
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
- `list_directory` and `read_file` to inspect the workspace.
|
|
84
|
-
- `write_file` and `edit_file` to create or change files.
|
|
85
|
-
- `run_shell_command` to run confirmed local commands.
|
|
86
|
-
- `web_search` to search the live web.
|
|
87
|
-
- `code_search` to find packages, clone public GitHub repositories into cache, and read bounded source snippets.
|
|
88
|
-
- `ask_user_question` to ask structured clarification questions.
|
|
89
|
-
|
|
90
|
-
Safety rules:
|
|
91
|
-
|
|
92
|
-
- Existing files must be read in the current conversation before Kward can write or edit them.
|
|
93
|
-
- Every write, edit, and shell command asks for confirmation first.
|
|
94
|
-
- Text file reads and edits are capped at 256 KiB per file.
|
|
95
|
-
- When successful tool results include unified diffs, the composer status shows live session totals such as `+700|-572`.
|
|
96
|
-
|
|
97
|
-
## Slash commands
|
|
98
|
-
|
|
99
|
-
Use slash commands in interactive mode for local Kward actions:
|
|
100
|
-
|
|
101
|
-
| Command | Purpose |
|
|
93
|
+
| Command | Use it when you want to... |
|
|
102
94
|
| --- | --- |
|
|
103
|
-
| `/
|
|
104
|
-
| `/
|
|
105
|
-
| `/
|
|
106
|
-
| `/
|
|
107
|
-
| `/
|
|
108
|
-
| `/
|
|
109
|
-
| `/
|
|
110
|
-
| `/
|
|
111
|
-
| `/
|
|
112
|
-
| `/
|
|
113
|
-
| `/
|
|
114
|
-
| `/
|
|
115
|
-
| `/
|
|
116
|
-
| `/
|
|
117
|
-
| `/
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
Prompt templates can add more slash commands. Plugin commands can also appear when trusted local plugins are installed.
|
|
95
|
+
| `/login` | sign in or save provider credentials. |
|
|
96
|
+
| `/model` | choose the active model. |
|
|
97
|
+
| `/reasoning` | choose reasoning effort. |
|
|
98
|
+
| `/status` | see session, model, and context status. |
|
|
99
|
+
| `/new` | start a fresh session. |
|
|
100
|
+
| `/resume` | continue a previous session. |
|
|
101
|
+
| `/name <name>` | name the current session. |
|
|
102
|
+
| `/clone` | copy the current session into a new branch. |
|
|
103
|
+
| `/copy last` | copy the latest assistant answer. |
|
|
104
|
+
| `/copy transcript` | copy the transcript as Markdown. |
|
|
105
|
+
| `/export notes.md` | write the transcript to a Markdown file. |
|
|
106
|
+
| `/compact [focus]` | summarize older context so a long chat can continue. |
|
|
107
|
+
| `/memory ...` | manage opt-in memory. |
|
|
108
|
+
| `/redraw` | fix terminal drawing after resize or glitches. |
|
|
109
|
+
| `/exit` | leave Kward. |
|
|
110
|
+
|
|
111
|
+
Prompt templates and plugins can add more slash commands.
|
|
122
112
|
|
|
123
113
|
## Sessions
|
|
124
114
|
|
|
125
|
-
Interactive chats are
|
|
115
|
+
Interactive chats are saved under:
|
|
126
116
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
- `/name <name>` gives the current session a human-readable name.
|
|
131
|
-
- `/clone` creates a new independent copy. Cloned sessions remember their parent and appear in the recent session picker by modification time.
|
|
132
|
-
- `/copy` and `/copy last` copy the latest assistant response without terminal borders or ANSI styling. `/copy transcript` copies the clean Markdown transcript. Mouse selection may still include terminal UI chrome.
|
|
133
|
-
- `/export [path]` writes a Markdown transcript. Explicit paths are resolved relative to the current workspace and must stay inside the workspace or Kward session directory.
|
|
134
|
-
- `/compact [instructions]` summarizes older conversation into a structured Ruby-aware checkpoint. Text after `/compact ` is freeform focus text, not parsed as flags.
|
|
117
|
+
```text
|
|
118
|
+
~/.kward/sessions/
|
|
119
|
+
```
|
|
135
120
|
|
|
136
|
-
|
|
121
|
+
Sessions are scoped to the workspace. Use them when work spans more than one terminal sitting.
|
|
137
122
|
|
|
138
|
-
|
|
123
|
+
Typical flow:
|
|
139
124
|
|
|
140
|
-
|
|
125
|
+
```text
|
|
126
|
+
/name oauth cleanup
|
|
127
|
+
# work with Kward
|
|
128
|
+
/export oauth-notes.md
|
|
129
|
+
/exit
|
|
130
|
+
```
|
|
141
131
|
|
|
142
|
-
|
|
132
|
+
Later:
|
|
143
133
|
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
"compaction": {
|
|
147
|
-
"enabled": true,
|
|
148
|
-
"reserve_tokens": 16384,
|
|
149
|
-
"keep_recent_tokens": 20000
|
|
150
|
-
}
|
|
151
|
-
}
|
|
134
|
+
```text
|
|
135
|
+
/resume
|
|
152
136
|
```
|
|
153
137
|
|
|
154
|
-
|
|
138
|
+
Use `/compact` when a conversation gets long. Kward summarizes older context and keeps recent context active. After compaction, it may need to re-read files before editing them again.
|
|
155
139
|
|
|
156
|
-
##
|
|
157
|
-
|
|
158
|
-
Memory is disabled by default and only applies to interactive sessions.
|
|
140
|
+
## One-shot prompts
|
|
159
141
|
|
|
160
|
-
|
|
142
|
+
One-shot prompts are best for short tasks that do not need session history:
|
|
161
143
|
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
/memory list
|
|
167
|
-
/memory why
|
|
168
|
-
/memory promote <id>
|
|
169
|
-
/memory relax <id>
|
|
170
|
-
/memory forget <id>
|
|
171
|
-
/memory disable
|
|
144
|
+
```bash
|
|
145
|
+
kward "What does this repository do?"
|
|
146
|
+
git diff | kward "Review this diff"
|
|
147
|
+
cat error.log | kward "Explain the likely cause"
|
|
172
148
|
```
|
|
173
149
|
|
|
174
|
-
|
|
150
|
+
Use `--` when your prompt starts with something that could be parsed as a command or option:
|
|
175
151
|
|
|
176
|
-
|
|
152
|
+
```bash
|
|
153
|
+
kward -- explain --working-directory
|
|
154
|
+
```
|
|
177
155
|
|
|
178
|
-
-
|
|
179
|
-
- Shift+Enter inserts a newline.
|
|
180
|
-
- Up/Down browse prompt history.
|
|
181
|
-
- Ctrl+D exits from an empty prompt.
|
|
182
|
-
- Ctrl+C stops the current response while assistant or tool output is running.
|
|
183
|
-
- Backspace at the beginning of the prompt removes the most recent image attachment.
|
|
156
|
+
One-shot prompts do not use Kward memory.
|
|
184
157
|
|
|
185
|
-
|
|
158
|
+
## Workspace tools
|
|
186
159
|
|
|
187
|
-
|
|
160
|
+
During a turn, Kward can inspect and change the workspace with tools for:
|
|
188
161
|
|
|
189
|
-
|
|
162
|
+
- listing and reading files,
|
|
163
|
+
- creating and editing files,
|
|
164
|
+
- running shell commands,
|
|
165
|
+
- searching the web,
|
|
166
|
+
- fetching specific URLs,
|
|
167
|
+
- inspecting public source repositories,
|
|
168
|
+
- asking structured clarification questions.
|
|
190
169
|
|
|
191
|
-
|
|
192
|
-
- Markdown image links,
|
|
193
|
-
- `file://` image URLs,
|
|
194
|
-
- image data URLs.
|
|
170
|
+
Important guardrails:
|
|
195
171
|
|
|
196
|
-
|
|
172
|
+
- Existing files must be read before Kward can edit or overwrite them.
|
|
173
|
+
- File reads and edits are bounded to avoid loading very large files by accident.
|
|
174
|
+
- Shell commands run from the workspace and should be treated like commands you run yourself.
|
|
197
175
|
|
|
198
|
-
##
|
|
176
|
+
## Images
|
|
199
177
|
|
|
200
|
-
|
|
178
|
+
If the active model supports images, Kward can attach image paths, Markdown image links, `file://` URLs, or image data URLs pasted into the composer.
|
|
201
179
|
|
|
202
|
-
|
|
203
|
-
|
|
180
|
+
Use this for tasks such as:
|
|
181
|
+
|
|
182
|
+
```text
|
|
183
|
+
This screenshot shows the broken layout. Find the likely CSS issue.
|
|
204
184
|
```
|
|
205
185
|
|
|
206
|
-
|
|
186
|
+
## Pan mode
|
|
187
|
+
|
|
188
|
+
Pan mode starts a simple LAN web UI:
|
|
207
189
|
|
|
208
190
|
```bash
|
|
209
|
-
|
|
191
|
+
kward --working-directory ~/code/project pan
|
|
210
192
|
```
|
|
211
193
|
|
|
212
|
-
|
|
194
|
+
Use it only on trusted networks. It exposes the same file, shell, and web tools through a browser UI and requires credentials configured in `config.json`. See [Configuration](configuration.md).
|
|
195
|
+
|
|
196
|
+
## RPC backend
|
|
213
197
|
|
|
214
|
-
|
|
198
|
+
`kward rpc` starts the experimental JSON-RPC backend for UI clients and editor integrations. Terminal users can ignore it. Integration authors should read [RPC protocol](rpc.md).
|
data/doc/web-search.md
CHANGED
|
@@ -1,28 +1,94 @@
|
|
|
1
1
|
# Web search
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use web search when the answer depends on current or external information:
|
|
4
|
+
|
|
5
|
+
- current framework or dependency docs,
|
|
6
|
+
- release notes and migration guides,
|
|
7
|
+
- security advisories,
|
|
8
|
+
- pricing or provider pages,
|
|
9
|
+
- bug reports and issue discussions,
|
|
10
|
+
- a specific URL you want Kward to inspect.
|
|
4
11
|
|
|
5
12
|
Example prompts:
|
|
6
13
|
|
|
7
14
|
```text
|
|
8
|
-
|
|
15
|
+
Check the current Rails release notes and summarize migration risks for this project.
|
|
9
16
|
Find the official OpenRouter docs for model configuration.
|
|
10
17
|
Check whether this dependency has a recent security advisory.
|
|
18
|
+
Read this URL and explain the setup steps: https://example.com/docs
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## How Kward researches
|
|
22
|
+
|
|
23
|
+
Kward has three web tools:
|
|
24
|
+
|
|
25
|
+
1. `web_search` finds candidate sources.
|
|
26
|
+
2. `fetch_content` reads human-readable pages.
|
|
27
|
+
3. `fetch_raw` reads machine-readable files such as JSON, YAML, XML, RSS, OpenAPI specs, or plain text.
|
|
28
|
+
|
|
29
|
+
A good research flow is:
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
Search for the official docs, fetch the relevant page, then answer with the source URL.
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Kward should search first, then fetch important pages before relying on them.
|
|
36
|
+
|
|
37
|
+
## Network behavior
|
|
38
|
+
|
|
39
|
+
Web tools are advertised to the model by default. Queries and fetched URLs are sent over the network to the selected provider or target host.
|
|
40
|
+
|
|
41
|
+
In automatic mode, provider fallback is:
|
|
42
|
+
|
|
43
|
+
1. Exa API when `EXA_API_KEY` is configured, otherwise keyless Exa MCP.
|
|
44
|
+
2. Perplexity API when configured and model-provider fallback is allowed.
|
|
45
|
+
3. Gemini API with Google Search grounding when configured and model-provider fallback is allowed.
|
|
46
|
+
4. DuckDuckGo HTML search, then bundled public SearXNG instances.
|
|
47
|
+
|
|
48
|
+
You do not need an API key for basic web search, but keys can improve limits or provider choice.
|
|
49
|
+
|
|
50
|
+
## Disable web tools
|
|
51
|
+
|
|
52
|
+
Hide all web tools:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"web_search": {
|
|
57
|
+
"enabled": false
|
|
58
|
+
}
|
|
59
|
+
}
|
|
11
60
|
```
|
|
12
61
|
|
|
13
|
-
|
|
62
|
+
Use this when working on private projects where no prompt should trigger external lookup.
|
|
63
|
+
|
|
64
|
+
## Tool details
|
|
65
|
+
|
|
66
|
+
### `web_search`
|
|
67
|
+
|
|
68
|
+
Finds candidate sources. Arguments:
|
|
69
|
+
|
|
70
|
+
- `queries`: one to four search strings.
|
|
71
|
+
- `max_results`: results per query, default 5, capped at 20.
|
|
72
|
+
- `provider`: optional `auto`, `exa`, `perplexity`, `gemini`, or `duckduckgo`.
|
|
73
|
+
- `recency_filter`: optional `day`, `week`, `month`, or `year`.
|
|
74
|
+
- `domain_filter`: optional domains to include, or domains prefixed with `-` to exclude.
|
|
75
|
+
|
|
76
|
+
### `fetch_content`
|
|
77
|
+
|
|
78
|
+
Reads a specific HTTP or HTTPS page and extracts readable text. Use it for docs pages, articles, issues, and release notes.
|
|
79
|
+
|
|
80
|
+
Arguments:
|
|
81
|
+
|
|
82
|
+
- `url`
|
|
83
|
+
- `max_bytes`: default 16384, capped at 131072.
|
|
84
|
+
- `extract`: optional `auto`, `text`, or `markdown`.
|
|
14
85
|
|
|
15
|
-
|
|
16
|
-
2. Perplexity API when configured and `allow_model_providers` is true
|
|
17
|
-
3. Gemini API with Google Search grounding when configured and `allow_model_providers` is true
|
|
18
|
-
4. Legacy DuckDuckGo HTML search, then bundled public SearXNG instances
|
|
86
|
+
### `fetch_raw`
|
|
19
87
|
|
|
20
|
-
|
|
88
|
+
Reads a specific HTTP or HTTPS resource without readability extraction. Use it for JSON, YAML, XML, RSS, OpenAPI specs, and plain text.
|
|
21
89
|
|
|
22
|
-
|
|
90
|
+
Arguments:
|
|
23
91
|
|
|
24
|
-
- `
|
|
25
|
-
- `
|
|
26
|
-
- `
|
|
27
|
-
- `recency_filter`: optional `day`, `week`, `month`, or `year`
|
|
28
|
-
- `domain_filter`: optional list of included domains, or excluded domains prefixed with `-`
|
|
92
|
+
- `url`
|
|
93
|
+
- `max_bytes`: default 16384, capped at 131072.
|
|
94
|
+
- `accept`: optional HTTP `Accept` header.
|
data/exe/kward
CHANGED
data/kward.gemspec
CHANGED
|
@@ -13,6 +13,10 @@ Gem::Specification.new do |spec|
|
|
|
13
13
|
spec.required_ruby_version = ">= 3.2"
|
|
14
14
|
|
|
15
15
|
spec.metadata["rubygems_mfa_required"] = "true"
|
|
16
|
+
spec.metadata["source_code_uri"] = "https://github.com/kaiwood/kward"
|
|
17
|
+
spec.metadata["changelog_uri"] = "https://github.com/kaiwood/kward/blob/main/CHANGELOG.md"
|
|
18
|
+
spec.metadata["documentation_uri"] = "https://github.com/kaiwood/kward#readme"
|
|
19
|
+
spec.metadata["bug_tracker_uri"] = "https://github.com/kaiwood/kward/issues"
|
|
16
20
|
|
|
17
21
|
spec.files = Dir.chdir(__dir__) do
|
|
18
22
|
`git ls-files -z`.split("\x0").reject do |file|
|
data/lib/kward/agent.rb
CHANGED
|
@@ -8,9 +8,21 @@ require_relative "steering"
|
|
|
8
8
|
require_relative "telemetry/logger"
|
|
9
9
|
require_relative "tools/registry"
|
|
10
10
|
|
|
11
|
+
# Namespace for the Kward CLI agent runtime.
|
|
11
12
|
module Kward
|
|
12
13
|
# Runs model turns, handles context compaction, dispatches tool calls, and
|
|
13
14
|
# streams high-level events back to CLI and RPC callers.
|
|
15
|
+
#
|
|
16
|
+
# `Agent` is the main turn orchestrator. It should know what a turn means:
|
|
17
|
+
# append the user's input, call the model, persist assistant/tool messages,
|
|
18
|
+
# retry once after recoverable context overflow, apply in-flight steering, and
|
|
19
|
+
# emit frontend-neutral `Events::*` objects. It should not know terminal or RPC
|
|
20
|
+
# rendering details; callers translate events into their own UI protocol.
|
|
21
|
+
#
|
|
22
|
+
# Tool implementations own local side effects. `Client` owns provider HTTP
|
|
23
|
+
# details. `Conversation` owns transcript state. Keep future changes in the
|
|
24
|
+
# lowest layer that owns the behavior, and use `Agent` only for cross-step turn
|
|
25
|
+
# coordination.
|
|
14
26
|
class Agent
|
|
15
27
|
def initialize(client:, tool_registry: ToolRegistry.new, conversation: Conversation.new, telemetry_logger: TelemetryLogger.new)
|
|
16
28
|
@client = client
|
|
@@ -67,6 +79,7 @@ module Kward
|
|
|
67
79
|
overflow_retried = true
|
|
68
80
|
next
|
|
69
81
|
end
|
|
82
|
+
update_conversation_runtime(message)
|
|
70
83
|
yield Events::AssistantMessage.new(message: message) if block_given?
|
|
71
84
|
@conversation.append_assistant(message)
|
|
72
85
|
steered_after_message = append_steering_events(steering_state)
|
|
@@ -200,18 +213,32 @@ module Kward
|
|
|
200
213
|
end
|
|
201
214
|
ChatInvocation.call(
|
|
202
215
|
@client,
|
|
203
|
-
@conversation.
|
|
216
|
+
@conversation.context_messages,
|
|
204
217
|
{
|
|
205
218
|
tools: @tool_registry.schemas,
|
|
206
219
|
on_reasoning_delta: reasoning_delta,
|
|
207
220
|
on_assistant_delta: assistant_delta,
|
|
208
221
|
on_retry: retry_callback,
|
|
209
222
|
cancellation: cancellation,
|
|
210
|
-
steering: steering
|
|
223
|
+
steering: steering,
|
|
224
|
+
provider: @conversation.provider,
|
|
225
|
+
model: @conversation.model,
|
|
226
|
+
reasoning: @conversation.reasoning_effort
|
|
211
227
|
}
|
|
212
228
|
)
|
|
213
229
|
end
|
|
214
230
|
|
|
231
|
+
def update_conversation_runtime(message)
|
|
232
|
+
return unless message.is_a?(Hash)
|
|
233
|
+
|
|
234
|
+
provider = message["provider"] || message[:provider]
|
|
235
|
+
model = message["model"] || message[:model]
|
|
236
|
+
return if provider.to_s.empty? || model.to_s.empty?
|
|
237
|
+
|
|
238
|
+
@conversation.update_runtime_context!(provider: provider, model: model, reasoning_effort: @conversation.reasoning_effort)
|
|
239
|
+
@conversation.persist_runtime_context!
|
|
240
|
+
end
|
|
241
|
+
|
|
215
242
|
def safe_answer(content)
|
|
216
243
|
text = content.to_s
|
|
217
244
|
return text unless claims_file_edit?(text)
|
|
@@ -222,7 +249,7 @@ module Kward
|
|
|
222
249
|
end
|
|
223
250
|
|
|
224
251
|
def claims_file_edit?(text)
|
|
225
|
-
text.match?(/\b(I|I've|I have)\s+(changed|updated|modified|edited|created|deleted|wrote)\b/i)
|
|
252
|
+
text.match?(/\b(?:I|I've|I have)\s+(?:changed|updated|modified|edited|created|deleted|wrote)\s+(?:the\s+)?(?:file|files|[\w.\/-]+\.[\w-]+)\b/i)
|
|
226
253
|
end
|
|
227
254
|
|
|
228
255
|
def last_file_change_succeeded?
|
data/lib/kward/ansi.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
# Namespace for the Kward CLI agent runtime.
|
|
1
2
|
module Kward
|
|
3
|
+
# ANSI color and terminal capability helpers.
|
|
2
4
|
module ANSI
|
|
3
5
|
ESCAPE_PATTERN = /\e\[[0-9;?]*[ -\/]*[@-~]/.freeze
|
|
4
6
|
SGR_PATTERN = /\e\[[0-9;:]*m/.freeze
|
|
@@ -125,6 +127,7 @@ module Kward
|
|
|
125
127
|
rendered.join("\n") + (string.end_with?("\n") ? "\n" : "")
|
|
126
128
|
end
|
|
127
129
|
|
|
130
|
+
# String wrapper that strips ANSI escape sequences while preserving visible text operations.
|
|
128
131
|
class MarkdownStream
|
|
129
132
|
def initialize(enabled: ANSI.enabled?)
|
|
130
133
|
@enabled = enabled
|