samagotchi 0.151.0 → 0.153.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 +46 -1
- data/docs/bundle-authoring.md +5 -5
- data/docs/bundles.md +84 -0
- data/docs/cli.md +35 -10
- data/docs/configuration.md +19 -14
- data/docs/guardrails.md +11 -5
- data/docs/hooks.md +4 -3
- data/docs/internals/anthropic.md +3 -3
- data/docs/internals/attached-context.md +3 -0
- data/docs/internals/block-renderers.md +3 -1
- data/docs/internals/bundles.md +48 -14
- data/docs/internals/engine.md +9 -5
- data/docs/internals/objectives.md +6 -4
- data/docs/internals/participants.md +1 -1
- data/docs/internals/prompt-caching.md +7 -3
- data/docs/internals/web-frontend.md +20 -17
- data/docs/memory.md +6 -1
- data/docs/plugins.md +80 -29
- data/docs/releasing.md +8 -3
- data/docs/sessions.md +2 -2
- data/docs/testing.md +2 -2
- data/lib/samagotchi/block_renderers.rb +9 -8
- data/lib/samagotchi/bundle_command/check.rb +43 -3
- data/lib/samagotchi/bundle_command/installed_check.rb +6 -2
- data/lib/samagotchi/bundle_command/try/sandbox.rb +11 -3
- data/lib/samagotchi/bundle_command.rb +88 -10
- data/lib/samagotchi/bundle_needs.rb +4 -6
- data/lib/samagotchi/bundle_settings_check.rb +14 -13
- data/lib/samagotchi/bundles/agents-md/manifest.yml +2 -2
- data/lib/samagotchi/bundles/btw/manifest.yml +2 -2
- data/lib/samagotchi/bundles/loop-guard/manifest.yml +2 -2
- data/lib/samagotchi/bundles/mcp/manifest.yml +2 -2
- data/lib/samagotchi/bundles/skills/manifest.yml +2 -2
- data/lib/samagotchi/bundles/slow-commands/manifest.yml +2 -2
- data/lib/samagotchi/bundles/system/manifest.yml +2 -2
- data/lib/samagotchi/bundles/system/memory_guide.md +3 -3
- data/lib/samagotchi/bundles/web-search/manifest.yml +13 -0
- data/lib/samagotchi/bundles/web-search/plugin.rb +174 -0
- data/lib/samagotchi/child_env.rb +15 -0
- data/lib/samagotchi/context_providers.rb +42 -10
- data/lib/samagotchi/engine.rb +37 -9
- data/lib/samagotchi/extension_load.rb +4 -3
- data/lib/samagotchi/guardrail_wiring.rb +28 -19
- data/lib/samagotchi/guardrails/approval.rb +2 -2
- data/lib/samagotchi/guardrails/review_boundary.rb +4 -3
- data/lib/samagotchi/guardrails/rules.rb +1 -0
- data/lib/samagotchi/guardrails/verdict.rb +20 -0
- data/lib/samagotchi/hooks/bundle_loader.rb +5 -7
- data/lib/samagotchi/llm_context_stale.rb +2 -2
- data/lib/samagotchi/memory_bundle/asset_installer.rb +11 -8
- data/lib/samagotchi/memory_bundle/builder.rb +36 -30
- data/lib/samagotchi/memory_bundle/bundle_hook.rb +3 -2
- data/lib/samagotchi/memory_bundle/file_digest.rb +31 -0
- data/lib/samagotchi/memory_bundle/file_standing.rb +2 -2
- data/lib/samagotchi/memory_bundle/installed_bundle.rb +55 -46
- data/lib/samagotchi/memory_bundle/installed_copy.rb +38 -15
- data/lib/samagotchi/memory_bundle/installed_manifest.rb +224 -0
- data/lib/samagotchi/memory_bundle/installer.rb +90 -16
- data/lib/samagotchi/memory_bundle/manifest.rb +146 -6
- data/lib/samagotchi/memory_bundle/manifest_standing.rb +171 -0
- data/lib/samagotchi/memory_bundle/merger.rb +7 -8
- data/lib/samagotchi/memory_bundle/profile.rb +3 -2
- data/lib/samagotchi/memory_bundle/provenance.rb +217 -18
- data/lib/samagotchi/memory_bundle/shas.rb +4 -3
- data/lib/samagotchi/memory_bundle/shipped_update.rb +52 -24
- data/lib/samagotchi/memory_bundle/status.rb +11 -10
- data/lib/samagotchi/memory_bundle/system_bundle.rb +13 -2
- data/lib/samagotchi/message_parts.rb +3 -2
- data/lib/samagotchi/plugin/loader.rb +1 -1
- data/lib/samagotchi/session_config.rb +5 -4
- data/lib/samagotchi/system_one/record.rb +10 -2
- data/lib/samagotchi/toolkit.rb +8 -5
- data/lib/samagotchi/toolkit_binding.rb +30 -5
- data/lib/samagotchi/toolkit_report_command.rb +9 -5
- data/lib/samagotchi/toolkit_suggest.rb +12 -6
- data/lib/samagotchi/tools/builtin_calls.rb +14 -10
- data/lib/samagotchi/tools/deferred_tools.rb +2 -2
- data/lib/samagotchi/tools/delegate.rb +20 -2
- data/lib/samagotchi/tools/registry.rb +44 -20
- data/lib/samagotchi/tools/tool_index.rb +27 -21
- data/lib/samagotchi/update_command.rb +13 -2
- data/lib/samagotchi/version.rb +1 -1
- data/lib/samagotchi/web/app.rb +2 -1
- data/lib/samagotchi/web/public/app.js +61 -357
- data/lib/samagotchi/web/public/composer_mode.js +110 -0
- data/lib/samagotchi/web/public/owner_claim.js +81 -0
- data/lib/samagotchi/web/public/owner_verify.js +112 -0
- data/lib/samagotchi/web/public/session_fields.js +3 -3
- data/lib/samagotchi/web/public/strip_grip.js +3 -3
- data/lib/samagotchi/web/public/strip_hidden.js +65 -0
- data/lib/samagotchi/web/public/version_notices.js +132 -0
- data/lib/samagotchi/web/session_access_routes.rb +2 -1
- data/lib/samagotchi/web/session_hub.rb +6 -0
- data/lib/samagotchi/worker.rb +6 -0
- metadata +11 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e9dd8da2f6f95806fccc0df5dad4844525947650b92589461adcb70b8bcdf2d7
|
|
4
|
+
data.tar.gz: a1457568c9d119b661d025be9e39989a33593666d668b328c3cd8528e451aa55
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6ed8fbbd7439b3ff95cb6eb251edf5635812cff0579928469a575bbb4bdc190e14ff6959a2f49eb627f127f711c1782c62c99379a2130433e057d0a55dd2e359
|
|
7
|
+
data.tar.gz: 82b22635aad92e8edb672e61ac0eed1c461c1c81330bfde64ac09cd8c969183e37f9420495cbb6b0fbe0624f9a552a17af9cb70a2707b0f483084d25fb10d936
|
data/CHANGELOG.md
CHANGED
|
@@ -5,8 +5,51 @@ format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
|
|
5
5
|
versions follow [Semantic Versioning](https://semver.org/); before 1.0, config
|
|
6
6
|
and commands may change between minor versions. How releases are made:
|
|
7
7
|
[docs/releasing.md](docs/releasing.md).
|
|
8
|
+
|
|
8
9
|
## [Unreleased]
|
|
9
10
|
|
|
11
|
+
## [0.153.0] - 2026-11-06
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- A `web-search` bundle (`chi bundle install web-search`, in no profile): a `web_search` tool that searches the web through your own SearXNG and returns titles, URLs and snippets for `web_fetch` to read. It is declared on `full` and kits on `base: full`; on kits built on `lean` or `child` it is reachable (`find_tools` finds `chi/web_search`, `call_tool` runs it); `add: [web_search]` in a kit declares it. [docs/bundles.md](docs/bundles.md#the-web-search-bundle)
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- A bundle's tools (`chi.tool`) follow a toolkit's tool list as built-ins do: `full`, the kits on `base: full` (the `kits:` default) and a kit's `add:` declare them, any other kit leaves them reachable through `find_tools` / `call_tool` (deferred on `api: anthropic`), and `remove:` removes them. [docs/configuration.md](docs/configuration.md#toolkits)
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- An attached context change that arrives while the worker's leaving pass is already in flight is saved as a note before the worker stops, instead of being dropped with its poller.
|
|
24
|
+
|
|
25
|
+
Update with `chi update` (no installed bundle's version moved; `chi bundle install web-search` adds the new one).
|
|
26
|
+
|
|
27
|
+
## [0.152.0] - 2026-11-06
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- `chi bundle install` and `chi bundle check` name a manifest key this chi doesn't read (`unknown-key`); `chi bundle check` also warns (`requires-chi-floor`) when a manifest uses a key newer than its `requires_chi` admits. [docs/plugins.md](docs/plugins.md)
|
|
32
|
+
- `chi bundle status NAME` has a `Manifest:` line saying where the bundle's manifest is read from, and why.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- An installed bundle keeps its `manifest.yml` and chi reads it live, so a newer chi reads keys the installing chi didn't know, with no reinstall. Bundles installed earlier get theirs on `chi update` (shipped bundles, or a folder or archive that is still there; the system bundle at the next start); for one from git, `chi update` names the `chi bundle upgrade NAME` to run. [docs/internals/bundles.md](docs/internals/bundles.md)
|
|
37
|
+
- `chi bundle install` and `chi bundle upgrade` refuse a bundle whose `requires_chi` this chi doesn't meet, and write nothing; `--force` installs it anyway. [docs/plugins.md](docs/plugins.md)
|
|
38
|
+
- `chi bundle upgrade NAME` upgrades a bundle from a folder, archive or git URL from the source its record keeps: the name alone is enough.
|
|
39
|
+
- "Stable for bundles" now covers the manifest schema. [docs/plugins.md](docs/plugins.md)
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
|
|
43
|
+
- `chi bundle diff NAME FILE` shows the bundle's new text for a file that stays behind, so the sections the "stays behind" line names can be read.
|
|
44
|
+
- `chi bundle try` no longer passes the user's dropped settings (guardrails, memories, hooks, log…) to its sandboxed chi through the environment.
|
|
45
|
+
- A bundle's `context_providers:` are skipped when this chi is older than the bundle's `requires_chi`.
|
|
46
|
+
- Reinstalling a bundle from the same source says what it did: `Up to date:` for unchanged files, and a last line naming what was rewritten and which of your memories were kept.
|
|
47
|
+
- A `files:` entry with no checksum no longer warns "Checksum mismatch" on every install.
|
|
48
|
+
- Objectives proposal cards no longer appear after a canceled or failed turn.
|
|
49
|
+
- A `delegate` child in a linked worktree is no longer told to re-delegate to the main checkout.
|
|
50
|
+
|
|
51
|
+
Update with `chi update` (agents-md 0.1.2, btw 0.1.4, loop-guard 0.3.10, mcp 0.7.6, skills 0.1.9, slow-commands 0.2.5: their `requires_chi` now names the chi that reads their settings).
|
|
52
|
+
|
|
10
53
|
## [0.151.0] - 2026-11-05
|
|
11
54
|
|
|
12
55
|
### Added
|
|
@@ -5690,7 +5733,9 @@ and long-lived sessions.
|
|
|
5690
5733
|
- A macOS desktop helper (`chi desktop install`): a "Send to chi" Service and a
|
|
5691
5734
|
hotkey panel that send selected text or the clipboard to your sessions.
|
|
5692
5735
|
|
|
5693
|
-
[Unreleased]: https://github.com/dm1try/samagotchi/compare/v0.
|
|
5736
|
+
[Unreleased]: https://github.com/dm1try/samagotchi/compare/v0.153.0...HEAD
|
|
5737
|
+
[0.153.0]: https://github.com/dm1try/samagotchi/compare/v0.152.0...v0.153.0
|
|
5738
|
+
[0.152.0]: https://github.com/dm1try/samagotchi/compare/v0.151.0...v0.152.0
|
|
5694
5739
|
[0.151.0]: https://github.com/dm1try/samagotchi/compare/v0.150.0...v0.151.0
|
|
5695
5740
|
[0.150.0]: https://github.com/dm1try/samagotchi/compare/v0.149.0...v0.150.0
|
|
5696
5741
|
[0.149.0]: https://github.com/dm1try/samagotchi/compare/v0.148.0...v0.149.0
|
data/docs/bundle-authoring.md
CHANGED
|
@@ -119,7 +119,7 @@ end
|
|
|
119
119
|
`questions` record effects; `bundle.answer` / `model_answers` provide `ask_user` / `ask_model` answers.
|
|
120
120
|
`bundle.judgments` answers `ctx.judge` and records its asks and runs (each judgment is on in the kit, off in chi until the user sets it);
|
|
121
121
|
`bundle.http.stub` stubs `ctx.http`; `bundle.question_asked(text, question:)` fires `:question_asked` and returns
|
|
122
|
-
the refs; `sandbox.config`, `sandbox.fake_executable` and `bundle.install` cover setup.
|
|
122
|
+
the refs; `sandbox.config`, `sandbox.fake_executable` and `bundle.install` cover setup. The kit's `ctx.declared_tools` is every tool, as on `full`; in chi a `chi.tool` is declared only on `full` and by a kit's `add:`, and on `lean` or `child` the model reaches it with `find_tools` (`chi/<name>`) and `call_tool` ([Toolkits](configuration.md#toolkits)), so `bundle.set(declared_tools: %w[read])` tests that case and the tool's description should be easy to search.
|
|
123
123
|
The full list is in [plugins.md, Testing a bundle](plugins.md#testing-a-bundle-experimental). The kit is
|
|
124
124
|
experimental (it may change before chi 1.0). A failing matcher that meets `ENV` prints `#<the process ENV, contents not shown>`, not your keys. If a test needs a fake of chi's own (a stub of a `Samagotchi::`
|
|
125
125
|
class, a hand-built `ctx`), that is a gap in the kit: say so to the user rather than reaching into chi.
|
|
@@ -129,10 +129,10 @@ class, a hand-built `ctx`), that is a gap in the kit: say so to the user rather
|
|
|
129
129
|
- **Shas.** Every file the manifest names has a sha256 line, and an edit makes it stale: the install then warns
|
|
130
130
|
of a checksum mismatch, and a line with no sha installs unchecked. `chi bundle check --fix` rewrites them; run it
|
|
131
131
|
after the last edit.
|
|
132
|
-
- **requires_chi.** Use the chi the user runs (`chi --version`)
|
|
133
|
-
newer than the floor (`ctx.http`
|
|
134
|
-
|
|
135
|
-
0.
|
|
132
|
+
- **requires_chi.** Use the chi the user runs (`chi --version`): a bundle whose `requires_chi` that chi doesn't
|
|
133
|
+
meet is now **refused at install** (`--force` is the only way past it), not just unloaded. `check` warns when the plugin calls something newer than the floor (`ctx.http` 0.80.0, `ctx.cost` 0.83.0, `ctx.usage` 0.100.0, `ctx.sessions.children` 0.34.0),
|
|
134
|
+
or a keyword added later (`ctx.ask_model(model:)` 0.80.0, `ctx.sessions.send(delivery:)` 0.64.0, `chi.toolkit(prompt:)` 0.72.0, `chi.toolkit(groups:)` 0.121.0), written on `ctx` / `chi` itself rather than through a variable,
|
|
135
|
+
or when the manifest itself uses a key newer than the floor (`block_renderers:` 0.151.0, `settings:` 0.143.0, `session_settings:` 0.84.0, `context_providers:` 0.32.0): an older chi ignores that key.
|
|
136
136
|
- **A typo in an API call.** `check` warns (`api`) on a call or keyword this chi lacks, on any path; for a newer chi on purpose, guard it with `ctx.respond_to?(:name)`.
|
|
137
137
|
- **trust_level.** Leave it out. `reviewed` / `trusted` are for someone who reviewed the bundle, not its author.
|
|
138
138
|
- **Restart.** A session loads bundles when it starts: after an install or a settings change, the user starts a
|
data/docs/bundles.md
CHANGED
|
@@ -225,6 +225,90 @@ bundles:
|
|
|
225
225
|
tools, or with different args, stay distinct, since the tool is in the
|
|
226
226
|
args).
|
|
227
227
|
|
|
228
|
+
## The web-search bundle
|
|
229
|
+
|
|
230
|
+
`chi bundle install web-search` installs the bundle shipped with chi (`lib/samagotchi/bundles/web-search/plugin.rb`).
|
|
231
|
+
No profile includes it, since it needs a running [SearXNG](https://docs.searxng.org), so `chi update` lists it as
|
|
232
|
+
not installed until you install it. It gives the model one tool, `web_search`, which asks your SearXNG through its
|
|
233
|
+
JSON API. `web_fetch` fetches a URL but can't find one; `web_search` finds them, and the model then reads the ones it
|
|
234
|
+
wants with `web_fetch`. It is an ordinary plugin tool, so it works on every host and loop.
|
|
235
|
+
|
|
236
|
+
- **The tool:** `web_search(query, time_range?, page?)`. `time_range` is `day`, `week`, `month` or `year`; `page`
|
|
237
|
+
starts at 1. It returns plain text: a header, the first answer SearXNG gives (if any), a numbered list of results
|
|
238
|
+
(title, URL, and a snippet of at most 300 characters), and SearXNG's suggestions:
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
SearXNG results for "ruby prism parser" (page 1):
|
|
242
|
+
1. Prism — Ruby parser
|
|
243
|
+
https://github.com/ruby/prism
|
|
244
|
+
A portable, error-tolerant Ruby parser…
|
|
245
|
+
Suggestions: ruby prism gem, prism vs parser
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
With nothing found it says `No results for "<query>".` and names the engines that failed. A SearXNG that can't be
|
|
249
|
+
reached, a 403 (JSON not enabled), a 429 (its limiter) or an answer that isn't JSON each give an `Error:` line that
|
|
250
|
+
says what to fix.
|
|
251
|
+
|
|
252
|
+
```yaml
|
|
253
|
+
# config.yml
|
|
254
|
+
bundles:
|
|
255
|
+
web-search:
|
|
256
|
+
url: http://127.0.0.1:8888 # the SearXNG root
|
|
257
|
+
max_results: 8 # results listed, 1..20
|
|
258
|
+
timeout: 10 # seconds per read
|
|
259
|
+
# optional, sent only when set:
|
|
260
|
+
language: en
|
|
261
|
+
safesearch: 0 # 0, 1 or 2
|
|
262
|
+
categories: general # comma-separated
|
|
263
|
+
engines: duckduckgo,brave # comma-separated
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
| key | default | |
|
|
267
|
+
|---|---|---|
|
|
268
|
+
| `url` | `http://127.0.0.1:8888` | the SearXNG root, `http` or `https` with a host; a trailing `/` is fine |
|
|
269
|
+
| `max_results` | `8` | clamped to 1..20 |
|
|
270
|
+
| `timeout` | `10` | seconds; a value that isn't a positive number uses the default |
|
|
271
|
+
| `language` | unset | unset (the default): SearXNG picks the language from the query; set it (e.g. `en`) to force one; dates and some results may follow your region |
|
|
272
|
+
| `safesearch` | unset | `0`, `1` or `2` |
|
|
273
|
+
| `categories`, `engines` | unset | comma-separated. SearXNG silently drops names it doesn't know, so a typo gives its defaults |
|
|
274
|
+
|
|
275
|
+
- **Privacy:** the query goes to your SearXNG and on to the engines it is configured with. No guardrail rule asks
|
|
276
|
+
about it by default; add one (`tool: web_search`, `verdict: ask`) if you want to approve each search. A review
|
|
277
|
+
turn can't call it.
|
|
278
|
+
- **Toolkits:** the tool follows a kit's list like a built-in ([Toolkits](configuration.md#toolkits)). `full` (and
|
|
279
|
+
any kit on `base: full`) declares it (about 150 tokens per request); on `lean`, `child` and the kits built on them
|
|
280
|
+
it is reachable, not declared: the model finds it with `find_tools` (`chi/web_search`) and calls it with
|
|
281
|
+
`call_tool` (on `api: anthropic` it goes deferred and is called by name). To declare it on such a kit, `add:` it
|
|
282
|
+
(or `/toolkit add web_search` in a session); to keep it away entirely, `remove:` it (or `/toolkit remove
|
|
283
|
+
web_search`).
|
|
284
|
+
|
|
285
|
+
```yaml
|
|
286
|
+
toolkit:
|
|
287
|
+
default: search
|
|
288
|
+
kits:
|
|
289
|
+
search: { base: lean, add: [web_search] }
|
|
290
|
+
quiet: { base: full, remove: [web_search] }
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Running SearXNG locally
|
|
294
|
+
|
|
295
|
+
```sh
|
|
296
|
+
mkdir -p searxng
|
|
297
|
+
cat > searxng/settings.yml <<'YAML'
|
|
298
|
+
use_default_settings: true
|
|
299
|
+
server:
|
|
300
|
+
secret_key: "change-me-to-a-random-string" # openssl rand -hex 32
|
|
301
|
+
limiter: false # a local instance: no rate limiting (else 429s)
|
|
302
|
+
search:
|
|
303
|
+
formats: [html, json] # json is off by default (else 403)
|
|
304
|
+
YAML
|
|
305
|
+
docker run -d --name searxng -p 127.0.0.1:8888:8080 -v ./searxng:/etc/searxng searxng/searxng
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
The port is bound to loopback, not the LAN. Under colima, run it from a folder in your home directory: colima
|
|
309
|
+
shares only that with its VM by default, and elsewhere SearXNG starts on its own default settings (JSON off).
|
|
310
|
+
`curl 'http://127.0.0.1:8888/search?q=ruby&format=json'` should answer JSON.
|
|
311
|
+
|
|
228
312
|
## The loop-guard bundle
|
|
229
313
|
|
|
230
314
|
`chi bundle install loop-guard` installs the bundle shipped with chi (`chi
|
data/docs/cli.md
CHANGED
|
@@ -36,12 +36,12 @@
|
|
|
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 `big memories` the memories over `memory.entry_warn_tokens` ([Memory](memory.md#a-memorys-size)), 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, and check the bundles from elsewhere, in one table (see [Updating](#updating))
|
|
38
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 and what should follow it, one row each with `ok`, `warn` or `fail` and what to run (exit 1 on a `fail`; see [Checking it](configuration.md#checking-it-chi-home-doctor)). At a terminal, a chi on another Ruby than the home's says so in one dim line a day. This machine only (see [The chi home](configuration.md#the-chi-home))
|
|
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), [Bundles](bundles.md#the-btw-bundle), [the mcp bundle](bundles.md#the-mcp-bundle) [the loop-guard bundle](bundles.md#the-loop-guard-bundle), [the check-in bundle](bundles.md#the-check-in-bundle) and [the skills bundle](bundles.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
|
+
- `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; `upgrade <name>` upgrades an installed bundle by name from the source it came from (its folder, archive or git URL), `upgrade <source>` from a new one; `core` and `dev` are profiles that install a set of them (see [Bundle profiles](memory.md#bundle-profiles-core-and-dev), [Guardrails](guardrails.md), [Bundles](bundles.md#the-btw-bundle), [the mcp bundle](bundles.md#the-mcp-bundle) [the loop-guard bundle](bundles.md#the-loop-guard-bundle), [the check-in bundle](bundles.md#the-check-in-bundle) and [the skills bundle](bundles.md#the-skills-bundle)). `trash` lists and empties the bundle trash (moved files from uninstalls/upgrades). `install`/`upgrade` `--force` overwrites existing entries and also installs a bundle whose `requires_chi` this chi doesn't meet; without it such a bundle is refused (exit 1), nothing written. A plain `install` of a bundle that is already installed from the same source rewrites its hooks, rules, plugin, scripts and record: the summary lists a file that already holds the bundle's bytes as `Up to date: …`, one you wrote as `Skipped: …`, and ends with `NAME was already installed from SOURCE: its hooks, rules, plugin and scripts now match it and its record was rewritten` (plus, when a memory was kept, `your own copies of its memories were kept (chi bundle upgrade NAME merges the bundle's changes into them)`). 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)
|
|
40
40
|
|
|
41
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))
|
|
42
42
|
- `chi guardrails rule <id>` — print exactly `asks` when that rule is loaded, not disabled and votes `ask` in this `guardrails.mode` for every model; any other line says why not (no such rule, disabled, another mode, it denies, for some models only, rules that failed to load, `guardrails.enabled: false`). Exit 0 either way, 2 for a usage error. It reads config.yml and the installed bundles as a worker does (`GuardrailWiring#rules`) and takes the rule's id, never a command; the [coordinator skill](bundles.md#the-coordinator-bundle) reads it before it merges without asking
|
|
43
43
|
- `chi judgments ls` / `chi judgments report NAME [--days N]` — what [System 1's saved runs](system-one.md) hold: each judgment's digests, runs, labels, failures, models and size; one judgment's counts, p histogram and labels by value. Reads only; local only; `--days` must be a positive whole number.
|
|
44
|
-
- `chi toolkit report [--days N]` — grade toolkit suggestions: the kit on mode would have run (the suggested kit when it would have applied it, else the default; an on-mode line's `did` says what it ran) against the tools the session called from that turn on (only that turn when the toolkit was chosen since), `call_tool` targets included, for both the chat and the raw-prompt loop. Each is *covers*, *short of a tool* (naming the tools), *wider than needed* (a narrower kit offered in the same ask would also have covered) or *ungradable* (calls it can't read back); then a per-kit tally with what on mode would have done. Includes archived sessions and caps the report at 14 days and 500 sessions. Reads `toolkit_suggestions.jsonl` (each ask logs every offered kit's rules, expanded against the called tools here); it never runs the model or changes a session. Local only; `--days` must be a positive whole number.
|
|
44
|
+
- `chi toolkit report [--days N]` — grade toolkit suggestions: the kit on mode would have run (the suggested kit when it would have applied it, else the default; an on-mode line's `did` says what it ran) against the tools the session called from that turn on (only that turn when the toolkit was chosen since), `call_tool` targets included, for both the chat and the raw-prompt loop. Each is *covers*, *short of a tool* (naming the tools; a built-in or plugin tool the kit left reachable but didn't declare counts), *wider than needed* (a narrower kit offered in the same ask would also have covered) or *ungradable* (calls it can't read back); then a per-kit tally with what on mode would have done. Includes archived sessions and caps the report at 14 days and 500 sessions. Reads `toolkit_suggestions.jsonl` (each ask logs every offered kit's rules, expanded against the called tools here); it never runs the model or changes a session. Local only; `--days` must be a positive whole number.
|
|
45
45
|
|
|
46
46
|
- `chi bundle try PATH -p TEXT [options]` — install a bundle in a temporary, filtered sandbox, run one real model turn,
|
|
47
47
|
and print its trace (see [Trying a bundle](#trying-a-bundle)).
|
|
@@ -133,8 +133,10 @@ The loop for a bundle you're writing (the whole path: [bundle-authoring.md](bund
|
|
|
133
133
|
chi's Ruby (minitest is one of chi's gems; rspec is optional). The tests run the bundle's code as written, with
|
|
134
134
|
your environment (the kit sandboxes each test's HOME and XDG dirs, not the process).
|
|
135
135
|
- `chi bundle install --dev PATH` installs the bundle in the local directory `PATH` (not a git URL, archive or name:
|
|
136
|
-
exit 2) as a link to it: its plugin, hooks, rules and
|
|
137
|
-
next worker or `chi web` restart with no re-install
|
|
136
|
+
exit 2) as a link to it: its plugin, hooks, rules, scripts and `manifest.yml` are `PATH`'s own files, so an edit applies at the
|
|
137
|
+
next worker or `chi web` restart with no re-install (a manifest edit to `block_renderers:` shows in chi web's next
|
|
138
|
+
request; a new `scripts:`, `hooks:` or `plugin:` entry needs `chi bundle install --dev PATH` again, since the record
|
|
139
|
+
has no entry for it), and their sha256 isn't checked, for this bundle only (the
|
|
138
140
|
record says `dev`; every other bundle is checked as before). Its memories are copied at install. `chi bundle
|
|
139
141
|
status` shows `NAME vX dev → /abs/path`. `chi bundle upgrade NAME` refuses it (it follows its source already; to
|
|
140
142
|
leave dev mode: `chi bundle uninstall NAME`, then `chi bundle install` without `--dev`), as does a plain install
|
|
@@ -147,9 +149,13 @@ The loop for a bundle you're writing (the whole path: [bundle-authoring.md](bund
|
|
|
147
149
|
so run it (and `test`) on code you'd install. The codes, in order: `manifest` (a parse error, verbatim; the run
|
|
148
150
|
stops), `missing-file`, `unlisted` (warn: a file an install leaves out, by `MemoryFiles`' rules, so a README
|
|
149
151
|
isn't one), `sha` (a stale or placeholder sha, or a plugin / hook / script entry with no sha line; `--fix`
|
|
150
|
-
rewrites the first two and prints `fixed sha FILE → sha256:…`), `
|
|
152
|
+
rewrites the first two and prints `fixed sha FILE → sha256:…`), `unknown-key` (warn: a manifest key this chi's
|
|
153
|
+
parser never reads, so it ignores it, one row per key at its line; the install keeps the manifest, so a newer
|
|
154
|
+
chi reads the key from it with no reinstall, and `chi update`'s re-check names it too), `requires-chi` (this chi doesn't satisfy it:
|
|
151
155
|
error; missing on a bundle with code: warn), `requires-chi-floor` (warn: the plugin calls an API newer than the
|
|
152
|
-
oldest chi `requires_chi` admits, from `Plugin::Api::SINCE
|
|
156
|
+
oldest chi `requires_chi` admits, from `Plugin::Api::SINCE`, or the manifest itself uses a key newer than it, from
|
|
157
|
+
`Manifest::SINCE`; an installed bundle gets the unknown-key row but never the floor, as it's the author's fix),
|
|
158
|
+
`trust` (warn: `trust_level: reviewed|trusted` on a
|
|
153
159
|
bundle chi doesn't ship), `clash` (warn: a name chi ships, or one installed from elsewhere; the sandboxed install
|
|
154
160
|
then forces), `install` (each Installer warning, a `needs` one as warn, and each plugin or hook load failure at
|
|
155
161
|
the source `file:line`; skipped while a placeholder sha is unfilled), `registered` (info: each command, tool,
|
|
@@ -313,7 +319,7 @@ Also shipped, not installed: dev (mcp, skills, source-links) (chi bundle install
|
|
|
313
319
|
file in the bundle trash and `merged 0.8.0 into your FILE` in the row. A real
|
|
314
320
|
conflict, no `git`, or no recorded base keeps your file untouched, and the row
|
|
315
321
|
says `FILE stays behind 0.8.0:` with why and what it missed (up to three headings
|
|
316
|
-
and a count, or `2 places`). `chi bundle diff NAME FILE` shows it; `chi bundle
|
|
322
|
+
and a count, or `2 places`). `chi bundle diff NAME FILE` shows it (the base, your file, then the bundle's new text); `chi bundle
|
|
317
323
|
upgrade NAME --force` takes the bundle's, with a copy of yours in the bundle
|
|
318
324
|
trash first. A later run retries such a file at the same version: its row reads
|
|
319
325
|
`0.8.0 merged 0.8.0 into your FILE` when it merges, and names it as behind when
|
|
@@ -367,6 +373,26 @@ Also shipped, not installed: dev (mcp, skills, source-links) (chi bundle install
|
|
|
367
373
|
update` again). A failed gem install checks against this chi, since it stays.
|
|
368
374
|
- `--no-bundles` (`update.bundles: false`) leaves these out too: no check, no row
|
|
369
375
|
but `bundles skipped`.
|
|
376
|
+
- **Bundles installed by an older chi** have no kept `manifest.yml` (it didn't
|
|
377
|
+
keep it), so chi reads what their install recorded, and a manifest
|
|
378
|
+
key that chi didn't know (`block_renderers:` before 0.151.0) is missing. Where
|
|
379
|
+
chi has the bundle's own manifest at the installed version, the update keeps it,
|
|
380
|
+
once: a shipped bundle from chi's shipped copy (`up to date (kept its manifest)`;
|
|
381
|
+
the system bundle at the next chi start), a bundle from a folder or a zip/tar
|
|
382
|
+
that is still there from it (a `kept its manifest` row; the archive is extracted
|
|
383
|
+
and the extract removed). Only when the source is what's installed: the same
|
|
384
|
+
name and version, the same manifest values as the install recorded (a key the
|
|
385
|
+
older chi didn't know aside), and the same memories, plugin, hooks, scripts and rules. A git source
|
|
386
|
+
isn't cloned: the row names the command,
|
|
387
|
+
`installed by an older chi, which didn't keep its manifest: chi bundle upgrade NAME reads it again from URL`.
|
|
388
|
+
A source that's gone or doesn't match gets its own row (why, and what to run: for
|
|
389
|
+
a gone one, `NAME's recorded source S is gone: chi bundle upgrade <path or URL of a copy>`). The
|
|
390
|
+
same goes for a record an older chi rewrote after a newer one kept the manifest
|
|
391
|
+
(`an older chi rewrote its record after the install, so its manifest.yml may be an
|
|
392
|
+
earlier version's`). `--dry-run` says `would keep its manifest` and writes nothing.
|
|
393
|
+
An edited `manifest.yml` isn't kept over: its row says so (`chi bundle upgrade
|
|
394
|
+
NAME`). These rows are warnings and fail nothing; `chi bundle status NAME` says the
|
|
395
|
+
same on its `Manifest:` line.
|
|
370
396
|
- **Profiles** (`core`, `dev`): an installed one installs the bundles a new
|
|
371
397
|
chi added to it (`updated (+ name)`), even at the same version, and retries
|
|
372
398
|
one that failed before; one you uninstalled stays out. See [Bundle
|
|
@@ -425,7 +451,7 @@ invalid option (exit 1).
|
|
|
425
451
|
| `--dir DIR` | With `--remote`: a new session's folder on that machine, its absolute path (required for a new session there). Without `--remote` it exits 2: cd there instead. |
|
|
426
452
|
| `--model NAME` | Use this model for the run (overrides the configured default and a resumed session's model). |
|
|
427
453
|
| `--thinking LEVEL` | This session's own thinking level: `off`, `low`, `medium` or `high`, saved in the session and first in the order (`default` unsets it). On `--resume` or `--attach` it is set at once, through a `/thinking` on an attached worker. With `chi web` it is instead the default for the sessions its workers run, below a session's own (as env `SAMAGOTCHI_THINKING_LEVEL` is). See "Thinking" in configuration.md. |
|
|
428
|
-
| `--toolkit NAME`, `--tool NAME`, `--no-tool NAME` | A new session's toolkit, the tools its prompts declare: `full` (every built-in), `lean`, `child`, one of config's `toolkit.kits` or a bundle's (without `--toolkit`: config's `toolkit.default`), with tools declared on top of it (`--tool`) or left out (`--no-tool`); both repeatable, a comma list too. Saved in the session as given; a respawned worker, a fork and a continue keep it. Ignored with `--attach`/`--resume` (one line, as `--memory`); `/toolkit` changes it. Not on `chi web` (config's `toolkit.default` covers its sessions). See [Toolkits](configuration.md#toolkits). |
|
|
454
|
+
| `--toolkit NAME`, `--tool NAME`, `--no-tool NAME` | A new session's toolkit, the tools its prompts declare: `full` (every built-in and plugin tool), `lean`, `child`, one of config's `toolkit.kits` or a bundle's (without `--toolkit`: config's `toolkit.default`), with tools declared on top of it (`--tool`) or left out (`--no-tool`); both repeatable, a comma list too. Saved in the session as given; a respawned worker, a fork and a continue keep it. Ignored with `--attach`/`--resume` (one line, as `--memory`); `/toolkit` changes it. Not on `chi web` (config's `toolkit.default` covers its sessions). See [Toolkits](configuration.md#toolkits). |
|
|
429
455
|
| `--parent-answers LEVEL` | A new session's own `guardrails.parent_answers` (`hard`, `standard` or `soft`): what a parent agent may answer on its questions. It may only tighten config.yml's: the stricter of the two applies, and a looser one is saved as given with a warning (`--parent-answers soft is looser than config.yml's guardrails.parent_answers: standard; standard applies`). Saved in the session; a respawned worker, a fork and a continue keep it, a `delegate` child takes its parent's. Ignored with `--attach`/`--resume` (one line, as `--toolkit`); refused with `chi web`. Only you loosen it: `/parent-answers` in the terminal or the web. See [Guardrails](guardrails.md#answers-from-a-parent-agent). |
|
|
430
456
|
| `--set KEY=VALUE` | A setting for a new session (repeatable; a later one of the same key wins). A core key a session may set (`recap.enabled`, `recap.sentences`) is typed by the key and goes first, over the CLI, env and config.yml: `--set recap.enabled=false` turns the idle recap off for this session; a value it doesn't take (`recap.enabled=maybe`) or a key no session sets (`guardrails.mode`) is an error, exit 2 (see [Per-session settings](configuration.md#per-session-settings)). Any other name is a bundle's `BUNDLE.KEY`, laid over config.yml's `bundles: <bundle>:` in what the bundle's plugin reads (`ctx.settings`): `--set cost-cap.cap=3`. The value is typed simply: an integer (`3`, `-1`) or a decimal (`2.5`, `.5`, `1e1`) is a number, `true`, `yes` and `on` are true, `false`, `no` and `off` are false (any case, as in config.yml), anything else stays the text as given (`010`, `0x10`, `3:30`, `y`, `null`), and so does every value of a key the manifest types `string`. For cost-cap, `0`, a negative number or `off` is no cap. Only a key the installed bundle's manifest lists in `session_settings:` is taken, with a value of the type it gives the key: a bundle that isn't installed (or whose plugin doesn't load), a key it doesn't list (a record installed before the bundle listed it says to run `chi update` or `chi bundle upgrade NAME`), a value of another type (`--set cost-cap.cap=five`), or another shape (`--set foo`, `--set a.b.c=1`) is an error naming what it takes, exit 2, nothing started. Saved in the session; a respawned worker, a fork and a continue keep it, a delegate child doesn't. Ignored with `--attach`/`--resume` (one line, as `--toolkit`); refused with `chi web`. See [Per-session settings](plugins.md#per-session-settings). |
|
|
431
457
|
| `--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. |
|
|
@@ -862,7 +888,7 @@ line, the web in the session bar's ⚙ panel (`⚙ reasoning all` once the sessi
|
|
|
862
888
|
|
|
863
889
|
`/toolkit` lists the tools the next turn declares (each with its estimated
|
|
864
890
|
tokens), the session's toolkit and the tools it leaves out: `reachable
|
|
865
|
-
(find_tools): …` (built-ins the model reaches with find_tools and call_tool)
|
|
891
|
+
(find_tools): …` (built-ins and plugin tools the model reaches with find_tools and call_tool)
|
|
866
892
|
and `removed: …` (only `/toolkit add` brings one back), or `not loaded: …` when
|
|
867
893
|
the toolkit removes call_tool, and its kit's prompt text when it has one (`prompt: <first line> (+N lines, ~T
|
|
868
894
|
tokens)`). `/toolkit remove TOOL` is hard: a tool the
|
|
@@ -907,7 +933,6 @@ the model's `objectives` tool); [Objectives](sessions.md#objectives) has what th
|
|
|
907
933
|
- `/objectives done O1 [O2…]`, `/objectives drop O1 [O2…]`: mark items. An id it doesn't have refuses the whole line, and
|
|
908
934
|
so does `done` on a dropped item. The model is shown a done item as `O1 [done] …` and no dropped one.
|
|
909
935
|
- `/objectives undo O1 [O2…]`: back to active, after a mistaken `done` or `drop`.
|
|
910
|
-
|
|
911
936
|
- `/objectives check O1`: an independent read of O1's latest move, one side request; the verdict comes as a card and as
|
|
912
937
|
`check: …` under the move. Information only: it edits nothing, and it is refused for an objective with no move or a dropped one, and during a participant's turn. See [Objectives](sessions.md#objectives).
|
|
913
938
|
|
data/docs/configuration.md
CHANGED
|
@@ -1501,17 +1501,18 @@ toolkit:
|
|
|
1501
1501
|
|
|
1502
1502
|
| toolkit | declares |
|
|
1503
1503
|
|---|---|
|
|
1504
|
-
| `full` | every built-in; the default |
|
|
1504
|
+
| `full` | every built-in and every plugin tool (a bundle's `chi.tool`, such as `web_search`); the default |
|
|
1505
1505
|
| `lean` | `execute`, `read`, `write`, `edit`, `memory_read`, `memory_write`, `task_create`, `task_wait`, `task_get`, `task_list`, `task_stop`, `ask_user_question`, `web_fetch`, `context_read` |
|
|
1506
1506
|
| `child` | `lean` plus `send_note`, without `memory_write`, `delegate`, `delegate_result` |
|
|
1507
1507
|
| `coordinator` | `lean` plus `delegate`, `delegate_result`, `list_sessions`, `objectives` (declared by the coordinator bundle) |
|
|
1508
1508
|
| `coding` | `child`, with the prompt text `- Be concise in your responses` / `- Show file paths clearly when working with files` (declared by the coordinator bundle, for build and fix children) |
|
|
1509
1509
|
| `review` | `read`, `memory_read` (not `forget_outputs`, even under the `forget` layer): what a [participant's](internals/participants.md#turns) turn may call, whatever the session declares (the review boundary, [guardrails](guardrails.md#a-participants-review-boundary)). Reserved: `toolkit.kits.review` is refused ("review is reserved for participants' turns"), and a bundle can't declare it. A session may run on it too, as any kit |
|
|
1510
1510
|
|
|
1511
|
-
- **Plugin tools**
|
|
1512
|
-
|
|
1513
|
-
`
|
|
1514
|
-
|
|
1511
|
+
- **Plugin tools** (a bundle's `chi.tool`, such as web-search's `web_search`) follow a kit's list as built-ins do:
|
|
1512
|
+
`full` (and every kit on `base: full`, the `kits:` default) declares them, another kit leaves them **reachable**
|
|
1513
|
+
(below) unless its `remove:` names them, and `add:` declares one (`search: { base: lean, add: [web_search] }`).
|
|
1514
|
+
`forget_outputs` is declared in every toolkit under the `forget` layer, unless removed. A `kits:` entry takes
|
|
1515
|
+
`base:` (default `full`), `add:`, `remove:`, `prompt:`, `groups:` and `description:` (any other key, a typo or a `tools:` list, is ignored with a warning); it can't reuse a built-in's name
|
|
1515
1516
|
(`review`'s least of all: it is the participants' boundary). A bundle declares its own with `chi.toolkit`
|
|
1516
1517
|
([plugins](plugins.md#chitoolkitname-base-add--remove--prompt-nil-groups-nil-description-nil)).
|
|
1517
1518
|
`description:` is optional classifier input, up to 300 characters; it is not included in the session prompt.
|
|
@@ -1565,7 +1566,7 @@ toolkit:
|
|
|
1565
1566
|
reaches none. A kit whose base doesn't resolve (an unknown name, a cycle) falls back to `full`, which reaches
|
|
1566
1567
|
every group.
|
|
1567
1568
|
A selector that matches no group in that load-time snapshot warns once. `find_tools` and `call_tool` are
|
|
1568
|
-
declared only when the toolkit reaches a source group or has a reachable built-in. Calls naming an unreached
|
|
1569
|
+
declared only when the toolkit reaches a source group or has a reachable tool (a built-in or a plugin tool). Calls naming an unreached
|
|
1569
1570
|
group are refused before guardrails and do not start its server. The first-run init wait is unchanged: it can
|
|
1570
1571
|
still block the first turn even when its server's group is unreached; `start: eager` and stale-cache refreshes
|
|
1571
1572
|
also still start. `/mcp` marks servers outside the current toolkit.
|
|
@@ -1599,17 +1600,21 @@ toolkit:
|
|
|
1599
1600
|
them with `/toolkit`. The configured default is always listed. A pick closes the list and shows a `tools: lean`
|
|
1600
1601
|
chip on the row (a dot on 🧰 on a phone); it is for that create only, never remembered. A review session is
|
|
1601
1602
|
always `chosen`: with review files set the list says it starts on the default unless you pick a kit.
|
|
1602
|
-
- **Left out: reachable or removed.** A built-in missing from a kit's base list (`lean` has no
|
|
1603
|
-
`kits:` entry on `base: lean` or `child` inherits that) is left out softly: it
|
|
1604
|
-
|
|
1605
|
-
|
|
1603
|
+
- **Left out: reachable or removed.** A built-in or plugin tool missing from a kit's base list (`lean` has no
|
|
1604
|
+
`delegate` and no `web_search`; a `kits:` entry on `base: lean` or `child` inherits that) is left out softly: it
|
|
1605
|
+
is **reachable**. `find_tools` searches it as group `chi` (`chi/delegate`, `chi/web_search`, with its
|
|
1606
|
+
inputSchema) beside the MCP servers' tools, and `call_tool(tool: "chi/delegate", args: {…})` runs it as `delegate`
|
|
1607
|
+
itself, through the usual guardrails, approvals and hooks ([plugins](plugins.md#chitool_sourcecall-acts_as-label-wait-prefix)). A
|
|
1606
1608
|
tool in a toolkit's `remove:`, a `--no-tool` or a `/toolkit remove` is **removed**: hard, also after an add, and
|
|
1607
1609
|
call_tool can't reach it (`child` removes `memory_write`, `delegate` and `delegate_result`, so a child on it
|
|
1608
|
-
starts no children). To keep a
|
|
1609
|
-
are declared when a toolkit has a reachable
|
|
1610
|
-
|
|
1610
|
+
starts no children). To keep a tool away from the model, name it under `remove:`. `find_tools` and `call_tool`
|
|
1611
|
+
are declared when a toolkit has a reachable tool or reaches a source group, as the tools stood when the
|
|
1612
|
+
session's worker started; `full` with no reachable source declares neither, and removing them there
|
|
1613
|
+
(`--no-tool call_tool`) leaves nothing out: no prompt line, no chip. A plugin tool that arrives later
|
|
1614
|
+
(`chi.replace_tools`) on a kit that declared neither stays out of reach for that worker, with one warn notice
|
|
1615
|
+
(`/toolkit add NAME` declares it).
|
|
1611
1616
|
- **On `api: anthropic`, reachable tools are callable by name.** Every tool `call_tool` reaches (the reachable
|
|
1612
|
-
built-ins, tools from reached MCP groups as `mcp_<server>_<tool>`) also goes in the request's tools deferred
|
|
1617
|
+
built-ins and plugin tools, tools from reached MCP groups as `mcp_<server>_<tool>`) also goes in the request's tools deferred
|
|
1613
1618
|
(`defer_loading`: Messages keeps them out of the model's view until something loads them, at a flat ~100 tokens).
|
|
1614
1619
|
A direct call of one (`list_sessions`, `mcp_fs_read`) runs, under the same guardrails, approvals and rows as
|
|
1615
1620
|
through `call_tool` (an MCP tool's call is `call_tool`'s). A `find_tools` hit **loads** its matches (up to 5):
|
data/docs/guardrails.md
CHANGED
|
@@ -841,11 +841,13 @@ trade-off, when such a clash exists:
|
|
|
841
841
|
- deny rules cover both, which is the point.
|
|
842
842
|
|
|
843
843
|
A `call_tool` of one of chi's own tools (`chi/delegate`: a built-in the
|
|
844
|
-
session's toolkit leaves out, [toolkits](configuration.md#toolkits))
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
844
|
+
session's toolkit leaves out, [toolkits](configuration.md#toolkits)), or of
|
|
845
|
+
a bundle's `chi.tool` it leaves out (`chi/web_search`), is gated **as that
|
|
846
|
+
tool**: it is turned into the `delegate` call before the guardrails run, so
|
|
847
|
+
every rule on `delegate` (or `execute`'s `command:`, the `rm` check, a
|
|
848
|
+
delegate child's boundary, a plugin tool's `targets:`) gives the same
|
|
849
|
+
verdict as for a direct call, and an approval is keyed `delegate:…` either
|
|
850
|
+
way. `tool:
|
|
849
851
|
call_tool` rules no longer see such calls, only MCP calls and misses. A
|
|
850
852
|
`chi/` name the toolkit removes is refused before the gate, with no card.
|
|
851
853
|
|
|
@@ -1157,6 +1159,10 @@ the whole call:
|
|
|
1157
1159
|
|
|
1158
1160
|
`decision` is what the judgment led to: `audit` (audit mode), `asked` (on
|
|
1159
1161
|
mode, the user was asked), `auto` (on mode, System 1 answered for the user).
|
|
1162
|
+
When two rules ask about one call the line's `rule` is the one the card names
|
|
1163
|
+
and `other_rules` lists the rest (`Verdict#other_ask_rules`), so a second
|
|
1164
|
+
rule's record (`SystemOne::Record`) counts the ask too; a line with one rule
|
|
1165
|
+
has no `other_rules` at all.
|
|
1160
1166
|
A judgment that never arrived is logged too, with `p` null, so the failures
|
|
1161
1167
|
count as well. The label line, keyed by the judgment's id, is what the user
|
|
1162
1168
|
did: `allow_once`, `allow_wide` (any scope wider than once), `deny`, or
|
data/docs/hooks.md
CHANGED
|
@@ -644,8 +644,9 @@ A `write`'s `content:` is the file text; an `edit` carries `old_text:` and
|
|
|
644
644
|
arguments whole on `args:` (string keys) instead, and its `content:` is those
|
|
645
645
|
arguments as JSON. An MCP tool's call is chi's `call_tool` (its tool index's, which the mcp
|
|
646
646
|
bundle runs): `tool: "call_tool"`, with `args: {"tool" => "<server>/<tool>", "args" => {…}}`.
|
|
647
|
-
A built-in reached through `call_tool` (`chi/delegate`, a tool the
|
|
648
|
-
declare) fires as that
|
|
647
|
+
A built-in or plugin tool reached through `call_tool` (`chi/delegate`, `chi/web_search`: a tool the
|
|
648
|
+
session's toolkit doesn't declare) fires as that tool, its call built as a direct call's, with
|
|
649
|
+
`call[:via] == "call_tool"`.
|
|
649
650
|
A hook that drops `via:` or rewrites the call to a tool the toolkit removes gets the call refused
|
|
650
651
|
by its name.
|
|
651
652
|
On a Messages host (`api: anthropic`), the model may call those tools by their own names (they
|
|
@@ -710,7 +711,7 @@ Notes:
|
|
|
710
711
|
- Ordering: bundle hooks fire by `(priority, bundle_name, hook_name)` (lower priority first), then plain `config.yml` hooks in registration order.
|
|
711
712
|
- Settings: a hook class with `initialize(settings = {})` gets the bundle's section of `config.yml` `bundles:` (see [Settings](#settings)).
|
|
712
713
|
- A bundle can also ship a `plugin.rb` whose `chi.on(event)` blocks are bundle hooks too, next to commands and tools; see [Plugins](plugins.md). There `ctx.notify`, `ctx.steer` and the other `ctx` helpers act as this page's `event[:notify]`… do for the event the block runs for.
|
|
713
|
-
- Shipped bundles (each in a profile: `core` or `dev`, see [Bundle profiles](memory.md#bundle-profiles-core-and-dev)): `chi bundle install guardrails` (rules, see [Guardrails](guardrails.md#the-guardrails-bundle)) and `chi bundle install known-names` (a hook, see [Guardrails](guardrails.md#the-known-names-bundle)), `chi bundle install source-links` (a hook: announces source refs, see [The source-links bundle](#the-source-links-bundle)), `chi bundle install btw` (a plugin: `/btw`, see [Bundles](bundles.md#the-btw-bundle)), `chi bundle install mcp` (a plugin: tools from MCP servers, see [Bundles](bundles.md#the-mcp-bundle)) `chi bundle install loop-guard` (a plugin: breaks tool-call loops, see [Bundles](bundles.md#the-loop-guard-bundle)), `chi bundle install check-in` (a plugin: checks on a long turn, see [Bundles](bundles.md#the-check-in-bundle)), `chi bundle install slow-commands` (a plugin: commands that ran past the execute limit are run as tasks next time, see [Bundles](bundles.md#the-slow-commands-bundle)), `chi bundle install agents-md` (a plugin: a nested AGENTS.md is steered into the conversation on the first touch under its directory, see [Bundles](bundles.md#the-agents-md-bundle)), `chi bundle install cost-cap` (a plugin: a per-session $ cap, `/cap`, see [Bundles](bundles.md#the-cost-cap-bundle)), `chi bundle install work-cap` (a plugin: a per-session cap on tool calls and active minutes, `/workcap`, see [Bundles](bundles.md#the-work-cap-bundle)), `chi bundle install ruby` (a plugin: an RSpec run with no examples at all, a hint, see [Bundles](bundles.md#the-ruby-bundle)) `chi bundle install skills` (a plugin: `/skill`, versions of skills, see [Bundles](bundles.md#the-skills-bundle)), `chi bundle install github-pr` (attached context: the branch's open PR, see [Bundles](bundles.md#the-github-pr-bundle)), `chi bundle install coordinator` (a plugin: parallel work in worktrees and child sessions, see [Bundles](bundles.md#the-coordinator-bundle)), `chi bundle install claude-peer` / `codex-peer` (a plugin: talk to a Claude Code or Codex session, see [Bundles](bundles.md#the-claude-peer-bundle))
|
|
714
|
+
- Shipped bundles (each but web-search in a profile: `core` or `dev`, see [Bundle profiles](memory.md#bundle-profiles-core-and-dev)): `chi bundle install guardrails` (rules, see [Guardrails](guardrails.md#the-guardrails-bundle)) and `chi bundle install known-names` (a hook, see [Guardrails](guardrails.md#the-known-names-bundle)), `chi bundle install source-links` (a hook: announces source refs, see [The source-links bundle](#the-source-links-bundle)), `chi bundle install btw` (a plugin: `/btw`, see [Bundles](bundles.md#the-btw-bundle)), `chi bundle install mcp` (a plugin: tools from MCP servers, see [Bundles](bundles.md#the-mcp-bundle)) `chi bundle install loop-guard` (a plugin: breaks tool-call loops, see [Bundles](bundles.md#the-loop-guard-bundle)), `chi bundle install check-in` (a plugin: checks on a long turn, see [Bundles](bundles.md#the-check-in-bundle)), `chi bundle install slow-commands` (a plugin: commands that ran past the execute limit are run as tasks next time, see [Bundles](bundles.md#the-slow-commands-bundle)), `chi bundle install agents-md` (a plugin: a nested AGENTS.md is steered into the conversation on the first touch under its directory, see [Bundles](bundles.md#the-agents-md-bundle)), `chi bundle install cost-cap` (a plugin: a per-session $ cap, `/cap`, see [Bundles](bundles.md#the-cost-cap-bundle)), `chi bundle install work-cap` (a plugin: a per-session cap on tool calls and active minutes, `/workcap`, see [Bundles](bundles.md#the-work-cap-bundle)), `chi bundle install ruby` (a plugin: an RSpec run with no examples at all, a hint, see [Bundles](bundles.md#the-ruby-bundle)) `chi bundle install skills` (a plugin: `/skill`, versions of skills, see [Bundles](bundles.md#the-skills-bundle)), `chi bundle install github-pr` (attached context: the branch's open PR, see [Bundles](bundles.md#the-github-pr-bundle)), `chi bundle install coordinator` (a plugin: parallel work in worktrees and child sessions, see [Bundles](bundles.md#the-coordinator-bundle)), `chi bundle install claude-peer` / `codex-peer` (a plugin: talk to a Claude Code or Codex session, see [Bundles](bundles.md#the-claude-peer-bundle)), `chi bundle install model-notes` (memories: reviewed model notes, see [Bundles](bundles.md#the-model-notes-bundle)) and `chi bundle install web-search` (a plugin: a `web_search` tool through your SearXNG, in no profile, see [Bundles](bundles.md#the-web-search-bundle)).
|
|
714
715
|
- Installing a bundle executes its hook code at `Engine` startup. Only install bundles you trust, as you would a gem. Hooks are **not** executed at install time (copy-only); they are `module_eval`'d at `Engine.new` inside per-bundle `Samagotchi::Bundles::<name>` namespaces (no top-level `require` collisions). Keep hook files side-effect-free at load time; do work in `#call` — top-level side effects (require, IO, `at_exit`, global assignment) run once per `Engine.new` (class redefinition is idempotent).
|
|
715
716
|
|
|
716
717
|
Lifecycle:
|
data/docs/internals/anthropic.md
CHANGED
|
@@ -225,7 +225,7 @@ host refused it for that model.
|
|
|
225
225
|
`ChatLoop#tool_definitions(conversation, model:)` appends them (`Tools::DeferredTools.list`) only on such an
|
|
226
226
|
adapter, and only with at least one tool declared (Messages wants one). The list, per request:
|
|
227
227
|
|
|
228
|
-
1. the built-ins the toolkit reaches (`Registry#reachable_names`), in registry order;
|
|
228
|
+
1. the built-ins and plugin tools the toolkit reaches (`Registry#reachable_names`), in registry order;
|
|
229
229
|
2. the tool index's source tools while `call_tool` is declared (`ToolIndex#deferrable`, via
|
|
230
230
|
`Registry::Index#deferrable`): callable, the only tool with its acts_as, a name Messages takes, no registered
|
|
231
231
|
tool's name; by acts_as (`mcp_<server>_<tool>`), sorted by name;
|
|
@@ -270,11 +270,11 @@ sets `:tool_changes` for the model: the retry and every later request drop the s
|
|
|
270
270
|
|
|
271
271
|
A direct call of a deferred tool runs whether something loaded it or not (the API doesn't check): the Engine sets
|
|
272
272
|
`TurnSettings#loads_tools` from the turn's final model (after the before_turn hooks), and then `ToolRunner#run` and
|
|
273
|
-
`KernelLoop#dispatch` take a reachable built-in by its own name (`Registry#indexed`) through the normal gate, and wrap
|
|
273
|
+
`KernelLoop#dispatch` take a reachable built-in or plugin tool by its own name (`Registry#indexed`) through the normal gate, and wrap
|
|
274
274
|
an MCP tool's acts_as into the `call_tool` call it stands for (`ToolIndex#wrap`): `call_tool`'s row, rules and
|
|
275
275
|
approvals. A reload rebuilds that wrapped call from the saved one (`BuiltinCalls.wrap_saved`). Each such call is
|
|
276
276
|
logged (`tool_direct_deferred`, with `loaded:` whether the conversation had loaded it). On `api: openai` and the
|
|
277
|
-
native loop nothing is deferred, and a direct call of a reachable built-in is refused with the `call_tool` route as
|
|
277
|
+
native loop nothing is deferred, and a direct call of a reachable built-in or plugin tool is refused with the `call_tool` route as
|
|
278
278
|
before.
|
|
279
279
|
|
|
280
280
|
## 400 fallbacks
|
|
@@ -35,6 +35,9 @@ Three rules hold the shape:
|
|
|
35
35
|
conversation already holds. Ids are deterministic: `ctx-<name>-<serial>-<revision[0,12]>` (the serial makes A, B, A
|
|
36
36
|
three notes), `ctx-<name>-error-<error_since digits>`, `ctx-<name>-detached-<seen[0,12]>`.
|
|
37
37
|
- **Polling is not activity.** The poller and the absorb never hold a worker up (`WorkerIdleExit`).
|
|
38
|
+
- **The leave absorbs too.** A pass looks at the context and then checks whether it should leave; a change that
|
|
39
|
+
lands in that gap has no later pass (the poller stops with the worker), so `Worker#left` absorbs whatever is
|
|
40
|
+
pending as plain notes before the recap, as it does for a background task that finished in the same gap.
|
|
38
41
|
|
|
39
42
|
## ContextSources
|
|
40
43
|
|
|
@@ -10,7 +10,9 @@ model. The TUI is untouched: it shows a fence as source.
|
|
|
10
10
|
in document order and zips them with the fragment's `<pre>`s, setting `data-lang` after sanitize's walk. Only the first
|
|
11
11
|
word, downcased, matching `BlockRenderers::LANG`. A count that differs sets nothing. **`web.markdown` off means no
|
|
12
12
|
`<pre data-lang>`, so nothing draws.**
|
|
13
|
-
2. `BlockRenderers.for_installed` (manifest `block_renderers:`, read
|
|
13
|
+
2. `BlockRenderers.for_installed` (manifest `block_renderers:`, read through `InstalledBundle#manifest`: the bundle's
|
|
14
|
+
kept `manifest.yml`, else its record's mirror, so chi web needs no plugins, and a bundle installed by a chi that
|
|
15
|
+
didn't know the key draws once a kept manifest is there) lists
|
|
14
16
|
who draws what: `GET /api/block_renderers`, `:owner`. `GET /api/block_renderers/:bundle/:file` serves a file, `:owner`:
|
|
15
17
|
the URL's names go through `BlockRenderers.script_path` (membership in a listed renderer's `load` before any path is
|
|
16
18
|
made), then `Provenance.sha_matches?`; a changed file is 409 `renderer_changed`. ETag + `no-cache`, as static files.
|