samagotchi 0.131.0 → 0.132.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/CHANGELOG.md +47 -1
- data/bin/chi +3 -1
- data/docs/architecture.md +32 -1
- data/docs/cli.md +29 -8
- data/docs/configuration.md +62 -6
- data/docs/desktop.md +15 -6
- data/docs/guardrails.md +3 -3
- data/docs/internals/anthropic.md +3 -2
- data/docs/internals/engine.md +4 -4
- data/docs/internals/prompt-caching.md +26 -6
- data/docs/memory.md +16 -2
- data/docs/plugins.md +68 -1
- data/lib/samagotchi/bootstrap_command.rb +35 -6
- data/lib/samagotchi/bundles/model-notes/manifest.yml +4 -1
- data/lib/samagotchi/bundles/model-notes/model_notes_tone.md +3 -0
- data/lib/samagotchi/bundles/model-notes/notes/README.md +14 -0
- data/lib/samagotchi/bundles/system/manifest.yml +1 -1
- data/lib/samagotchi/cache_confirm.rb +18 -0
- data/lib/samagotchi/chi_home.rb +311 -0
- data/lib/samagotchi/desktop/macos.rb +75 -19
- data/lib/samagotchi/engine.rb +35 -4
- data/lib/samagotchi/engine_snapshots.rb +5 -0
- data/lib/samagotchi/gem_update.rb +19 -10
- data/lib/samagotchi/guardrail_wiring.rb +3 -1
- data/lib/samagotchi/guardrails/protected_paths.rb +6 -3
- data/lib/samagotchi/guardrails/verdict.rb +1 -1
- data/lib/samagotchi/home_command.rb +149 -0
- data/lib/samagotchi/installed_versions.rb +5 -3
- data/lib/samagotchi/llm_context_command.rb +53 -7
- data/lib/samagotchi/llm_context_override.rb +3 -2
- data/lib/samagotchi/plugin/api.rb +45 -1
- data/lib/samagotchi/plugin/context.rb +34 -1
- data/lib/samagotchi/plugin/loader.rb +5 -2
- data/lib/samagotchi/plugin/prompt_sections.rb +124 -0
- data/lib/samagotchi/run_options.rb +1 -0
- data/lib/samagotchi/session_access/contract.rb +1 -1
- data/lib/samagotchi/session_commands.rb +64 -17
- data/lib/samagotchi/session_manager.rb +36 -1
- data/lib/samagotchi/session_model_settings.rb +5 -2
- data/lib/samagotchi/system_prompt.rb +34 -3
- data/lib/samagotchi/terminal_ui/attach_launcher.rb +3 -2
- data/lib/samagotchi/terminal_ui/formatting.rb +3 -0
- data/lib/samagotchi/testing/bundle.rb +22 -3
- data/lib/samagotchi/testing/host.rb +22 -1
- data/lib/samagotchi/testing/recorder.rb +6 -1
- data/lib/samagotchi/testing/recording_api.rb +1 -1
- data/lib/samagotchi/update_command.rb +65 -7
- data/lib/samagotchi/version.rb +1 -1
- data/lib/samagotchi/web/app.rb +11 -1
- data/lib/samagotchi/web/public/index.html +6 -2
- data/lib/samagotchi/web/public/llm_context_chip.js +4 -3
- data/lib/samagotchi/web/public/model_pick.js +26 -0
- data/lib/samagotchi/web/public/model_picker.js +3 -1
- data/lib/samagotchi/web/public/start_page.js +14 -2
- data/lib/samagotchi/web/server.rb +27 -8
- data/lib/samagotchi/web/update_check.rb +3 -2
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ebe264e1dbd5adc620889aa40d66fd458519c64f038a3a3e5de06ee6a6da46e7
|
|
4
|
+
data.tar.gz: 3c72148287422c9821c25bc3979c71890fb4abad81af3829650aef3c13549a3f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f8ffaf8ca17c125a38af6a30432d8b14a66ea97df8201686acedca8dde11869845b0e2a6abe0f9ece18db4e5848f9340b2ef73910371977fafe9889d430eebad
|
|
7
|
+
data.tar.gz: e556232bbad1093cff1779510162a179b1284cc90bd8cc54d8082e2a4dab5e96f98bb6ebae5ef99ab82610a1bd33880c830cfae8b1076d1e6ca841c406ae45b3
|
data/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,55 @@ and commands may change between minor versions. How releases are made:
|
|
|
7
7
|
[docs/releasing.md](docs/releasing.md).
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.132.0] - 2026-10-29
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `chi home`, `chi home set [--ruby PATH]`, `chi home doctor`: the chi home, the one Ruby and gem path every chi
|
|
15
|
+
launch boots (`~/.config/samagotchi/home.json`). The first `chi bootstrap` or `chi update` records it once (the
|
|
16
|
+
desktop helper's Ruby when it has samagotchi, else chi's own); see docs/configuration.md (The chi home). A
|
|
17
|
+
write or edit of home.json asks, as config.yml does (rule `chi-home`, the user's alone).
|
|
18
|
+
- Bundles: model-notes 0.2.0 ships `model_notes_tone` (`models: *`): every model answers first, in plain words, without
|
|
19
|
+
preambles or closing offers. Off with `chi --mute model_notes_tone`; your own note of that name wins.
|
|
20
|
+
- Plugins: `chi.prompt_section(name) { |ctx| … }` adds a bundle's text to the system prompt's stable part (after the
|
|
21
|
+
toolkit's prompt, before the memory indexes), and `chi.prompt_changed!` builds the prompt again at the next turn.
|
|
22
|
+
A section that fails keeps its last good text; `/stats` names the sections (`prompt sections:`).
|
|
23
|
+
- Plugins: a command can ask before a change that restarts the prompt cache, as `/thinking` does:
|
|
24
|
+
`ctx.cache_confirm(line, changed:)` gives a confirm for a person at a web tab or a TUI once the session has a
|
|
25
|
+
model reply, and the command returns `[text, confirm]` (the TUI prefills the `--yes` line, the web shows Apply).
|
|
26
|
+
- Plugins: `ctx.model_names` lists the names chi looks the session's model up under (alias, target, ref, bare id),
|
|
27
|
+
so a bundle can match a per-model map the way config.yml's `models:` settings are matched.
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- With a chi home, every session worker (whoever starts or wakes it), chi web's restart and Update, `chi update`
|
|
32
|
+
and `chi bootstrap`'s commonmarker install run on it: the home's Ruby with its gem path set inside Ruby, never in
|
|
33
|
+
an env, so session tools keep the spawner's GEM_HOME/GEM_PATH. `chi update` from another Ruby runs the home's
|
|
34
|
+
(`updating the chi home (<ruby>)`) and installs into its gems; a worker whose home can't load chi logs one
|
|
35
|
+
`boot_failed` line instead of a silent spawn timeout. Without a home every launch is as before.
|
|
36
|
+
- Desktop helper: `chi desktop install` and `upgrade` make it boot the chi home when there is one, and its launch
|
|
37
|
+
file no longer carries `RUBYLIB`, nor `GEM_HOME`/`GEM_PATH` when it boots the home (they reached every command its
|
|
38
|
+
sessions ran). `chi update` drops `RUBYLIB` from an existing one, and `GEM_HOME`/`GEM_PATH` once it boots the home.
|
|
39
|
+
- `/model` asks before switching to another model once the session has a model reply, from a web tab or a TUI (the
|
|
40
|
+
new model has no cache of the conversation): the reply names the size it rereads and the line that applies it,
|
|
41
|
+
flags and all (`/model qwen --default --yes`); `--yes` (or `-y`) applies at once, and a typo is an error before any
|
|
42
|
+
question. `chi send`, delegates and `chi --model` on an attached or resumed session apply at once.
|
|
43
|
+
- `/llm-context` asks the same way before the two changes that break the prompt cache now: `forget` turned on or off,
|
|
44
|
+
and a layer with applied stubs turned off (`/llm-context reset --yes` applies too). Turning `stale` on, the apply
|
|
45
|
+
rule and the budget don't ask; the web's `llm ctx` chip and `chi --llm-context` on an attached or resumed session
|
|
46
|
+
apply at once.
|
|
47
|
+
|
|
48
|
+
Update with `chi update`, then restart `chi web` and the session workers (`chi sessions restart`): a new TUI's
|
|
49
|
+
`--model X` on a worker from before this release switches it to the model "X --yes".
|
|
50
|
+
|
|
10
51
|
## [0.131.0] - 2026-10-29
|
|
11
52
|
|
|
12
53
|
### Changed
|
|
13
54
|
|
|
55
|
+
- Web: the start page's composer row stays one row at any width: a long model name ellipsizes instead of pushing
|
|
56
|
+
Start to a second row.
|
|
57
|
+
- Web: the start page's model button shows a short name (`openrouter · deepseek-v4.1-flash`: no org prefix, the tag
|
|
58
|
+
kept, the host only when it isn't the default); its tooltip and label keep the full name.
|
|
14
59
|
- Cache: confirmations for prompt-cache changes estimate the reread size when known and warn that Anthropic drops
|
|
15
60
|
preserved thinking after a full-prefix change.
|
|
16
61
|
|
|
@@ -4992,7 +5037,8 @@ and long-lived sessions.
|
|
|
4992
5037
|
- A macOS desktop helper (`chi desktop install`): a "Send to chi" Service and a
|
|
4993
5038
|
hotkey panel that send selected text or the clipboard to your sessions.
|
|
4994
5039
|
|
|
4995
|
-
[Unreleased]: https://github.com/dm1try/samagotchi/compare/v0.
|
|
5040
|
+
[Unreleased]: https://github.com/dm1try/samagotchi/compare/v0.132.0...HEAD
|
|
5041
|
+
[0.132.0]: https://github.com/dm1try/samagotchi/compare/v0.131.0...v0.132.0
|
|
4996
5042
|
[0.131.0]: https://github.com/dm1try/samagotchi/compare/v0.130.1...v0.131.0
|
|
4997
5043
|
[0.130.1]: https://github.com/dm1try/samagotchi/compare/v0.130.0...v0.130.1
|
|
4998
5044
|
[0.130.0]: https://github.com/dm1try/samagotchi/compare/v0.129.0...v0.130.0
|
data/bin/chi
CHANGED
|
@@ -82,7 +82,9 @@ SUBCOMMANDS = {
|
|
|
82
82
|
# audit suggestions for which toolkit fits a session's first prompt
|
|
83
83
|
"toolkit" => ["samagotchi/toolkit_report_command", "ToolkitReportCommand"],
|
|
84
84
|
# other machines' chi web, for chi --remote NAME (add, ls, rm)
|
|
85
|
-
"remote" => ["samagotchi/remote_command", "RemoteCommand"]
|
|
85
|
+
"remote" => ["samagotchi/remote_command", "RemoteCommand"],
|
|
86
|
+
# the chi home: the Ruby every chi launch boots (set, doctor)
|
|
87
|
+
"home" => ["samagotchi/home_command", "HomeCommand"]
|
|
86
88
|
}.freeze
|
|
87
89
|
# chi --remote NAME <command> (or CHI_REMOTE=NAME): the session commands
|
|
88
90
|
# against another machine's chi web; what runs here only is refused (exit 2).
|
data/docs/architecture.md
CHANGED
|
@@ -133,6 +133,36 @@ terminal renders the events it gets over the Bridge.
|
|
|
133
133
|
- In REPL mode `TerminalUI` builds the `Engine` in process (`-p` and `--non-interactive` too);
|
|
134
134
|
otherwise the session's `Worker` (`lib/samagotchi/worker.rb`, spawned by `SessionManager`) builds it.
|
|
135
135
|
|
|
136
|
+
## How chi launches itself
|
|
137
|
+
|
|
138
|
+
chi starts chi in several places, and each must land on the same install whoever starts it (a terminal on another
|
|
139
|
+
Ruby, chi web, the macOS helper under launchd). The **chi home** (`ChiHome`, `chi_home.rb`; recorded in
|
|
140
|
+
`$XDG_CONFIG_HOME/samagotchi/home.json` by `chi home set`, or once by `chi bootstrap` / `chi update`:
|
|
141
|
+
[configuration.md](configuration.md#the-chi-home)) names that install: a Ruby and its gem path.
|
|
142
|
+
|
|
143
|
+
**One mechanism.** `ChiHome::Record#boot_argv(run:)` is `[home ruby, "-e", "Gem.paths = {'GEM_HOME' => …,
|
|
144
|
+
'GEM_PATH' => …}; <run>"]`: the gem path goes into the boot string, never into an environment, so the tools a worker
|
|
145
|
+
runs keep the spawner's GEM_HOME/GEM_PATH (or none), and a stray one in the spawner's env can't move chi off the
|
|
146
|
+
home. `ChiHome::CHI_BOOT` (`gem 'samagotchi', '>= 0.a'; load Gem.bin_path('samagotchi', 'chi')`) plus `"--"` and
|
|
147
|
+
the arguments runs the home's newest `chi`. Each site asks `ChiHome.current` at launch time; it is nil (and the site
|
|
148
|
+
keeps its own argv, as before the home) without home.json, for one that isn't its shape (warned once), when the
|
|
149
|
+
home's Ruby is gone, when no `samagotchi-*.gemspec` is under its gem path, and from a source checkout.
|
|
150
|
+
|
|
151
|
+
| Site | With a home | Without |
|
|
152
|
+
|---|---|---|
|
|
153
|
+
| `SessionManager.worker_command`: every worker (attach, `chi send`, chi web, delegate and Verify-fresh children, `resume_session`, `:restart`) | the home's ruby, `Gem.paths`, `>= 0.a` with the fallback pin (`ChiHome.fallback_version`: the spawner's version when the home has it, else the home's newest; a home older than the spawner is warned once); a chi that still can't load writes one `boot_failed` line to `SAMAGOTCHI_LOG_FILE` and exits 1 | `RbConfig.ruby -e` with `>= 0.a` (a checkout: `-I lib`) |
|
|
154
|
+
| `Web::Server.reexec_command` (chi web's restart) | `CHI_BOOT -- web …`; the `:no_wrapper` refusal never applies; a home whose newest chi is older than this one is passed over (logged `restart_home_older`) | `[RbConfig.ruby, wrapper, …]` (`$PROGRAM_NAME` in a checkout) |
|
|
155
|
+
| `Web::App#update_argv` (the **Update** button's child) | `CHI_BOOT -- update --to V --no-desktop --json` | `[RbConfig.ruby, wrapper, update, …]` |
|
|
156
|
+
| `UpdateCommand` | on another Ruby than the home (`Record#running_here?`): exec `CHI_BOOT -- update …` once (`SAMAGOTCHI_UPDATE_IN_HOME=1`: an older home chi ignores it); the install (`GemUpdate`) runs `ChiHome.gem_bin` with `ChiHome.install_env` (the home's GEM_HOME/GEM_PATH for that child, `mise`'s dir on PATH); the hand-over execs `CHI_BOOT -- update --no-gem --gem-from …` | this Ruby's `gem`, the wrapper |
|
|
157
|
+
| `BootstrapCommand` (commonmarker) | `ChiHome.gem_bin` + `install_env`; installed? = in the home's specifications | this Ruby's `gem` |
|
|
158
|
+
| `Desktop::MacOS#launch_config` | argv `CHI_BOOT + ["--"]`; `launch_ok?` / `launch_problem` check only absolute argv entries | `[ruby, wrapper or bin/chi]` |
|
|
159
|
+
| `InstalledVersions`, `Web::UpdateCheck` | the home's specification dirs and gem dir | the running process's |
|
|
160
|
+
|
|
161
|
+
Unchanged: `ContextProviders`' `{ruby}` (`RbConfig.ruby`: the home's ruby inside a home worker), `chi bundle
|
|
162
|
+
try/test/check` (`-I LIB_DIR`), hooks (in-process). The worker's boot string, `run_session_loop(id, state_dir:)` and
|
|
163
|
+
`SAMAGOTCHI_BOOT_FALLBACK` stay the cross-version contract (`spec/worker_contract_spec.rb`): the home only adds the
|
|
164
|
+
prelude in front. An older chi that wakes a session doesn't read home.json and starts its worker as before.
|
|
165
|
+
|
|
136
166
|
## Session retention & ordering
|
|
137
167
|
|
|
138
168
|
- **Files:** `~/.local/state/samagotchi/sessions/<uuid>.json` + `<uuid>/input|output|owner.lock|bridge.json` (XDG-aware), and the `<uuid>/stopped` and `<uuid>/archived` marker files.
|
|
@@ -227,7 +257,8 @@ The system prompt (`SystemPrompt#build`, assembled in `#system_prompt_with_index
|
|
|
227
257
|
base prompt, then the toolkit's "Not loaded in this session" line (only when the toolkit
|
|
228
258
|
leaves tools out), rg guidance, the identity, the model notes, the preloaded memories,
|
|
229
259
|
AGENTS.md (root → cwd), the appended files (`--append-system-prompt`), the toolkit's
|
|
230
|
-
kit prompt (a kit's `prompt:` text, only when it has one), the
|
|
260
|
+
kit prompt (a kit's `prompt:` text, only when it has one), the plugins' prompt
|
|
261
|
+
sections (`chi.prompt_section`, only when a plugin gives text), the memory
|
|
231
262
|
indexes, and last **the model** (`Model: this session runs on <ref> (host …; model key …)` and a line telling
|
|
232
263
|
the model to answer "which model are you" from it, not from training), the working
|
|
233
264
|
directory and the session id and log (Gemma's native tool declarations still follow).
|
data/docs/cli.md
CHANGED
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
- `chi models [--format text|json] [--timeout S] [TEXT]` — list the models every configured host offers, as the names `--model` takes (see [Listing the models](#listing-the-models))
|
|
36
36
|
- `chi self` — print version, source dir (checkout or installed gem), config/memory/session paths, model/host and bundles. Run by a session's `execute`, the `model` row (and host, loop, profile, thinking, served model) is **that session's** model, labelled `(this session <id8>; default …)`; elsewhere it is the default, `(default)`. `model key` is the memory overlay key (`<name>.<key>.md`), and `model notes` the model notes a prompt of that model loads (`model_notes_deepseek (system, 612 chars)`, `none`; inside a session its `--mute` list is left out). `chi self --model` prints only the model a new session starts on, an alias resolved to its target (the desktop helper's hint)
|
|
37
37
|
- `chi update [--dry-run] [--to VERSION] [--json] [--no-gem] [--no-bundles] [--no-desktop]` — update an installed chi: the gem, the system bundle, the shipped bundles you installed and the desktop helper, in one table (see [Updating](#updating))
|
|
38
|
+
- `chi home`, `chi home set [--ruby PATH]`, `chi home doctor` — the chi home: the one Ruby (and its gem path) every chi launch boots, whoever launches it. `chi home` shows it (its Ruby, the newest chi in it, gem home and path, `mise`, when and by which chi it was set, and the chi you ran when that is another one; exit 1 with the problem when it can't boot chi), `set` records this chi's Ruby and gem path (or `--ruby PATH`'s own; it must have samagotchi), `doctor` checks it (for now: its Ruby is there and has samagotchi; exit 1 says what to do). This machine only (see [The chi home](configuration.md#the-chi-home))
|
|
38
39
|
- `chi bundle install|upgrade|uninstall|status|diff|list|build|trash|new|test|check` — manage memory bundles (see [Bundle hooks](hooks.md#bundle-hooks-unified-workflow-bundle)); `list` shows the installed ones and the ones shipped with chi, which `install <name>` installs; `core` and `dev` are profiles that install a set of them (see [Bundle profiles](memory.md#bundle-profiles-core-and-dev), [Guardrails](guardrails.md), [Plugins](plugins.md#the-btw-bundle), [the mcp bundle](plugins.md#the-mcp-bundle) [the loop-guard bundle](plugins.md#the-loop-guard-bundle), [the check-in bundle](plugins.md#the-check-in-bundle) and [the skills bundle](plugins.md#the-skills-bundle)). `trash` lists and empties the bundle trash (moved files from uninstalls/upgrades). A usage error (an unknown subcommand or flag, a missing argument, a bad `build --scope`) exits 2, as for the other subcommands. Plain `chi` and `chi web` exit 1 on an unknown flag, a flag missing its value or a stray argument. `new`, `test` and `check` are for writing one: see [Writing a bundle](#writing-a-bundle-new-test-check)
|
|
39
40
|
|
|
40
41
|
- `chi guardrails replay [--dry-run] [--threshold T] [--model M]` — seed System 1's record from the approvals this machine's sessions already answered: each ask is judged by the configured model and written to `guardrails/judgments.jsonl` with the answer the user gave, then a per-rule table prints (asks, allowed, denied, would-be auto-allows, false allows, asks with no judgment). A parent agent's answer is not the user's: only its deny is replayed, and only where the parent could have allowed. `--dry-run` judges without writing, `--threshold` overrides `guardrails.system_one.threshold` for the table, `--model` the configured model for this run. Exit 2 when `guardrails.system_one.mode` is off or no `host` is set; a usage error exits 2 (see [System 1](guardrails.md#system-1-experimental))
|
|
@@ -257,11 +258,22 @@ done
|
|
|
257
258
|
[configuration](configuration.md#all-settings)). If the gem can't be updated
|
|
258
259
|
in place, the notice gives the blocker and its command instead.
|
|
259
260
|
|
|
261
|
+
- **The chi home.** With a [chi home](configuration.md#the-chi-home), a `chi
|
|
262
|
+
update` started on another Ruby first says `updating the chi home (<ruby>)`
|
|
263
|
+
and runs the home's chi update instead (the version check, `--to` and the
|
|
264
|
+
rows are the home's); chi web's **Update** runs the home's too. Without
|
|
265
|
+
one, the first `chi update` (not `--dry-run`, not under Bundler, and only
|
|
266
|
+
once its own checks passed) records one: of the desktop helper's Ruby and
|
|
267
|
+
the Ruby it runs on, the one with the newer chi, and says `chi home set to
|
|
268
|
+
<ruby> (chi home set to change)`.
|
|
260
269
|
- **The gem.** It asks rubygems.org for the newest samagotchi (5 s timeout)
|
|
261
270
|
and, when that's newer, runs `gem install samagotchi` with the gem command
|
|
262
|
-
of the
|
|
263
|
-
|
|
264
|
-
|
|
271
|
+
of the chi home's Ruby, into the home's gems (`GEM_HOME`/`GEM_PATH` set to
|
|
272
|
+
the home's for that one command, and `mise`'s folder on its PATH when the
|
|
273
|
+
home names one, for mise's reshim plugin); without a home, the Ruby chi runs
|
|
274
|
+
on (the real one, not a mise/rbenv/asdf shim; a chi installed under another
|
|
275
|
+
Ruby is a separate install it doesn't touch). Then it hands over to the new
|
|
276
|
+
chi, which does the rest and prints the table. Old
|
|
265
277
|
versions stay installed: running workers and an old `chi web` still load
|
|
266
278
|
files from them, so a `gem cleanup` while they run breaks them (a
|
|
267
279
|
`LoadError`, missing web assets); restart them first. A chi web, an
|
|
@@ -293,7 +305,9 @@ done
|
|
|
293
305
|
sources changed; otherwise only its launch file is refreshed (a newer chi or
|
|
294
306
|
other terminal settings). It keeps the Ruby, chi and PATH the helper runs (a
|
|
295
307
|
PATH is filled in only when the file has none): `chi desktop install --force`
|
|
296
|
-
and `chi desktop upgrade` bake this shell's
|
|
308
|
+
and `chi desktop upgrade` bake this shell's (the chi home's boot, when there
|
|
309
|
+
is one). A refresh drops `RUBYLIB` from the launch file, and `GEM_HOME`/`GEM_PATH`
|
|
310
|
+
once it boots the chi home. A helper whose Ruby or chi is gone
|
|
297
311
|
is reported as failed, naming `chi desktop install --force`. See
|
|
298
312
|
[Desktop helper](desktop.md).
|
|
299
313
|
- **Running processes** are reported, never stopped. A live worker keeps its
|
|
@@ -689,11 +703,14 @@ saved with the session and applies from the next turn's start; the reply says
|
|
|
689
703
|
what it costs: `forget` on or off re-reads the whole prompt once, `stale` turned
|
|
690
704
|
on stages the reads already superseded as one batch under the apply rule, and a
|
|
691
705
|
layer turned off sends its stubs whole again (turning it back on brings them
|
|
692
|
-
back).
|
|
706
|
+
back). Once the session has a model reply, the two that break the cache now
|
|
707
|
+
(`forget` on or off, a layer with applied stubs turned off) ask first and name
|
|
708
|
+
the `--yes` line that applies them; `/llm-context reset --yes` works too.
|
|
709
|
+
`/llm-context` alone answers mid-turn too; a change sent while a turn runs
|
|
693
710
|
waits for the turn's end (see *Typing during a turn*). `/stats` shows
|
|
694
711
|
the same values on its `llm context:` line. The web's info bar shows them as the
|
|
695
712
|
`llm ctx` chip (`llm ctx stale,forget · session`), whose popover sets them
|
|
696
|
-
through `/llm-context
|
|
713
|
+
through `/llm-context … --yes` (its form says what a change costs). See "LLM context: a session's own strategy" in
|
|
697
714
|
[configuration.md](configuration.md).
|
|
698
715
|
|
|
699
716
|
`/working-set` lists the session's working set as the model has it (see [The
|
|
@@ -801,9 +818,9 @@ mid-turn too, and the lists, cards, top bar and tab show it in place of the firs
|
|
|
801
818
|
message; a continue's next link keeps it. In the web, `✎` next to the session's
|
|
802
819
|
title (its strip card, or the top bar) does it. See [Session titles](sessions.md#session-titles).
|
|
803
820
|
|
|
804
|
-
A `/thinking`, `/reasoning-history` or `/toolkit` change that restarts the prompt cache
|
|
821
|
+
A `/model`, `/llm-context`, `/thinking`, `/reasoning-history` or `/toolkit` change that restarts the prompt cache
|
|
805
822
|
asks first: the reply says what it costs, changes nothing, and names the line
|
|
806
|
-
that applies it (`/thinking low --yes`). `--yes` (or `-y`) applies it at once.
|
|
823
|
+
that applies it (`/thinking low --yes`, `/model qwen --default --yes`). `--yes` (or `-y`) applies it at once.
|
|
807
824
|
The terminal puts that line in the next input (Enter applies it); the web's
|
|
808
825
|
reply has an Apply button. `chi send ID "/thinking low"`,
|
|
809
826
|
`chi -p "/thinking low" --non-interactive` and lines piped into the REPL apply
|
|
@@ -1596,6 +1613,10 @@ In interactive assist mode, you can switch the request model without restarting:
|
|
|
1596
1613
|
- `/model <name> --alias <alias>`: create alias for current effective model (alias value may be bare or `host:model`).
|
|
1597
1614
|
- `/model`: show the effective model (and default when diverged: `runtime model: <effective> (default: <default>, profile=<name>, <source>)`, e.g. `profile=qwen36, server (chat_template)`). When the session's prompt carries model notes the line ends with `; notes: model_notes_deepseek (system, 612 chars)`; a switch's `runtime model set to …` names the new model's ([Memory](memory.md#model-notes)).
|
|
1598
1615
|
- `/model clear` (or `default`/`none`/`off`): clear the session override, reverting to the configured default.
|
|
1616
|
+
- Once the session has a model reply, a switch to another model asks first from a web tab or a TUI (the new model
|
|
1617
|
+
has no cache of the conversation): the reply names the line with `--yes` that applies it, flags and all
|
|
1618
|
+
(`/model qwen --alias q --yes`); `--yes` (or `-y`) applies at once. A typo (an unknown host, a bad alias) is an
|
|
1619
|
+
error before any question. See "Changes that restart the prompt cache" in [configuration.md](configuration.md).
|
|
1599
1620
|
- `/guardrails`: the guardrail rules (by source), what failed to load, your stored approvals, and System 1's
|
|
1600
1621
|
recent auto-allows; `/guardrails revoke N` removes approval N and `/guardrails wrong [N]` flags an auto-allow
|
|
1601
1622
|
this session should have been asked about (see [Guardrails](guardrails.md)).
|
data/docs/configuration.md
CHANGED
|
@@ -833,10 +833,14 @@ models:
|
|
|
833
833
|
|
|
834
834
|
## Changes that restart the prompt cache
|
|
835
835
|
|
|
836
|
-
`/thinking`, `/reasoning-history` and `/toolkit` ask before a change that makes the server
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
836
|
+
`/model`, `/llm-context`, `/thinking`, `/reasoning-history` and `/toolkit` ask before a change that makes the server
|
|
837
|
+
read the conversation again: a switch to another model (a plain name, `--default`, `--alias N`, `clear`; the new model
|
|
838
|
+
has no cache of the conversation), `forget` turned on or off and a layer with applied stubs turned off ("LLM context:
|
|
839
|
+
a session's own strategy"), Gemma's thinking switch, a remote chat host's thinking fields ("Thinking"), a change to or
|
|
840
|
+
from `all` once an earlier reply has thinking ("Reasoning history"), and any change to the declared tools, which start
|
|
841
|
+
every request ("Toolkits"). They ask only when what the next turn runs under really changes (`/model` naming the model
|
|
842
|
+
it already runs, by its resolved ref, doesn't ask) and the session has a model reply. A `/model` name is checked
|
|
843
|
+
first: an unknown host or a bad alias is an error at once, not a question.
|
|
840
844
|
|
|
841
845
|
- The reply says what it costs and changes nothing yet. When known, it estimates the reread size: the whole
|
|
842
846
|
conversation for full-prefix changes, or from the first changed reply for reasoning history. On `api: anthropic`,
|
|
@@ -849,8 +853,9 @@ reply has thinking ("Reasoning history"), and any change to the declared tools,
|
|
|
849
853
|
the button is gone after a reload.
|
|
850
854
|
- Only a person at a web tab or a chi TUI is asked. `chi send ID "/thinking low"`,
|
|
851
855
|
`chi -p "/thinking low" --non-interactive`, lines piped into the REPL, a delegate, a plugin and a card's action
|
|
852
|
-
apply directly, since nobody would see the question; so do the start flags (`chi --thinking`
|
|
853
|
-
attached session
|
|
856
|
+
apply directly, since nobody would see the question; so do the start flags (`chi --thinking`, `--model` and
|
|
857
|
+
`--llm-context` on a resumed or attached session send `/thinking LEVEL --yes`, `/model NAME --yes` and
|
|
858
|
+
`/llm-context … --yes`). A plain `chi -p` opens the REPL, which asks.
|
|
854
859
|
|
|
855
860
|
## Llama HTTP Timeouts
|
|
856
861
|
|
|
@@ -1347,6 +1352,51 @@ The helper reads these from its launch file: after editing them run
|
|
|
1347
1352
|
(`$TMUX_TMPDIR/tmux-<uid>`, else `/tmp/tmux-<uid>`) are resolved then and
|
|
1348
1353
|
frozen in it. See [Desktop helper](desktop.md#agents-in-kitty-and-tmux).
|
|
1349
1354
|
|
|
1355
|
+
## The chi home
|
|
1356
|
+
|
|
1357
|
+
With several Rubies on one machine (mise, rbenv, chruby; a project that pins its own), whichever Ruby started chi
|
|
1358
|
+
used to decide which chi ran: a terminal in a project on Ruby 3.4 woke its session's worker on that Ruby's chi (an
|
|
1359
|
+
older one, or none), chi web's restart could fall off onto another install, and the macOS helper ran the Ruby of the
|
|
1360
|
+
shell it was installed from. The **chi home** is the one Ruby, and its gem path, every chi launch boots, whoever
|
|
1361
|
+
launches it. It is recorded in `~/.config/samagotchi/home.json` (`$XDG_CONFIG_HOME` is honoured):
|
|
1362
|
+
|
|
1363
|
+
```json
|
|
1364
|
+
{
|
|
1365
|
+
"ruby": "/Users/me/.local/share/mise/installs/ruby/4.0.7/bin/ruby",
|
|
1366
|
+
"gem_home": "/Users/me/.local/share/mise/installs/ruby/4.0.7/lib/ruby/gems/4.0.0",
|
|
1367
|
+
"gem_path": "/Users/me/.gem/ruby/4.0.0:/Users/me/.local/share/mise/installs/ruby/4.0.7/lib/ruby/gems/4.0.0",
|
|
1368
|
+
"mise": "/opt/homebrew/bin/mise",
|
|
1369
|
+
"set_at": "2026-10-29T21:00:00Z",
|
|
1370
|
+
"set_by_version": "0.132.0"
|
|
1371
|
+
}
|
|
1372
|
+
```
|
|
1373
|
+
|
|
1374
|
+
- **Setting it.** `chi home set` records the Ruby your `chi` runs on and its gem path (a chruby shell's
|
|
1375
|
+
`GEM_HOME`/`GEM_PATH` are part of it: that is where its chi lives); `chi home set --ruby PATH` records another
|
|
1376
|
+
Ruby with its own gem dirs. Either needs samagotchi installed there (`gem install samagotchi` with that Ruby
|
|
1377
|
+
first). Without a home.json, the first `chi bootstrap` or `chi update` records one, once (from an installed chi,
|
|
1378
|
+
never under `bundle exec`): of the desktop helper's Ruby (when its newest chi is at least the one running) and the
|
|
1379
|
+
Ruby chi runs on, the one with the newer chi. Nothing else ever overwrites it.
|
|
1380
|
+
`chi home` shows it; `chi home doctor` checks it (see [CLI](cli.md#commands)).
|
|
1381
|
+
- **What follows it.** Every session worker (whoever starts or wakes it: a terminal, `chi send`, chi web, a
|
|
1382
|
+
delegating session, a restart), chi web's restart and its **Update** button, `chi update` (from another Ruby it
|
|
1383
|
+
runs the home's `chi update`, and installs into the home's gems with the home's `gem`), `chi bootstrap`'s
|
|
1384
|
+
commonmarker install, chi web's "installed; restart" notice and the macOS helper after its next `chi desktop
|
|
1385
|
+
install` or `upgrade`. The boot sets the home's gem path inside Ruby (`Gem.paths`), never in an environment
|
|
1386
|
+
variable: the commands a session runs (`execute`, tasks, `!cmd`, MCP servers) keep the GEM_HOME/GEM_PATH of whoever
|
|
1387
|
+
started the worker, or none. How: [How chi launches itself](architecture.md#how-chi-launches-itself).
|
|
1388
|
+
- **No home, or one that can't boot chi** (its Ruby gone after a Ruby upgrade, samagotchi uninstalled there, a
|
|
1389
|
+
home.json that isn't JSON): each launch uses the Ruby that starts it, as without a home, and the log says why once
|
|
1390
|
+
per process (`home_unusable`, `home_invalid`). After a Ruby upgrade: `gem install samagotchi` with the new Ruby,
|
|
1391
|
+
then `chi home set` from it. A source checkout (`bin/chi`, `bundle exec`) never uses the home: a worktree's
|
|
1392
|
+
`bin/chi` starts its own code.
|
|
1393
|
+
- **A home with an older chi than the one launching**: workers still boot the home (the log says so once,
|
|
1394
|
+
`home_older_than_spawner`), but chi web's restart runs the newest chi it knows outside the home instead
|
|
1395
|
+
(`restart_home_older`): its flags may be ones the older chi doesn't know.
|
|
1396
|
+
- **A home that still fails at boot** (a broken install): the worker writes one `boot_failed` line to the debug log
|
|
1397
|
+
(`log.file`) and exits, rather than leave the spawner waiting.
|
|
1398
|
+
- Each machine has its own home (a remote's is that machine's).
|
|
1399
|
+
|
|
1350
1400
|
## Project specific description
|
|
1351
1401
|
|
|
1352
1402
|
If an AGENTS.md file is present in the project root, samagotchi injects its
|
|
@@ -1641,6 +1691,12 @@ its own). The first target is a long session such as a day-long coordinator, whe
|
|
|
1641
1691
|
and their results stay in the history.
|
|
1642
1692
|
- **Switching a layer off:** its stubs go out whole again from the next request (a cache break from the first). The
|
|
1643
1693
|
session keeps the originals and the edits, so turning the layer back on brings the same stubs back.
|
|
1694
|
+
- **Asks first:** once the session has a model reply, `/llm-context` from a web tab or a TUI asks before the two that
|
|
1695
|
+
break the cache now: `forget` on or off, and a layer with applied stubs turned off (the reply names the
|
|
1696
|
+
`/llm-context … --yes` line; "Changes that restart the prompt cache"). Turning `stale` on, the apply rule and the
|
|
1697
|
+
budget don't ask: they only decide when a batch goes in, and each batch's break comes as designed (`next_request`
|
|
1698
|
+
with staged edits pending moves a break the old rule makes by the end of the next turn anyway). The chip's Set and
|
|
1699
|
+
`--llm-context` on an attached or resumed session send `--yes`.
|
|
1644
1700
|
- **Where to see it:** `/llm-context` (each value and where it came from: `the session`, `models: <key>`,
|
|
1645
1701
|
`hosts entry '<name>'`, `llm_context.*`), `/stats` (`llm context:`), the turn log (an `llm_context` record per
|
|
1646
1702
|
turn that runs a layer or whose session set its strategy) and the web's chip. A woken worker's status line counts
|
data/docs/desktop.md
CHANGED
|
@@ -257,7 +257,9 @@ don't break it. From a checkout it runs **that** checkout's `bin/chi`; installin
|
|
|
257
257
|
warning, because the helper stops working once that worktree is removed. After switching between a checkout and a
|
|
258
258
|
gem install, run `chi desktop upgrade` from the one you now use.
|
|
259
259
|
|
|
260
|
-
|
|
260
|
+
With a [chi home](configuration.md#the-chi-home), `chi desktop install` and `upgrade` make the helper boot the home
|
|
261
|
+
(its Ruby, the newest chi in its gems) whatever shell you run them from. Without one, the helper runs the Ruby and
|
|
262
|
+
chi of **the shell you installed from**, and only `chi desktop install --force` and
|
|
261
263
|
`chi desktop upgrade` change that: they pick the Ruby and chi of the shell you run them in. `chi update` never
|
|
262
264
|
repoints it, so running it from a project with another Ruby (or an older chi) leaves the helper where it was. If
|
|
263
265
|
the Ruby or chi the helper runs is gone (a Ruby upgrade, a removed worktree), `chi update` fails the helper's row
|
|
@@ -286,12 +288,19 @@ says the same.
|
|
|
286
288
|
Apps started by macOS get a bare environment: no shell rc files, so no rbenv/chruby/mise/asdf and none of your
|
|
287
289
|
exports. So `install` writes `~/Library/Application Support/Chi Helper/launch.json` with:
|
|
288
290
|
|
|
289
|
-
-
|
|
290
|
-
the
|
|
291
|
+
- what to run, as of the last `chi desktop install` or `upgrade` (`chi update` keeps it): with a
|
|
292
|
+
[chi home](configuration.md#the-chi-home), the home's boot, `["<home ruby>", "-e", "Gem.paths = {…}; gem
|
|
293
|
+
'samagotchi', '>= 0.a'; load Gem.bin_path('samagotchi', 'chi')", "--"]` (the helper appends its own arguments
|
|
294
|
+
after `--`); without one, the absolute path of the Ruby running chi and of chi itself (the gem's wrapper, or a
|
|
295
|
+
checkout's `bin/chi`). The helper and `chi update` check only the absolute paths in it;
|
|
291
296
|
- `LANG=en_US.UTF-8`;
|
|
292
|
-
- only these variables, and only when they are set: `XDG_CONFIG_HOME`, `XDG_STATE_HOME
|
|
293
|
-
|
|
294
|
-
|
|
297
|
+
- only these variables, and only when they are set: `XDG_CONFIG_HOME`, `XDG_STATE_HOME` (a relative one made
|
|
298
|
+
absolute from the install's current folder: the helper starts in `/`). No tokens and no `SAMAGOTCHI_*` settings
|
|
299
|
+
go in, and never `RUBYLIB`. `GEM_HOME` and `GEM_PATH` go in only without a chi home (a `[ruby, chi]` launch,
|
|
300
|
+
whose chi may be found only through them, as under chruby): the home's boot sets its gem path itself, and they
|
|
301
|
+
would reach every command the helper's sessions run (a project's `bundle exec` on the wrong gems). A launch file
|
|
302
|
+
from an older chi loses `RUBYLIB` at the next `chi update`, and `GEM_HOME`/`GEM_PATH` once it boots the chi home
|
|
303
|
+
(`chi desktop upgrade` moves it to the home);
|
|
295
304
|
- `PATH`: the shell's PATH when the file is written, with only absolute folders, in order, each once. The helper's
|
|
296
305
|
chi, the sessions it starts and their `execute` commands can find the tools your terminal finds (mise, Homebrew,
|
|
297
306
|
`codex`, `node`);
|
data/docs/guardrails.md
CHANGED
|
@@ -4,7 +4,7 @@ Every tool call the model makes passes one check before it runs, in both
|
|
|
4
4
|
loops (native and chat hosts). The verdict is **allow**, **ask** or
|
|
5
5
|
**deny**; the strictest vote wins, and a deny can't be undone by a later
|
|
6
6
|
voter. Of two asks the first one names the rule, except a rule only the
|
|
7
|
-
user may allow (`chi-config`, `chi-hooks`, `shell-touches-chi`,
|
|
7
|
+
user may allow (`chi-config`, `chi-home`, `chi-hooks`, `shell-touches-chi`,
|
|
8
8
|
`chi-context-cmd`, `chi-broadcast`): it takes over, and only the scopes both asks offer
|
|
9
9
|
are offered.
|
|
10
10
|
|
|
@@ -215,7 +215,7 @@ rules off: `guardrails: {disable: [write-outside-repo, git-outside-repo]}`.
|
|
|
215
215
|
|
|
216
216
|
Whatever the setting, a parent can't allow a call on chi's own files: a
|
|
217
217
|
`write`, `edit` or `execute` on the config dir (config.yml, installed bundles'
|
|
218
|
-
rules), the hooks dir or the approval store, by its rule (`chi-config`,
|
|
218
|
+
rules), the hooks dir or the approval store, by its rule (`chi-config`, `chi-home`,
|
|
219
219
|
`chi-hooks`, `shell-touches-chi`), its paths or its command. "Allow once" on a
|
|
220
220
|
config.yml rewrite would allow everything from then on, so those questions are
|
|
221
221
|
the user's alone (`user_only`): `chi answer` and the worker refuse the allow
|
|
@@ -280,7 +280,7 @@ Built in, for `write`, `edit` and `memory_write` (symlinks resolved; see
|
|
|
280
280
|
- deny: the approval store's dir, installed bundles (`memories/.bundles/`),
|
|
281
281
|
and [attached context](context.md) sources (`<state dir>/context/`: a
|
|
282
282
|
source's command runs later, outside the gate; `chi context` changes them);
|
|
283
|
-
- ask (once or for the session): `config.yml` and the plain hooks dir.
|
|
283
|
+
- ask (once or for the session): `config.yml`, `home.json` (the [chi home](configuration.md#the-chi-home): the Ruby every chi launch boots) and the plain hooks dir.
|
|
284
284
|
|
|
285
285
|
`execute` can still reach them; the guardrails bundle asks about shell
|
|
286
286
|
commands that name them.
|
data/docs/internals/anthropic.md
CHANGED
|
@@ -133,8 +133,9 @@ append-only within a process, so what changes the prefix is:
|
|
|
133
133
|
1. **A system-prompt rebuild** (`SystemPrompt#build` is cached per process and key; `SystemPrompt#reset!` drops it):
|
|
134
134
|
a new process (`--resume`, a respawn after `session.idle_exit_minutes`, a crash) after a memory index line, an
|
|
135
135
|
AGENTS.md, an appended file, a model note or a bundle memory changed; `/model` (the tail's `Model:` line, its
|
|
136
|
-
overlays and notes); `/thinking` (another key); a toolkit or profile change; a plugin's `tools_changed
|
|
137
|
-
session's first participant joining or last
|
|
136
|
+
overlays and notes); `/thinking` (another key); a toolkit or profile change; a plugin's `tools_changed!` or
|
|
137
|
+
`prompt_changed!` (its prompt section's text, plugins.md); the session's first participant joining or last
|
|
138
|
+
leaving (the tail's participants line, participants.md).
|
|
138
139
|
2. **A tool set change**: the same triggers, plus MCP lines that differ on a respawn.
|
|
139
140
|
3. **History edits by design**: the `llm_context` `stale`/`forget` stubs, and the image cut moving a batch.
|
|
140
141
|
|
data/docs/internals/engine.md
CHANGED
|
@@ -832,10 +832,10 @@ answer is stripped from prefill + response, so the reasoning never lands in it).
|
|
|
832
832
|
persistent.
|
|
833
833
|
5. **A stable system prompt for the cache.** `SystemPrompt#build` caches the prompt per Engine, keyed by
|
|
834
834
|
`[chat, thinking, layers]` (chat/native, the thinking level, the turn's LLM context layers), and is reset
|
|
835
|
-
only on a model switch, a tools change, a
|
|
836
|
-
stable part (base prompt, the toolkit's not-loaded line,
|
|
837
|
-
AGENTS.md, appended files, the toolkit's kit prompt,
|
|
838
|
-
working directory, session).
|
|
835
|
+
only on a model switch, a tools change, a plugin's `prompt_changed!` (`Engine#prompt_changed!`), a profile
|
|
836
|
+
change or a toolkit change (`Engine#apply_toolkit!`). The stable part (base prompt, the toolkit's not-loaded line,
|
|
837
|
+
rg guidance, identity, model notes, preloaded memories, AGENTS.md, appended files, the toolkit's kit prompt, the
|
|
838
|
+
plugins' prompt sections, memory indexes) comes before the volatile tail (model, working directory, session).
|
|
839
839
|
prompt-caching.md covers this in detail.
|
|
840
840
|
|
|
841
841
|
## Key files
|
|
@@ -40,6 +40,7 @@ right-hand column happens.
|
|
|
40
40
|
│ AGENTS.md (root → cwd) │ (picked up by a new
|
|
41
41
|
│ appended files (append_system_prompt:, --append-system-prompt) │ process or a rebuild)
|
|
42
42
|
│ kit prompt (per toolkit: its kit's prompt: text, only when it has one) │
|
|
43
|
+
│ plugin prompt sections (chi.prompt_section, by (bundle, name)) │ chi.prompt_changed!
|
|
43
44
|
│ project + system memory indexes │
|
|
44
45
|
│ ◄── remote Claude / Messages: cache_control breakpoint #1 │
|
|
45
46
|
├──────────────────────────────────────────────────────────────────────────┤
|
|
@@ -65,8 +66,8 @@ right-hand column happens.
|
|
|
65
66
|
- The system prompt is built **once per key** and kept (`SystemPrompt#build`, keyed by `[chat, thinking, layers]`:
|
|
66
67
|
the loop, the thinking level, the turn's LLM context layers; a `/thinking` change builds under another key). All
|
|
67
68
|
of them are dropped only on `@prompt_builder.reset!`: a model switch (`Engine#switch_model!`), a plugin's
|
|
68
|
-
`tools_changed
|
|
69
|
-
everything below it.
|
|
69
|
+
`tools_changed!` or `prompt_changed!` (`Engine#prompt_changed!`), a profile change, or a toolkit change
|
|
70
|
+
(`Engine#apply_toolkit!`). A per-turn rebuild would break everything below it.
|
|
70
71
|
- The tools layer is shared **per toolkit** (configuration.md, "Toolkits"): sessions on the same toolkit share it,
|
|
71
72
|
and a chain's links keep theirs. A session's toolkit is saved when it is created and never resolved again from
|
|
72
73
|
config. A change (`/toolkit`, `ctx.use_toolkit`) is applied only at a turn's start (`Engine#apply_toolkit!`,
|
|
@@ -88,6 +89,15 @@ right-hand column happens.
|
|
|
88
89
|
sessions on the kit share it; a memory write (the indexes after it) doesn't move it. It is part of the
|
|
89
90
|
`Toolkit::Resolved` the Registry holds, so a switch that changes only the text is a toolkit change
|
|
90
91
|
(`apply_toolkit!` → `reset!`). `full` and kits without one send the bytes they sent before.
|
|
92
|
+
- A plugin's prompt sections (`chi.prompt_section`, `Plugin::PromptSections`) sit after the kit prompt and before
|
|
93
|
+
the memory indexes (`SystemPrompt#plugin_prompt_section`), sorted by (bundle, name), each
|
|
94
|
+
`From <bundle> (<name>):\n<text>`; with none (every block nil) the bytes are what they were before. A block runs
|
|
95
|
+
only inside a build, never per request, so its text changes the prompt only at a rebuild: `/model` (a block
|
|
96
|
+
reading `ctx.model` re-resolves for free) or the plugin's `chi.prompt_changed!`, which its command calls only
|
|
97
|
+
after asking (`ctx.cache_confirm`, rule 6); a running turn keeps the prompt it started with (`turn_messages` puts
|
|
98
|
+
it in the turn's messages once). A block that raises, returns a non-String or text over 2000 characters keeps
|
|
99
|
+
the section's last good text for the session: a skip on a transient error would break the cache twice (and on
|
|
100
|
+
Claude 5.x cost the preserved thinking each time).
|
|
91
101
|
- find_tools' description is a function of the toolkit and the source groups **at load**: `ToolIndex#declare`
|
|
92
102
|
snapshots source group names and description lines (name, summary, callable count). `ToolIndex#refresh!` (from
|
|
93
103
|
`ToolkitBinding#apply!`) filters that snapshot by the new toolkit and rebuilds the `chi` line from the built-ins
|
|
@@ -221,7 +231,9 @@ is prefilled once. The native and the chat loop use the same plan.
|
|
|
221
231
|
3. **Deterministic order.** Tools, memory lists and anything else that's rendered from a hash or a set needs a
|
|
222
232
|
fixed sort. Plugin tools are sorted by (bundle, name) whatever order their plugins finished starting in
|
|
223
233
|
(R5a).
|
|
224
|
-
4. **Don't rebuild the system prompt per turn.** Rebuild only when its content really changed (`reset!`).
|
|
234
|
+
4. **Don't rebuild the system prompt per turn.** Rebuild only when its content really changed (`reset!`). A
|
|
235
|
+
plugin's prompt section is the same text for the same inputs, and its `chi.prompt_changed!` is called only when
|
|
236
|
+
its text changed.
|
|
225
237
|
5. **Measure.** Every generation logs `prompt=`, `cached=` and, where the provider reports it, `cache_write=`
|
|
226
238
|
on its `generation_completed` log line. `/stats` shows "cached N (P%)" and "cache writes". A change that
|
|
227
239
|
drops `cached=` on the second fresh session is a regression. Update the prompt snapshot fixtures with
|
|
@@ -230,13 +242,21 @@ is prefilled once. The native and the chat loop use the same plan.
|
|
|
230
242
|
the conversation again asks a person at a web tab or a TUI first (`CacheConfirm`: the reply carries the
|
|
231
243
|
`--yes` line, `SessionCommands::Result#confirm` and the `command_ran` event's `confirm`). Each setting has a
|
|
232
244
|
classifier: `Thinking.cache_cost` (`:full` for Gemma, `:provider` for a remote chat host, `:tail` otherwise) and
|
|
233
|
-
`ReasoningHistory.cache_cost` (`:history` for a change to or from `all` once an earlier reply has thinking)
|
|
245
|
+
`ReasoningHistory.cache_cost` (`:history` for a change to or from `all` once an earlier reply has thinking),
|
|
246
|
+
`/model` (`SessionCommands#model_ask`: `:full` for any other resolved ref, `Engine#model_switch_ref` checking
|
|
247
|
+
the name first, so a typo errors instead of asking; every switching branch, `--default`, `--alias`, `clear`), and `LLMContextCommand#cache_cost` (`:full` for forget
|
|
248
|
+
on or off, `:history` for a layer with applied stubs turned off; stale on, the apply rule and the budget only
|
|
249
|
+
decide when a batch's break comes, so they don't ask).
|
|
234
250
|
`CacheConfirm.needed?` asks only for `:full`, `:provider` and `:history`, when the effective level changes and
|
|
235
251
|
the session has a model reply. The confirmation estimates the reread size from the latest known context count:
|
|
236
252
|
the whole conversation for `:full` / `:provider`, or up to the first changed reply for `:history`; it omits the
|
|
237
253
|
estimate when no count is known. On `api: anthropic`, a `:full` / `:provider` change also warns that preserved
|
|
238
|
-
thinking in replies is dropped from then on. A new setting with a cost
|
|
239
|
-
|
|
254
|
+
thinking in replies is dropped from then on. A new setting with a cost adds its classifier and goes through
|
|
255
|
+
the same step. A launch flag (`chi --model`, `--llm-context`, `--thinking` on an attached or resumed session,
|
|
256
|
+
`LLMContextOverride.command_line`) and a chip whose form states the cost (`level_chip.js`, `llm_context_chip.js`)
|
|
257
|
+
send their line with `--yes`: typing the flag, or the Set, is the choice. A plugin command asks
|
|
258
|
+
through `ctx.cache_confirm(line, changed:)` (cost `:full`: its prompt section is in the stable part), with the
|
|
259
|
+
sender's flag `SessionCommands#run` gives it (`CacheConfirm.asking`), and returns `[text, confirm]`.
|
|
240
260
|
7. **No wall-clock time rendered at wire time.** A history entry's `at` (`MessageTime::KEY`, when it happened) is
|
|
241
261
|
display-only: no wire format reads it, and a guard spec checks that `ChatLoop#wire_messages` and
|
|
242
262
|
`Prompt.format_with_images` give the same bytes with and without it (`spec/message_time_history_spec.rb`). A
|
data/docs/memory.md
CHANGED
|
@@ -164,9 +164,23 @@ Working habits for this model:
|
|
|
164
164
|
longest run without an edit and the Continues and steers each needed; run a
|
|
165
165
|
note on and muted for the same kind of task. See
|
|
166
166
|
[testing.md](testing.md) ("The model notes report").
|
|
167
|
+
- **A note for every model**: `models: *` matches any id, so one note sets a
|
|
168
|
+
house style for all of them. The model-notes bundle ships one,
|
|
169
|
+
`model_notes_tone`:
|
|
170
|
+
|
|
171
|
+
```markdown
|
|
172
|
+
models: *
|
|
173
|
+
How to write answers:
|
|
174
|
+
- Answer first, in plain words. Skip preambles, restating the question and closing offers. Use a list only for steps or several parallel items.
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
It stacks with a family's note. Off for one session: `chi --mute
|
|
178
|
+
model_notes_tone` (at launch); everywhere: `chi memory rm model_notes_tone
|
|
179
|
+
--scope system`, or keep your own text under that name (yours wins).
|
|
167
180
|
- **Shipped notes: the model-notes bundle.** `chi bundle install model-notes`
|
|
168
|
-
(or the `dev` profile) installs reviewed notes into the system scope
|
|
169
|
-
|
|
181
|
+
(or the `dev` profile) installs reviewed notes into the system scope:
|
|
182
|
+
`model_notes_deepseek` (`models: *deepseek-v4*`) and `model_notes_tone`
|
|
183
|
+
(`models: *`, concise answers for every model). Each note's provenance
|
|
170
184
|
and evidence is in the bundle's `notes/README.md`, and its spec pins which
|
|
171
185
|
model ids load which note ([Plugins](plugins.md#the-model-notes-bundle)).
|
|
172
186
|
- **Your own note of the same name wins.** The install skips a
|