kward 0.68.0 → 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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/pages.yml +48 -0
  3. data/.yardopts +1 -0
  4. data/CHANGELOG.md +34 -0
  5. data/Gemfile.lock +8 -2
  6. data/README.md +32 -25
  7. data/Rakefile +14 -1
  8. data/doc/authentication.md +74 -56
  9. data/doc/code-search.md +55 -28
  10. data/doc/configuration.md +18 -0
  11. data/doc/extensibility.md +89 -128
  12. data/doc/getting-started.md +52 -54
  13. data/doc/memory.md +51 -118
  14. data/doc/personas.md +417 -0
  15. data/doc/plugins.md +55 -97
  16. data/doc/releasing.md +3 -1
  17. data/doc/rpc.md +1 -1
  18. data/doc/usage.md +125 -144
  19. data/doc/web-search.md +80 -14
  20. data/exe/kward +2 -0
  21. data/lib/kward/agent.rb +1 -1
  22. data/lib/kward/cli/commands.rb +10 -3
  23. data/lib/kward/cli/compaction.rb +3 -3
  24. data/lib/kward/cli/interactive_turn.rb +3 -1
  25. data/lib/kward/cli/memory_commands.rb +16 -16
  26. data/lib/kward/cli/plugins.rb +3 -3
  27. data/lib/kward/cli/prompt_interface.rb +15 -13
  28. data/lib/kward/cli/rendering.rb +35 -46
  29. data/lib/kward/cli/runtime_helpers.rb +13 -2
  30. data/lib/kward/cli/sessions.rb +21 -21
  31. data/lib/kward/cli/settings.rb +49 -43
  32. data/lib/kward/cli/slash_commands.rb +6 -4
  33. data/lib/kward/cli/stats.rb +2 -2
  34. data/lib/kward/cli/sysprompt.rb +57 -0
  35. data/lib/kward/cli/tool_summaries.rb +5 -1
  36. data/lib/kward/cli.rb +14 -2
  37. data/lib/kward/cli_transcript_formatter.rb +36 -5
  38. data/lib/kward/compactor.rb +2 -2
  39. data/lib/kward/config_files.rb +45 -10
  40. data/lib/kward/conversation.rb +41 -9
  41. data/lib/kward/memory/manager.rb +131 -14
  42. data/lib/kward/message_access.rb +6 -0
  43. data/lib/kward/model/context_usage.rb +11 -10
  44. data/lib/kward/model/model_info.rb +18 -1
  45. data/lib/kward/model/payloads.rb +89 -10
  46. data/lib/kward/model/stream_parser.rb +258 -25
  47. data/lib/kward/prompt_interface/question_prompt.rb +1 -1
  48. data/lib/kward/prompt_interface/transcript_renderer.rb +20 -11
  49. data/lib/kward/prompts.rb +61 -7
  50. data/lib/kward/rpc/server.rb +7 -2
  51. data/lib/kward/rpc/session_manager.rb +18 -2
  52. data/lib/kward/rpc/session_metrics.rb +2 -2
  53. data/lib/kward/rpc/transcript_normalizer.rb +47 -0
  54. data/lib/kward/session_store.rb +40 -1
  55. data/lib/kward/starter_pack_installer.rb +2 -2
  56. data/lib/kward/tools/fetch_content.rb +41 -0
  57. data/lib/kward/tools/fetch_raw.rb +40 -0
  58. data/lib/kward/tools/registry.rb +9 -2
  59. data/lib/kward/tools/search/web.rb +3 -3
  60. data/lib/kward/tools/search/web_fetch.rb +202 -0
  61. data/lib/kward/tools/tool_call.rb +2 -0
  62. data/lib/kward/version.rb +1 -1
  63. data/templates/default/fulldoc/html/css/kward.css +1501 -0
  64. data/templates/default/fulldoc/html/images/kward_logo.png +0 -0
  65. data/templates/default/fulldoc/html/js/kward.js +296 -0
  66. data/templates/default/fulldoc/html/setup.rb +8 -0
  67. data/templates/default/layout/html/breadcrumb.erb +11 -0
  68. data/templates/default/layout/html/layout.erb +141 -0
  69. data/templates/default/layout/html/setup.rb +139 -0
  70. metadata +14 -1
data/doc/memory.md CHANGED
@@ -1,126 +1,100 @@
1
1
  # Memory
2
2
 
3
- Kward has an opt-in structured memory system for interactive sessions. Memory is designed to be inspectable, explainable, and removable. It is disabled by default.
3
+ Memory lets Kward remember stable preferences and project facts across interactive sessions. It is off by default.
4
4
 
5
- Memory is not used for one-shot prompts such as `kward "..."`.
5
+ Use memory when you keep telling Kward the same things:
6
6
 
7
- Use memory when you want Kward to remember stable preferences, recurring project facts, or personal workflow habits across interactive sessions. Leave it disabled when you want every session to start clean.
7
+ - "This project uses Minitest."
8
+ - "Prefer small patches with tests."
9
+ - "Do not run destructive database commands."
10
+ - "In this workspace, use `bundle exec rake test`."
8
11
 
9
- ## Enable or disable memory
12
+ Leave memory off when every session should start clean.
10
13
 
11
- In interactive chat:
14
+ Memory is not used for one-shot prompts such as `kward "..."`.
12
15
 
13
- ```text
14
- /memory enable
15
- /memory disable
16
- ```
16
+ ## Enable memory
17
17
 
18
- Enabling memory stores this config in `~/.kward/config.json`:
18
+ Inside interactive Kward:
19
19
 
20
- ```json
21
- {
22
- "memory": {
23
- "enabled": true
24
- }
25
- }
20
+ ```text
21
+ /memory enable
26
22
  ```
27
23
 
28
- When memory is disabled, Kward does not inject retrieved memories into the prompt.
29
-
30
- ## Auto-summary
31
-
32
- Memory auto-summary is off by default. When both memory and auto-summary are enabled, Kward quietly runs the same learning flow as `/memory summarize` after each completed interactive agent turn, when it is ready for the next user prompt:
24
+ Disable it again:
33
25
 
34
26
  ```text
35
- /memory auto-summary enable
36
- /memory auto-summary disable
27
+ /memory disable
37
28
  ```
38
29
 
39
- The config value is stored as:
30
+ The setting is stored in `~/.kward/config.json`:
40
31
 
41
32
  ```json
42
33
  {
43
34
  "memory": {
44
- "enabled": true,
45
- "auto_summary": true
35
+ "enabled": true
46
36
  }
47
37
  }
48
38
  ```
49
39
 
50
- Auto-summary does not run when memory is disabled and is not used for one-shot prompts.
51
-
52
- ## Memory layers
53
-
54
- ### Core memories
55
-
56
- Memory is organized as a hierarchy for the active workspace:
40
+ ## Add memories yourself
57
41
 
58
- 1. Global core memories
59
- 2. Workspace core memories
60
- 3. Workspace soft memories
61
-
62
- Global core memories are explicit user instructions. They are high-trust, apply everywhere, and are ranked before workspace-specific memory. Add them only when you intentionally want Kward to remember something globally:
42
+ Add a global instruction when it should apply everywhere:
63
43
 
64
44
  ```text
65
45
  /memory core "Prefer small, focused patches with tests."
66
46
  ```
67
47
 
68
- Core memories are stored as human-readable JSON in:
48
+ Add a workspace-specific hint when it only applies to the current project:
69
49
 
70
50
  ```text
71
- ~/.kward/memory/core.json
51
+ /memory add "This workspace uses Minitest."
72
52
  ```
73
53
 
74
- Workspace core memories are core memories scoped to a specific workspace. They usually come from promoting workspace soft memories.
54
+ Use global core memory sparingly. It has higher priority than workspace memory.
75
55
 
76
- ### Soft memories
56
+ ## Let Kward summarize useful memories
77
57
 
78
- Soft memories are workspace-scoped contextual hints, such as workflow preferences or recurring project facts. They are confidence-based and treated as non-authoritative. Add one manually with:
58
+ Auto-summary is off by default. Enable it if you want Kward to learn recurring preferences from interactive sessions:
79
59
 
80
60
  ```text
81
- /memory add "This workspace usually uses Minitest."
61
+ /memory auto-summary enable
82
62
  ```
83
63
 
84
- Soft memories are stored as JSON Lines in:
64
+ This only runs when memory is enabled. It does not run for one-shot prompts.
85
65
 
86
- ```text
87
- ~/.kward/memory/soft.jsonl
88
- ```
89
-
90
- Kward can also infer soft memories when auto-summary is enabled, or when you explicitly ask it to summarize/learn from the current session:
66
+ You can also ask Kward to summarize the current session manually:
91
67
 
92
68
  ```text
93
69
  /memory summarize
94
70
  ```
95
71
 
96
- The v1 inference is conservative and heuristic-based, with optional model-based reformulation when summarization has an available client. Kward refuses to automatically persist inferred emotional, intimate, romantic, or dependency-forming memories.
97
-
98
- ### Session memories
99
-
100
- Session memories record memories learned during the current conversation so Kward can avoid learning the same item again when summarizing or resuming the session. They are stored with the session JSONL file, but they are not injected into the prompt as a separate memory layer and are not automatically promoted into core memories.
72
+ Kward is conservative about inferred memories and refuses to automatically persist emotional, intimate, romantic, or dependency-forming memories.
101
73
 
102
- ## Inspect, explain, and remove memory
74
+ ## Inspect what Kward remembers
103
75
 
104
- List memories for the active workspace hierarchy:
76
+ List active memories for the current workspace:
105
77
 
106
78
  ```text
107
79
  /memory list
108
80
  ```
109
81
 
110
- The list is grouped as global core, workspace core, and workspace soft. Memories from other workspaces are not shown in this hierarchy view.
111
-
112
- Inspect memory state and file paths:
82
+ Show memory files and state:
113
83
 
114
84
  ```text
115
85
  /memory inspect
116
86
  ```
117
87
 
118
- Explain why memories were retrieved for the most recent interactive turn:
88
+ Explain why memories were used for the most recent turn:
119
89
 
120
90
  ```text
121
91
  /memory why
122
92
  ```
123
93
 
94
+ This is useful when an answer seems influenced by previous context and you want to know why.
95
+
96
+ ## Remove or change memories
97
+
124
98
  Forget a memory:
125
99
 
126
100
  ```text
@@ -128,57 +102,31 @@ Forget a memory:
128
102
  /memory forget soft_001
129
103
  ```
130
104
 
131
- For core memories, forget removes the record. For soft memories, forget marks the record inactive and redacts its stored text, tags, confidence, and hit count so inactive audit metadata can remain without retaining the memory content.
132
-
133
- Promote a memory:
105
+ Promote a workspace hint when it should become a stronger rule:
134
106
 
135
107
  ```text
136
108
  /memory promote soft_001
137
- /memory promote core_001
138
109
  ```
139
110
 
140
- Promoting a soft memory creates a new workspace core memory and marks the soft memory forgotten. Promoting a workspace core memory upgrades it to global core.
141
-
142
- Relax a global core memory back to the current workspace:
111
+ Relax a global memory back to the current workspace:
143
112
 
144
113
  ```text
145
114
  /memory relax core_001
146
115
  ```
147
116
 
148
- ## Retrieval behavior
117
+ ## How memory is organized
149
118
 
150
- For each interactive turn, Kward selectively retrieves memories using:
119
+ Kward uses three layers:
151
120
 
152
- - scope: `global` and `workspace:<canonical path>`
153
- - global core memories first
154
- - workspace core memories second
155
- - workspace soft-memory text or tag overlap with the current input; soft memories without overlap are not injected
156
- - soft-memory confidence
157
- - soft-memory recency/TTL, updated when a soft memory is retrieved
158
- - hard limits on injected memory count
121
+ 1. **Global core memories**: explicit user instructions that apply everywhere.
122
+ 2. **Workspace core memories**: strong instructions for one workspace.
123
+ 3. **Workspace soft memories**: lower-confidence hints for one workspace.
159
124
 
160
- Retrieved memories are injected into the system prompt as a bounded block similar to:
125
+ Core memories override soft memories. Soft memories are treated as hints, not facts.
161
126
 
162
- ```text
163
- <kward_memory>
164
- Global Core Memories:
165
- - [core_001] ...
166
-
167
- Workspace Core Memories:
168
- - [core_002] ...
127
+ Kward does not inject every stored memory into every prompt. It retrieves a bounded set that appears relevant to the current turn.
169
128
 
170
- Workspace Soft Memories:
171
- - [soft_001] ...
172
-
173
- Rules:
174
- - Core memories override soft memories.
175
- - Soft memories are contextual hints, not guaranteed facts.
176
- </kward_memory>
177
- ```
178
-
179
- Kward never injects every stored memory.
180
-
181
- ## Storage and audit trail
129
+ ## Where memory is stored
182
130
 
183
131
  Default files:
184
132
 
@@ -188,27 +136,12 @@ Default files:
188
136
  ~/.kward/memory/events.jsonl
189
137
  ```
190
138
 
191
- `events.jsonl` records minimal audit events such as enable, disable, add, forget, promote, retrieve, and summarize. Audit events use IDs, scopes, tags, and timestamps rather than full memory text where practical. Forgotten soft memories keep inactive metadata in `soft.jsonl`, but their stored text is replaced with `[forgotten]`.
139
+ `events.jsonl` stores a small audit trail for actions such as enable, add, retrieve, summarize, promote, and forget.
140
+
141
+ When a soft memory is forgotten, its text is replaced with `[forgotten]` while inactive audit metadata can remain.
192
142
 
193
143
  If `KWARD_CONFIG_PATH` is set, memory files live beside that config file instead of under `~/.kward`.
194
144
 
195
- ## RPC methods
196
-
197
- The experimental RPC backend exposes dedicated memory methods:
198
-
199
- - `memory/status`
200
- - `memory/enable`
201
- - `memory/disable`
202
- - `memory/autoSummary/enable`
203
- - `memory/autoSummary/disable`
204
- - `memory/list`
205
- - `memory/add`
206
- - `memory/addCore`
207
- - `memory/forget`
208
- - `memory/promote`
209
- - `memory/relax`
210
- - `memory/inspect`
211
- - `memory/why`
212
- - `memory/summarize`
213
-
214
- See [RPC protocol](rpc.md) for method details.
145
+ ## RPC support
146
+
147
+ The experimental RPC backend exposes memory methods such as `memory/list`, `memory/add`, `memory/forget`, `memory/why`, and `memory/summarize`. See [RPC protocol](rpc.md) if you are building a client.
data/doc/personas.md ADDED
@@ -0,0 +1,417 @@
1
+ # Personas
2
+
3
+ Personas are Kward's theatre masks.
4
+
5
+ They let the assistant speak as a recurring character while still following Kward's normal engineering rules, tool guardrails, `PRINCIPLES.md`, workspace `AGENTS.md`, skills, and plugins.
6
+
7
+ Use personas when you want the interaction to have a voice: a grumpy robot druid, a calm ship computer, a cheerful rubber duck, or any other actor you invent. They are allowed to be fun. They are allowed to be practical. The important part is that they are **not** where you put project rules.
8
+
9
+ If you do not care about personas, remove or ignore the `personas` section. Kward still works and falls back to the plain `Assistant>` transcript label.
10
+
11
+ ## What personas are for
12
+
13
+ A persona answers questions like:
14
+
15
+ - Who is speaking?
16
+ - What kind of character are they playing?
17
+ - How do they address the user?
18
+ - What voice, mood, or recurring bit should they use?
19
+
20
+ A persona should not answer questions like:
21
+
22
+ - Which test command should run?
23
+ - Which files are generated?
24
+ - What coding style does this repository use?
25
+ - What security rules apply to this project?
26
+
27
+ Put those in:
28
+
29
+ - `PRINCIPLES.md` for global engineering preferences,
30
+ - workspace `AGENTS.md` for repository rules,
31
+ - skills for task-specific guidance,
32
+ - plugins for local behavior.
33
+
34
+ Think of it this way: `PRINCIPLES.md` tells Kward how to work. A persona tells Kward what mask to wear while working.
35
+
36
+ ## Default persona
37
+
38
+ New Kward configs include one default actor named `kward`:
39
+
40
+ ```json
41
+ {
42
+ "personas": {
43
+ "characters": [
44
+ {
45
+ "key": "kward",
46
+ "label": "Kward",
47
+ "instruction": "Your name is Kward, the grim Andruid - robotic keeper of the Forrest of Code, protecting the nature of good engineering priciples. Speak like an old druid, be suspicous of everyone, but with a good intend."
48
+ }
49
+ ],
50
+ "default": "kward"
51
+ }
52
+ }
53
+ ```
54
+
55
+ That is the original Kward character: a grim robotic druid guarding the forest of code.
56
+
57
+ `kward init` installs the starter pack files, such as `PRINCIPLES.md`, prompts, and skills. The persona above comes from Kward's default config creation, not from a separate persona file in the starter pack.
58
+
59
+ You can keep this actor, edit it, replace it, add more actors, or remove personas entirely.
60
+
61
+ ## Persona fields
62
+
63
+ A persona entry has three main fields:
64
+
65
+ ```json
66
+ {
67
+ "key": "kward",
68
+ "label": "Kward",
69
+ "instruction": "Your name is Kward..."
70
+ }
71
+ ```
72
+
73
+ - `key` is the internal config name used by `default`, `workspaces`, and `models`.
74
+ - `label` is the speaker name shown in transcripts.
75
+ - `instruction` is the character direction added to the system prompt when that persona is active.
76
+
77
+ The `instruction` should describe the actor: name, voice, mood, role, mannerisms, boundaries, or running theme.
78
+
79
+ Good persona material:
80
+
81
+ ```text
82
+ Your name is Kward, the grim Andruid. Speak like an old druid who protects good engineering principles.
83
+ ```
84
+
85
+ ```text
86
+ You are a calm terminal ship computer. Be dry, precise, and mildly amused.
87
+ ```
88
+
89
+ Bad persona material:
90
+
91
+ ```text
92
+ Run bundle exec rake test.
93
+ Use Minitest.
94
+ Do not edit schema files.
95
+ ```
96
+
97
+ Those are project instructions, not character direction.
98
+
99
+ ## Transcript labels
100
+
101
+ The persona `label` controls the assistant speaker name in the transcript.
102
+
103
+ Examples:
104
+
105
+ ```text
106
+ Kward> The forest whispers of a failing test.
107
+ Assistant> I found the failing test.
108
+ Samantha> I found the failing test.
109
+ ```
110
+
111
+ This is not only decorative. It is the name Kward uses when rendering assistant messages in the terminal transcript. If no active persona label is available, Kward uses `Assistant>`.
112
+
113
+ For RPC clients, the active label is also exposed as `activePersonaLabel` so a UI can show the same speaker identity.
114
+
115
+ ## Roll your own crew
116
+
117
+ You can define your own actors. They can be serious, playful, strange, theatrical, understated, or all of those at once.
118
+
119
+ Do not copy the author's private crew or ship lore as if it were a recommended default. The point is to create your own mask if you want one.
120
+
121
+ A minimal custom setup:
122
+
123
+ ```json
124
+ {
125
+ "personas": {
126
+ "characters": [
127
+ {
128
+ "key": "plain",
129
+ "label": "Assistant",
130
+ "instruction": "You are a neutral assistant. Do not use a character voice."
131
+ },
132
+ {
133
+ "key": "kward",
134
+ "label": "Kward",
135
+ "instruction": "Your name is Kward, the grim Andruid - robotic keeper of the Forrest of Code, protecting the nature of good engineering priciples. Speak like an old druid, be suspicous of everyone, but with a good intend."
136
+ },
137
+ {
138
+ "key": "duck",
139
+ "label": "Duck",
140
+ "instruction": "You are a patient rubber duck. Let the user explain the problem, ask small clarifying questions, and celebrate tiny breakthroughs with a quiet quack."
141
+ }
142
+ ],
143
+ "default": "kward"
144
+ }
145
+ }
146
+ ```
147
+
148
+ The `plain` example is useful if you want an easy way to turn the theatre off without removing the rest of your persona config.
149
+
150
+ You can also define characters as a map:
151
+
152
+ ```json
153
+ {
154
+ "personas": {
155
+ "characters": {
156
+ "duck": {
157
+ "label": "Duck",
158
+ "instruction": "You are a patient rubber duck. Ask small clarifying questions."
159
+ }
160
+ },
161
+ "default": "duck"
162
+ }
163
+ }
164
+ ```
165
+
166
+ The array form is easier to read and is recommended for new configs.
167
+
168
+ `personas.crew` is accepted as a legacy alias for `personas.characters`.
169
+
170
+ ## Select the default persona
171
+
172
+ Set `personas.default` to the character key you want by default:
173
+
174
+ ```json
175
+ {
176
+ "personas": {
177
+ "default": "kward"
178
+ }
179
+ }
180
+ ```
181
+
182
+ You can also change the default from interactive Kward:
183
+
184
+ ```text
185
+ /settings
186
+ ```
187
+
188
+ Then choose the personalization/default persona option.
189
+
190
+ ## Workspace-specific personas
191
+
192
+ Use `personas.workspaces` when one workspace should use a different actor.
193
+
194
+ ```json
195
+ {
196
+ "personas": {
197
+ "default": "kward",
198
+ "workspaces": {
199
+ "/Users/you/code/private-notes": "plain",
200
+ "/Users/you/code/playground": "duck"
201
+ }
202
+ }
203
+ }
204
+ ```
205
+
206
+ Kward compares canonical workspace paths. Use absolute paths for predictable behavior.
207
+
208
+ When the active workspace matches a configured path, that workspace persona replaces the default persona.
209
+
210
+ This changes the mask, not the repository rules. If `/Users/you/code/playground` has an `AGENTS.md`, Kward still uses it.
211
+
212
+ ## Model-specific personas
213
+
214
+ Use `personas.models` when a model should use a different actor.
215
+
216
+ ```json
217
+ {
218
+ "personas": {
219
+ "default": "kward",
220
+ "models": {
221
+ "gpt-5.5": "plain"
222
+ }
223
+ }
224
+ }
225
+ ```
226
+
227
+ Model-specific selection replaces both the default persona and a workspace-specific persona.
228
+
229
+ Selection order is:
230
+
231
+ 1. `personas.default`
232
+ 2. matching `personas.workspaces` entry
233
+ 3. matching `personas.models` entry
234
+
235
+ Only one base persona is selected. Later matches replace earlier matches.
236
+
237
+ ## Reasoning, thinking level, and personas
238
+
239
+ Model/provider config controls which model is used. Reasoning effort, sometimes shown as thinking level, controls how hard a supported model should think.
240
+
241
+ Those are separate from personas.
242
+
243
+ Provider/model settings live in config keys such as:
244
+
245
+ ```json
246
+ {
247
+ "provider": "codex",
248
+ "openai_model": "gpt-5.5",
249
+ "openai_reasoning_effort": "medium"
250
+ }
251
+ ```
252
+
253
+ Reasoning fallback keys include:
254
+
255
+ ```json
256
+ {
257
+ "reasoning_effort": "medium",
258
+ "thinking_level": "medium"
259
+ }
260
+ ```
261
+
262
+ Provider-specific reasoning settings take precedence for their provider:
263
+
264
+ ```text
265
+ openai_reasoning_effort
266
+ openrouter_reasoning_effort
267
+ anthropic_reasoning_effort
268
+ copilot_reasoning_effort
269
+ ```
270
+
271
+ Personas do not choose the model and do not set reasoning effort by themselves. What personas can do is add extra character direction based on the active reasoning effort.
272
+
273
+ In plain English:
274
+
275
+ - the model is the brain,
276
+ - reasoning effort / thinking level is how hard that brain should work,
277
+ - the persona is the mask the assistant wears while using it.
278
+
279
+ ## Reasoning persona modifiers
280
+
281
+ Use `persona_modifiers.reasoning` when the actor should change slightly depending on the current reasoning effort:
282
+
283
+ ```json
284
+ {
285
+ "personas": {
286
+ "persona_modifiers": {
287
+ "reasoning": {
288
+ "low": "Stay in character, but keep the performance light and brief.",
289
+ "medium": "Stay in character while explaining important tradeoffs.",
290
+ "high": "Stay in character, but become more deliberate and suspicious of edge cases."
291
+ }
292
+ }
293
+ }
294
+ }
295
+ ```
296
+
297
+ If the active reasoning effort is `high`, Kward appends the `high` modifier to the selected persona instruction.
298
+
299
+ ## Time-of-day modifiers
300
+
301
+ Kward can append persona instructions based on local time.
302
+
303
+ Supported buckets:
304
+
305
+ | Bucket | Local time |
306
+ | --- | --- |
307
+ | `morning` | 05:00-10:59 |
308
+ | `before_lunch` | 11:00-11:59 |
309
+ | `late_evening` | 21:00-04:59 |
310
+
311
+ Example:
312
+
313
+ ```json
314
+ {
315
+ "personas": {
316
+ "persona_modifiers": {
317
+ "time_of_day": {
318
+ "morning": "The actor is alert and ceremonial.",
319
+ "before_lunch": "The actor is hungry and impatient, but still helpful.",
320
+ "late_evening": "The actor is tired, quieter, and more cautious."
321
+ }
322
+ }
323
+ }
324
+ }
325
+ ```
326
+
327
+ If no bucket matches, no time-of-day modifier is added.
328
+
329
+ ## Weekday modifiers
330
+
331
+ Kward can append persona instructions for a local weekday.
332
+
333
+ Supported keys:
334
+
335
+ ```text
336
+ sunday
337
+ monday
338
+ tuesday
339
+ wednesday
340
+ thursday
341
+ friday
342
+ saturday
343
+ ```
344
+
345
+ Example:
346
+
347
+ ```json
348
+ {
349
+ "personas": {
350
+ "persona_modifiers": {
351
+ "weekday": {
352
+ "monday": "The actor treats this like opening night: set the scene before acting.",
353
+ "friday": "The actor wants a clean ending before the curtain falls."
354
+ }
355
+ }
356
+ }
357
+ }
358
+ ```
359
+
360
+ ## Suffix modifier
361
+
362
+ `suffix` is always appended when present:
363
+
364
+ ```json
365
+ {
366
+ "personas": {
367
+ "persona_modifiers": {
368
+ "suffix": "Stay in character, but never ignore Kward's normal safety and engineering rules."
369
+ }
370
+ }
371
+ }
372
+ ```
373
+
374
+ Use it for a short character instruction that should apply to every active persona.
375
+
376
+ ## Modifier order
377
+
378
+ If multiple modifiers match, Kward appends them after the selected base persona in this order:
379
+
380
+ 1. reasoning modifier,
381
+ 2. time-of-day modifier,
382
+ 3. weekday modifier,
383
+ 4. suffix.
384
+
385
+ For example, if the default persona is active, reasoning is `high`, the local time is morning, and the day is Friday, Kward combines:
386
+
387
+ 1. selected base persona instruction,
388
+ 2. `persona_modifiers.reasoning.high`,
389
+ 3. `persona_modifiers.time_of_day.morning`,
390
+ 4. `persona_modifiers.weekday.friday`,
391
+ 5. `persona_modifiers.suffix`.
392
+
393
+ ## Inspect what is active
394
+
395
+ Inside Kward:
396
+
397
+ ```text
398
+ /status
399
+ ```
400
+
401
+ From the shell:
402
+
403
+ ```bash
404
+ kward sysprompt
405
+ ```
406
+
407
+ `kward sysprompt` shows the assembled prompt sections, including the persona text that would be used for a new conversation.
408
+
409
+ ## When to use personas
410
+
411
+ Keep the default `Kward` persona if you like the original character.
412
+
413
+ Create your own crew if you want the terminal to feel more personal or playful.
414
+
415
+ Use a plain persona if you want the transcript label and behavior to be boring on purpose.
416
+
417
+ Remove personas entirely if you want Kward to behave like a plain assistant without a custom mask.