samagotchi 0.2.0 → 0.4.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 +198 -1
- data/README.md +56 -4
- data/bin/chi +118 -50
- data/docs/cli.md +184 -9
- data/docs/configuration.md +333 -47
- data/docs/desktop.md +45 -4
- data/docs/guardrails.md +11 -0
- data/docs/hooks.md +208 -5
- data/docs/plugins.md +68 -2
- data/docs/releasing.md +23 -13
- data/docs/sessions.md +45 -17
- data/lib/samagotchi/answer_display.rb +95 -0
- data/lib/samagotchi/archive_store.rb +90 -0
- data/lib/samagotchi/bootstrap/config_writer.rb +342 -0
- data/lib/samagotchi/bootstrap/probe.rb +262 -0
- data/lib/samagotchi/bootstrap_command.rb +347 -0
- data/lib/samagotchi/bridge/pending_card.rb +89 -0
- data/lib/samagotchi/bridge/turn_accumulator.rb +15 -3
- data/lib/samagotchi/bridge.rb +13 -1
- data/lib/samagotchi/bridge_client.rb +6 -2
- data/lib/samagotchi/bundles/check-in/manifest.yml +10 -0
- data/lib/samagotchi/bundles/check-in/plugin.rb +244 -0
- data/lib/samagotchi/bundles/source-links/hooks/source_links.rb +531 -0
- data/lib/samagotchi/bundles/source-links/manifest.yml +14 -0
- data/lib/samagotchi/bundles/source-links/source_links.md +5 -0
- data/lib/samagotchi/bundles/system/config_modification_protocol.md +10 -6
- data/lib/samagotchi/bundles/system/delegated.md +6 -7
- data/lib/samagotchi/bundles/system/manifest.yml +4 -4
- data/lib/samagotchi/bundles/system/self_map.md +8 -2
- data/lib/samagotchi/client.rb +81 -19
- data/lib/samagotchi/commands/registry.rb +8 -0
- data/lib/samagotchi/config.rb +252 -48
- data/lib/samagotchi/desktop/macos/App.swift +12 -8
- data/lib/samagotchi/desktop/macos/ChiRunner.swift +17 -9
- data/lib/samagotchi/desktop/macos/Images.swift +113 -0
- data/lib/samagotchi/desktop/macos/Info.plist.erb +6 -0
- data/lib/samagotchi/desktop/macos/Panel.swift +180 -25
- data/lib/samagotchi/desktop/macos.rb +59 -8
- data/lib/samagotchi/desktop_command.rb +6 -3
- data/lib/samagotchi/edit_preview.rb +82 -0
- data/lib/samagotchi/empty_answer_retry.rb +43 -0
- data/lib/samagotchi/engine.rb +434 -140
- data/lib/samagotchi/gem_update.rb +89 -0
- data/lib/samagotchi/guardrails/approval.rb +35 -4
- data/lib/samagotchi/guardrails/load_failures.rb +9 -3
- data/lib/samagotchi/guardrails/scratch_writes.rb +40 -0
- data/lib/samagotchi/guardrails.rb +1 -0
- data/lib/samagotchi/hooks/registry.rb +24 -5
- data/lib/samagotchi/host_registry.rb +9 -12
- data/lib/samagotchi/idle_client.rb +24 -15
- data/lib/samagotchi/idle_recap.rb +5 -1
- data/lib/samagotchi/idle_reminders.rb +2 -2
- data/lib/samagotchi/image_store.rb +10 -6
- data/lib/samagotchi/kernel_loop.rb +73 -94
- data/lib/samagotchi/live_versions.rb +59 -0
- data/lib/samagotchi/llm/api_key.rb +41 -0
- data/lib/samagotchi/llm/chat_loop.rb +132 -29
- data/lib/samagotchi/llm/errors.rb +41 -9
- data/lib/samagotchi/llm/http.rb +57 -17
- data/lib/samagotchi/llm/openai_chat.rb +17 -30
- data/lib/samagotchi/log_subscriber.rb +18 -3
- data/lib/samagotchi/memory_bundle/installer.rb +65 -63
- data/lib/samagotchi/memory_bundle/provenance.rb +51 -12
- data/lib/samagotchi/memory_bundle/shipped_update.rb +157 -0
- data/lib/samagotchi/memory_bundle/status.rb +4 -1
- data/lib/samagotchi/memory_bundle/system_bundle.rb +81 -53
- data/lib/samagotchi/model_profile.rb +24 -1
- data/lib/samagotchi/plugin/context.rb +22 -1
- data/lib/samagotchi/plugin/sessions.rb +3 -1
- data/lib/samagotchi/prompt.rb +4 -2
- data/lib/samagotchi/reminder_store.rb +1 -9
- data/lib/samagotchi/reply_wait.rb +126 -0
- data/lib/samagotchi/sampling_settings.rb +58 -0
- data/lib/samagotchi/self_report.rb +18 -3
- data/lib/samagotchi/send_command.rb +252 -11
- data/lib/samagotchi/session.rb +52 -11
- data/lib/samagotchi/session_archive_command.rb +107 -0
- data/lib/samagotchi/session_commands.rb +46 -7
- data/lib/samagotchi/session_manager.rb +115 -25
- data/lib/samagotchi/session_metrics.rb +222 -106
- data/lib/samagotchi/steer.rb +72 -0
- data/lib/samagotchi/terminal_ui/attached_loop.rb +57 -28
- data/lib/samagotchi/terminal_ui/event_renderer.rb +21 -11
- data/lib/samagotchi/terminal_ui/formatting.rb +40 -8
- data/lib/samagotchi/terminal_ui/input_support.rb +7 -19
- data/lib/samagotchi/terminal_ui/question_prompt.rb +35 -0
- data/lib/samagotchi/terminal_ui.rb +134 -247
- data/lib/samagotchi/text_diff.rb +181 -0
- data/lib/samagotchi/thinking.rb +115 -0
- data/lib/samagotchi/tool_activity.rb +3 -1
- data/lib/samagotchi/tool_runner.rb +34 -1
- data/lib/samagotchi/tools/ask_user_question.rb +41 -33
- data/lib/samagotchi/tools/builtins.rb +15 -4
- data/lib/samagotchi/tools/delegate_wait.rb +26 -69
- data/lib/samagotchi/tools/edit.rb +23 -9
- data/lib/samagotchi/tools/execute.rb +52 -14
- data/lib/samagotchi/tools/task_runtime.rb +19 -0
- data/lib/samagotchi/tools/task_wait.rb +27 -3
- data/lib/samagotchi/tools/write.rb +4 -0
- data/lib/samagotchi/turn_flow.rb +12 -2
- data/lib/samagotchi/turn_note.rb +60 -6
- data/lib/samagotchi/update_command.rb +308 -0
- data/lib/samagotchi/update_hint.rb +59 -0
- data/lib/samagotchi/version.rb +1 -1
- data/lib/samagotchi/vision_support.rb +7 -9
- data/lib/samagotchi/web/app.rb +91 -7
- data/lib/samagotchi/web/message_parts.rb +8 -3
- data/lib/samagotchi/web/public/activity.js +13 -1
- data/lib/samagotchi/web/public/annotate_presets.js +26 -0
- data/lib/samagotchi/web/public/annotations.js +13 -0
- data/lib/samagotchi/web/public/app.js +472 -111
- data/lib/samagotchi/web/public/card.js +5 -3
- data/lib/samagotchi/web/public/chat_view.js +13 -1
- data/lib/samagotchi/web/public/copy.js +20 -4
- data/lib/samagotchi/web/public/ctx.js +15 -0
- data/lib/samagotchi/web/public/data.js +23 -6
- data/lib/samagotchi/web/public/diff_view.js +58 -0
- data/lib/samagotchi/web/public/format.js +9 -0
- data/lib/samagotchi/web/public/index.html +60 -3
- data/lib/samagotchi/web/public/notify.js +175 -0
- data/lib/samagotchi/web/public/question_card.js +5 -2
- data/lib/samagotchi/web/public/sessions_list.js +7 -0
- data/lib/samagotchi/web/public/timing.js +39 -14
- data/lib/samagotchi/web/public/turn_events.js +75 -5
- data/lib/samagotchi/web/public/turn_view.js +49 -8
- data/lib/samagotchi/web/server.rb +8 -4
- data/lib/samagotchi/web/session_hub.rb +2 -1
- data/lib/samagotchi/web/session_summary.rb +24 -1
- data/lib/samagotchi/worker.rb +16 -4
- metadata +31 -1
data/docs/cli.md
CHANGED
|
@@ -2,22 +2,120 @@
|
|
|
2
2
|
|
|
3
3
|
## Commands
|
|
4
4
|
|
|
5
|
+
- `chi bootstrap [HOST[:PORT]|URL]` — first setup: find the model server (llama.cpp or OpenAI-compatible), pick the model, send a test request and write config.yml, or add a `hosts:` entry to an existing one (see [First setup](#first-setup))
|
|
5
6
|
- `chi` — start a session in a background worker and attach the terminal to it, so the Web UI (or another terminal) can share it (see [Sharing a session](#sharing-a-session))
|
|
6
7
|
- `chi -p "your prompt"` — run a prompt, then stay attached
|
|
7
8
|
- `chi -p "your prompt" --non-interactive` — run a prompt, print the answer, exit
|
|
8
9
|
- `chi --resume <session-id>` — resume a prior session (in its worker)
|
|
9
10
|
- `chi --no-shared [--resume <session-id>]` — the plain in-process REPL instead, for this run
|
|
11
|
+
- `chi scratch [options]` — a one-time session in the plain in-process REPL, in this folder, that leaves nothing behind (see [Scratch sessions](#scratch-sessions))
|
|
10
12
|
- `chi --attach <session-id>` — attach the terminal to a session's worker (e.g. one started from the Web UI), waking one if it has exited
|
|
11
|
-
- A session id can be shortened to any unique prefix (like git): `chi --attach 2ea8`. `--resume`, `--attach`, `sessions stop` and `sessions delete` take one; an ambiguous prefix lists the sessions it matches.
|
|
13
|
+
- A session id can be shortened to any unique prefix (like git): `chi --attach 2ea8`. `--resume`, `--attach`, `sessions stop`, `sessions archive` and `sessions delete` take one; an ambiguous prefix lists the sessions it matches.
|
|
12
14
|
- `chi web [--port 4567] [--open] [--scope=all]` — start the Web UI (single localhost port session control plane) on this git project's sessions (`--scope=all`, or a folder in no repo: every session); if a chi web already runs on the port, print (with `--open`, open) its page for this folder and exit. Something else on the port (an older chi web too) exits 1 with "port N is in use"
|
|
13
15
|
- `chi web --web-markdown` — opt in to sanitized Markdown rendering for completed assistant messages
|
|
14
16
|
- `chi web --no-web-turn-view` — show turns as the classic row of bubbles instead of the default turn view (each turn as one block of steps, the running one at the bottom); `?view=turn|chat` on the page URL overrides it (see [Web turn view](#web-turn-view))
|
|
15
|
-
- `chi sessions list|stop|delete|prune|clean` — manage persisted sessions; `list` shows this git project's, `list --scope=all` every one, a delegated session with `↳ <parent
|
|
17
|
+
- `chi sessions list|stop|archive|unarchive|delete|prune|clean` — manage persisted sessions; `list` shows this git project's, `list --scope=all` every one, a delegated session with `↳ <parent>`, `list --archived` the archived ones too (see [Sessions](sessions.md))
|
|
16
18
|
- `chi note [--source NAME] [-m TEXT] (ID|PREFIX)... | --all` — add a context note (TEXT or stdin) to sessions: background the model sees on its next turn; it starts no turn (see [Sessions: Context notes](sessions.md#context-notes))
|
|
17
|
-
- `chi send [-m TEXT] (ID|PREFIX)...` — send a message to sessions as if typed there: a turn starts (or a running one picks it up); piped stdin goes above `-m` as quoted context (see [Sessions: Sending a message](sessions.md#sending-a-message))
|
|
19
|
+
- `chi send [-m TEXT] [--image PATH]... (ID|PREFIX)...` — send a message to sessions as if typed there: a turn starts (or a running one picks it up); piped stdin goes above `-m` as quoted context, and `--image` attaches images (see [Sessions: Sending a message](sessions.md#sending-a-message)); `--new` starts a session with it instead, and `--wait` prints the answer (`--wait ID` with no message waits for the next reply without sending; see [Starting a session](sessions.md#starting-a-session))
|
|
18
20
|
- `chi desktop install|upgrade|uninstall|status` — the macOS "Send to chi" helper: a Service and a ⌃⌥⌘N hotkey that send text to live sessions as context notes (see [Desktop helper](desktop.md))
|
|
19
21
|
- `chi self` — print version, source dir (checkout or installed gem), config/memory/session paths, model/host and bundles
|
|
20
|
-
- `chi
|
|
22
|
+
- `chi update [--dry-run] [--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))
|
|
23
|
+
- `chi bundle install|upgrade|uninstall|status|diff|list|build` — 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 (see [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) and [the check-in bundle](plugins.md#the-check-in-bundle))
|
|
24
|
+
|
|
25
|
+
### First setup
|
|
26
|
+
|
|
27
|
+
`chi bootstrap TARGET` names the model server and writes the config for it:
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
chi bootstrap 192.168.1.29:8081 # host:port (port 8080 when none)
|
|
31
|
+
chi bootstrap https://openrouter.ai/api/v1 --key-env OPENROUTER_API_KEY
|
|
32
|
+
chi bootstrap # try localhost 8080, 11434, 1234, 8000
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- **What it is.** llama.cpp's `/props` answering means the native API (no
|
|
36
|
+
`api:`); otherwise `GET /v1/models` answering means an OpenAI-compatible
|
|
37
|
+
server (`api: openai`). A URL with a path is the API base as given
|
|
38
|
+
(`…/api/v1`); a domain without a scheme is tried over https, then http.
|
|
39
|
+
Each request is tried once, with 5 s timeouts, so a refused port answers
|
|
40
|
+
at once.
|
|
41
|
+
- **The key.** A server that answers 401/403 wants an API key: `--key-env VAR`
|
|
42
|
+
names the environment variable holding it (on a terminal chi asks for the
|
|
43
|
+
name). Only the variable's name is written, never the key.
|
|
44
|
+
- **The model.** One model is taken; with several, `--model ID` picks one
|
|
45
|
+
(a terminal gets a numbered list, a script the ids and exit 2). A llama.cpp
|
|
46
|
+
server also shows its context size and the prompt profile its chat template
|
|
47
|
+
matches.
|
|
48
|
+
- **The test.** One short chat request ("test: answered in 1.1 s"); `--no-test`
|
|
49
|
+
skips it. A failed test still writes the config, says so and exits 1.
|
|
50
|
+
- **The file.** With no config.yml it writes a small commented one:
|
|
51
|
+
`default.model` as `<host>:<model>` and one `hosts:` entry named `local`
|
|
52
|
+
(localhost), `lan` (an IP) or after the domain (`openrouter`); `--name`
|
|
53
|
+
sets it. An existing file is left as it is apart from the new entry, added
|
|
54
|
+
at the end of its `hosts:` block (it gets a `hosts:` block, with a
|
|
55
|
+
`default` entry for its `server:` first, when it has none), after a backup
|
|
56
|
+
to `config.yml.bak-<time>`. `default.model` is set only when the file has
|
|
57
|
+
none. A server already in the file writes nothing; a file in YAML flow style
|
|
58
|
+
or with anchors gets the lines printed to paste instead. `--dry-run` shows
|
|
59
|
+
what it would write.
|
|
60
|
+
|
|
61
|
+
### Updating
|
|
62
|
+
|
|
63
|
+
`chi update` brings an installed chi up to date and prints one table:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
component from to status
|
|
67
|
+
chi (gem) 0.2.0 0.3.0 updated
|
|
68
|
+
system bundle 0.2.0 0.3.0 updated (kept your edits in identity.md: chi bundle diff samagotchi-system identity.md)
|
|
69
|
+
btw 0.1.1 up to date
|
|
70
|
+
known-names 0.1.0 0.1.1 updated
|
|
71
|
+
infra_tools 1.0.0 skipped (not from chi)
|
|
72
|
+
Chi Helper 0.2.0 up to date (launch file refreshed)
|
|
73
|
+
workers 2 live on 0.2.0: they move to 0.3.0 at idle exit (30 min) or chi sessions stop 2ea8c1f0 91b0d2aa
|
|
74
|
+
Also shipped, not installed: check-in, source-links (chi bundle install NAME)
|
|
75
|
+
done
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
- **The gem.** It asks rubygems.org for the newest samagotchi (5 s timeout)
|
|
79
|
+
and, when that's newer, runs `gem install samagotchi` with the gem command
|
|
80
|
+
of the Ruby chi runs on (the real one, not a mise/rbenv/asdf shim). Then it
|
|
81
|
+
hands over to the new chi, which does the rest and prints the table. Old
|
|
82
|
+
versions stay installed: running workers and an old `chi web` still use
|
|
83
|
+
them (so don't `gem cleanup` while they run). Offline, the row says
|
|
84
|
+
"couldn't check" and the rest still runs; a failed install fails the row
|
|
85
|
+
and the rest runs on the current version. Under Bundler (`bundle exec`)
|
|
86
|
+
the row says `bundle update samagotchi` instead.
|
|
87
|
+
- **The system bundle** normally updated itself when the new chi started;
|
|
88
|
+
the row says what it did.
|
|
89
|
+
- **Shipped bundles**: each one you installed from chi (`chi bundle install
|
|
90
|
+
NAME`) is upgraded when chi ships a newer version. Memory files get the
|
|
91
|
+
3-way merge of `chi bundle upgrade`: an unedited file is updated, an edited
|
|
92
|
+
one that the new version also changes is kept, and the row says so (`chi
|
|
93
|
+
bundle diff NAME FILE` shows it; `chi bundle upgrade NAME --force` takes the
|
|
94
|
+
bundle's). Hooks, rules and the plugin are replaced; an edited one didn't
|
|
95
|
+
load anyway (its sha no longer matched) and the row says it was replaced.
|
|
96
|
+
A bundle of the same name from elsewhere (a zip, git) is skipped ("not from
|
|
97
|
+
chi"), a newer installed one is left, one whose new version needs a newer
|
|
98
|
+
chi is skipped, and bundles you didn't install stay uninstalled.
|
|
99
|
+
- **The desktop helper** (macOS) is rebuilt and restarted only when its Swift
|
|
100
|
+
sources changed (or the Ruby it runs moved); otherwise only its launch file
|
|
101
|
+
is refreshed. See [Desktop helper](desktop.md).
|
|
102
|
+
- **Running processes** are reported, never stopped: live workers on another
|
|
103
|
+
version, and a `chi web` on `web.port` running an older chi (sessions it
|
|
104
|
+
starts run that version too: restart it).
|
|
105
|
+
|
|
106
|
+
`--dry-run` shows the table with "would update" and changes nothing. It is
|
|
107
|
+
this version's view: bundles that only a newer gem ships newer show up once
|
|
108
|
+
that gem is installed (the real run installs it first and hands over).
|
|
109
|
+
`--no-gem`, `--no-bundles` and `--no-desktop` leave a part alone for one run;
|
|
110
|
+
`update.gem`, `update.bundles` and `update.desktop: false` in config.yml turn
|
|
111
|
+
one off for good. It exits 0 when nothing failed (kept edits and skips are
|
|
112
|
+
fine), 1 when a part failed, 2 on a usage error. A second run changes nothing
|
|
113
|
+
and ends with "everything is up to date".
|
|
114
|
+
|
|
115
|
+
From a checkout it refuses (`git pull`, or `chi bundle upgrade NAME` for one
|
|
116
|
+
bundle). After a gem update, the first interactive start of the new version
|
|
117
|
+
(`chi`, `chi web`; not `-p` or `--non-interactive`) says in one line when
|
|
118
|
+
bundles or the helper can be updated.
|
|
21
119
|
|
|
22
120
|
## Flags
|
|
23
121
|
|
|
@@ -33,6 +131,7 @@ controls exit behavior (`--non-interactive`); `--resume` composes with both.
|
|
|
33
131
|
| `--no-shared` | Run the plain in-process REPL for this run. |
|
|
34
132
|
| `--attach SESSION_ID` | Attach to a session's worker, waking one if it has exited. |
|
|
35
133
|
| `--model NAME` | Use this model for the run (overrides the configured default and a resumed session's model). |
|
|
134
|
+
| `--thinking LEVEL` | How much the model thinks this run: `off`, `low`, `medium`, `high` or `default` (env `SAMAGOTCHI_THINKING_LEVEL`), over the config's levels. A session already running keeps its own. See "Thinking" in configuration.md. |
|
|
36
135
|
| `--profile NAME` | Prompt profile (`qwen36` or `gemma4`) for every model in this run, over config and the server's template (same as `--model-profile`, env `SAMAGOTCHI_MODEL_PROFILE`). See "Prompt profile" in configuration.md. |
|
|
37
136
|
| `--memory NAME` | Preload a memory entry into the system prompt (repeatable; a comma list too). Merged under the config.yml `memories:` baseline. Works attached: the list is stored on the session, so its worker builds the same prompt on every respawn. |
|
|
38
137
|
| `--mute NAME` | Hide a memory from this session (repeatable; a comma list too): its index line is not in the prompt, `memory_read` refuses it, the identity auto-load skips it, and it is dropped from the preloads (config baseline or `--memory`). A name matches in both scopes (`gh-helper`, `project/gh-helper` and `gh-helper.md` all hide `gh-helper`). Nothing on disk changes. See [Muting a memory](#muting-a-memory). |
|
|
@@ -64,6 +163,7 @@ it sees one.
|
|
|
64
163
|
| `chi --resume ID -p "next step" --non-interactive` | Resume `ID`, run the prompt, save, exit. |
|
|
65
164
|
| `chi --resume ID -p "next step"` | Resume `ID`, send the prompt, **stay attached** to that session. |
|
|
66
165
|
| `chi --no-shared [...]` | The same, in the plain in-process REPL. |
|
|
166
|
+
| `chi scratch [-p ...] [--non-interactive]` | A new session in the plain REPL, deleted when it ends. |
|
|
67
167
|
|
|
68
168
|
Notes:
|
|
69
169
|
|
|
@@ -75,6 +175,28 @@ Notes:
|
|
|
75
175
|
- Non-interactive runs (`-p` with `--non-interactive`, or bare `--non-interactive`)
|
|
76
176
|
print only the final result output — no spinner, status line, or REPL.
|
|
77
177
|
|
|
178
|
+
### Scratch sessions
|
|
179
|
+
|
|
180
|
+
`chi scratch` is `chi --no-shared` for a session you won't keep: a quick
|
|
181
|
+
question, a try-out. It takes the run options (`-p`, `--non-interactive`,
|
|
182
|
+
`--model`, `--profile`, `--memory`, `--mute`, `-v`, …); `--resume`, `--attach`
|
|
183
|
+
and `--shared` are refused. Its first line says it is a scratch session.
|
|
184
|
+
|
|
185
|
+
- The session is deleted however it ends: `/exit`, Ctrl-D, Ctrl-C at the
|
|
186
|
+
prompt, an error, SIGTERM or SIGHUP. There is no recap, and the lines typed
|
|
187
|
+
are not added to the prompt history.
|
|
188
|
+
- It never shows in `chi web`. A process killed with `kill -9` leaves its
|
|
189
|
+
session behind, marked `"scratch": true` in its session.json: `chi sessions
|
|
190
|
+
list` shows it as `[scratch]`, and the next sweep or `chi sessions clean`
|
|
191
|
+
deletes it. `chi --resume` and `--attach` refuse it (exit 1), so it never
|
|
192
|
+
turns into a kept session.
|
|
193
|
+
- Memories are read and preloaded as usual, but nothing is saved: `memory_write`
|
|
194
|
+
answers "scratch session: nothing is saved", and `write`/`edit` into the
|
|
195
|
+
memories folder are denied (a guardrail, rule `scratch-session`). `execute`
|
|
196
|
+
can still write files anywhere, memories included.
|
|
197
|
+
- No child sessions: the `delegate` tools are not offered, and a plugin's
|
|
198
|
+
`ctx.sessions.fork` (btw's side session) refuses, since they would outlive it.
|
|
199
|
+
|
|
78
200
|
### Sharing a session
|
|
79
201
|
|
|
80
202
|
Plain `chi` runs the session in a background worker and attaches the terminal
|
|
@@ -122,7 +244,8 @@ A worker nobody uses exits after `session.idle_exit_minutes` (30 by default, `0`
|
|
|
122
244
|
for never): no turn running or queued, no UI attached (an open web tab or an
|
|
123
245
|
attached terminal counts, even an idle one) and no reminder registered. The next
|
|
124
246
|
prompt or `--attach` wakes a new worker with the conversation intact; `/stats`
|
|
125
|
-
|
|
247
|
+
keeps counting from the turns before (they are saved in the session's
|
|
248
|
+
`analytics.json`, one record per turn), and the recap is saved with the session.
|
|
126
249
|
|
|
127
250
|
A session you leave with nothing in it (no prompt sent, no `/model` switch, no
|
|
128
251
|
note or image) is deleted as its worker exits, and `/exit` says so; set
|
|
@@ -134,6 +257,21 @@ a `chi --resume ID` after it starts a fresh one. A worker still running an
|
|
|
134
257
|
older chi (from before an upgrade) takes turns but not commands; the attached
|
|
135
258
|
terminal and the Web UI say so, with that restart line.
|
|
136
259
|
|
|
260
|
+
`chi sessions archive ID...` hides sessions from every list (the terminal's,
|
|
261
|
+
the web's, `list_sessions`) and keeps them for good: the retention sweep never
|
|
262
|
+
deletes an archived session, nor counts it. Its delegates go with it. A live
|
|
263
|
+
worker is stopped first; a session running a turn (or with a delegate running
|
|
264
|
+
one), open in a plain REPL, or a `chi scratch` one is refused. `chi sessions
|
|
265
|
+
list --archived` shows them too, marked `[archived]` (`archived: true` in
|
|
266
|
+
`--format json`); `chi sessions unarchive ID...` brings them back, and so does
|
|
267
|
+
a message you send to one (the web, an attached terminal, `chi send`), but not
|
|
268
|
+
a delegate's follow-up or a reminder. The web archives from the info bar
|
|
269
|
+
(`archive`, before `stop`); "include archived" by the all-sessions search
|
|
270
|
+
finds archived sessions. `/archive` in a terminal leaves the session and
|
|
271
|
+
archives it (an empty session is discarded instead; `chi scratch` refuses
|
|
272
|
+
it). See
|
|
273
|
+
[Sessions](sessions.md#archiving-a-session).
|
|
274
|
+
|
|
137
275
|
`chi sessions delete [--force] ID...` deletes sessions for good: the
|
|
138
276
|
session file and its whole directory (notes, images, queued input). Each id
|
|
139
277
|
(or unique prefix) gets one line: `deleted`, or `refused` with the reason. A
|
|
@@ -202,7 +340,7 @@ REPL alike:
|
|
|
202
340
|
typed comes back once it closes. The choices then go, and one line stays:
|
|
203
341
|
`? Pick a fruit → Banana`.
|
|
204
342
|
- Ctrl-C cancels the turn and keeps what you typed.
|
|
205
|
-
- In the plain REPL, Ctrl-D on an empty prompt (or `exit`, `/exit`) mid-turn
|
|
343
|
+
- In the plain REPL, Ctrl-D on an empty prompt (or `exit`, `/exit`, `/quit`) mid-turn
|
|
206
344
|
exits once the turn ends: `(exits after this turn; Ctrl-C cancels it)`
|
|
207
345
|
(`/exit --delete` deletes the session then too). In an
|
|
208
346
|
attached terminal it detaches at once and the turn goes on in the worker
|
|
@@ -213,7 +351,7 @@ turns.
|
|
|
213
351
|
|
|
214
352
|
### Images
|
|
215
353
|
|
|
216
|
-
A model that can see images gets them
|
|
354
|
+
A model that can see images gets them these ways:
|
|
217
355
|
|
|
218
356
|
- **`@path` in a prompt** (REPL, attached terminal, `-p`): `what's wrong in
|
|
219
357
|
@shot.png?`, `@~/Desktop/a.jpg`, `@"my shot.png"`. Each `@` token that names an
|
|
@@ -228,6 +366,12 @@ A model that can see images gets them three ways:
|
|
|
228
366
|
- **The Web UI**: paste or drop images into the composer. Each shows as a chip
|
|
229
367
|
(× removes it) and is sent with the message; an image alone is sent as
|
|
230
368
|
`[image: name]`. Messages show thumbnails; a click opens one full size.
|
|
369
|
+
- **`chi send --image PATH`** (repeatable, up to 20) with a message, from a
|
|
370
|
+
script or another terminal: `chi send --image shot.png -m "why is this red?"
|
|
371
|
+
3fa2`. The attached terminal and the web show it like an image typed there.
|
|
372
|
+
- **The desktop panel** (macOS, [Desktop](desktop.md#images)): a screenshot on
|
|
373
|
+
the clipboard, an image selected in Finder, or one dropped on the panel goes
|
|
374
|
+
as an attachment with the message.
|
|
231
375
|
|
|
232
376
|
Images are downscaled to a 1568 px long side (with `sips` on macOS or
|
|
233
377
|
ImageMagick; without either, a larger image is refused with a hint) and stored
|
|
@@ -298,7 +442,10 @@ from the saved messages (each step's thinking, narration, tool parameters
|
|
|
298
442
|
and output, the output capped at 2000 characters) and the timing records
|
|
299
443
|
(status and duration per row). On an `api: openai` host the model's
|
|
300
444
|
reasoning is saved with each step for this (never sent back to the model);
|
|
301
|
-
steps saved before that have none, so they show no thinking.
|
|
445
|
+
steps saved before that have none, so they show no thinking. An `edit` or
|
|
446
|
+
`write` row has a closed `diff +3 −1` under it that opens to the change it
|
|
447
|
+
made (up to 120 lines or 8 KB), live and after a reload (see
|
|
448
|
+
[Guardrails](guardrails.md#ask) for the diff an approval shows first).
|
|
302
449
|
|
|
303
450
|
```sh
|
|
304
451
|
chi web --no-web-turn-view # the classic chat view; --web-turn-view is the default
|
|
@@ -316,6 +463,32 @@ and `?view=turn` the turn view, whatever the config says; the parameter is dropp
|
|
|
316
463
|
when you switch between the project and all-sessions views. The terminal
|
|
317
464
|
UIs are not affected.
|
|
318
465
|
|
|
466
|
+
### Web annotate presets
|
|
467
|
+
|
|
468
|
+
Selecting text in an answer, a thinking block, a tool row or one of your
|
|
469
|
+
messages shows **Annotate**, which quotes the selection into the composer
|
|
470
|
+
for a note under it. Next to it sit quick replies, by default `Agreed` and
|
|
471
|
+
`Could you please elaborate?`: a click quotes the selection the same way
|
|
472
|
+
with that text already written as the note. It only fills the composer,
|
|
473
|
+
never sends, so you can collect several quotes and edit before sending.
|
|
474
|
+
|
|
475
|
+
The list is `web.annotate_presets`, `|`-separated (at most five; a preset
|
|
476
|
+
can't contain `|`; a YAML list works too):
|
|
477
|
+
|
|
478
|
+
```sh
|
|
479
|
+
chi web --web-annotate-presets "Yes|No|Why this way?"
|
|
480
|
+
chi web --web-annotate-presets "" # only Annotate
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
```yaml
|
|
484
|
+
web:
|
|
485
|
+
annotate_presets: "Agreed|Could you please elaborate?"
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
`SAMAGOTCHI_WEB_ANNOTATE_PRESETS` overrides the file, but an empty value
|
|
489
|
+
there means the default, not "none": use `""` in the file or on the command
|
|
490
|
+
line. A `chi web` that already runs keeps its list; restart it.
|
|
491
|
+
|
|
319
492
|
## Runtime Model Switch (Assist Mode)
|
|
320
493
|
|
|
321
494
|
In interactive assist mode, you can switch the request model without restarting:
|
|
@@ -479,7 +652,9 @@ During assist-mode thinking (while the spinner is active), you can cancel an in-
|
|
|
479
652
|
Behavior notes:
|
|
480
653
|
|
|
481
654
|
- Cancellation returns control to the prompt immediately; what you typed there stays.
|
|
482
|
-
-
|
|
655
|
+
- Visible text the canceled request had streamed stays in the conversation, marked `[interrupted]`, so the next
|
|
656
|
+
message (or a continue) picks up from the half-finished reply; the canceled request's thinking and any unfinished
|
|
657
|
+
tool call are dropped.
|
|
483
658
|
|
|
484
659
|
## Iteration Limit Behavior
|
|
485
660
|
|