samagotchi 0.3.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 +83 -1
- data/README.md +16 -0
- data/bin/chi +32 -31
- data/docs/cli.md +77 -5
- data/docs/configuration.md +104 -2
- data/docs/desktop.md +39 -4
- data/docs/guardrails.md +11 -0
- data/docs/hooks.md +88 -6
- data/docs/releasing.md +6 -6
- data/docs/sessions.md +19 -17
- data/lib/samagotchi/bridge/turn_accumulator.rb +1 -0
- data/lib/samagotchi/bridge.rb +4 -1
- data/lib/samagotchi/bundles/source-links/hooks/source_links.rb +178 -5
- data/lib/samagotchi/bundles/source-links/manifest.yml +3 -3
- data/lib/samagotchi/bundles/source-links/source_links.md +1 -1
- data/lib/samagotchi/bundles/system/config_modification_protocol.md +2 -2
- data/lib/samagotchi/bundles/system/delegated.md +6 -7
- data/lib/samagotchi/bundles/system/manifest.yml +3 -3
- data/lib/samagotchi/client.rb +9 -6
- data/lib/samagotchi/commands/registry.rb +8 -0
- data/lib/samagotchi/config.rb +64 -20
- data/lib/samagotchi/desktop/macos/App.swift +12 -8
- data/lib/samagotchi/desktop/macos/ChiRunner.swift +4 -2
- 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 +112 -9
- 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/engine.rb +201 -104
- data/lib/samagotchi/gem_update.rb +89 -0
- data/lib/samagotchi/guardrails/approval.rb +26 -4
- data/lib/samagotchi/guardrails/load_failures.rb +9 -3
- data/lib/samagotchi/host_registry.rb +8 -12
- data/lib/samagotchi/idle_client.rb +24 -15
- data/lib/samagotchi/idle_reminders.rb +2 -2
- data/lib/samagotchi/image_store.rb +10 -6
- data/lib/samagotchi/kernel_loop.rb +26 -79
- data/lib/samagotchi/live_versions.rb +59 -0
- data/lib/samagotchi/llm/api_key.rb +41 -0
- data/lib/samagotchi/llm/chat_loop.rb +77 -13
- data/lib/samagotchi/llm/errors.rb +21 -7
- data/lib/samagotchi/llm/http.rb +15 -4
- data/lib/samagotchi/llm/openai_chat.rb +5 -26
- 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 +23 -0
- data/lib/samagotchi/prompt.rb +4 -2
- data/lib/samagotchi/reminder_store.rb +1 -9
- data/lib/samagotchi/self_report.rb +17 -3
- data/lib/samagotchi/send_command.rb +107 -12
- data/lib/samagotchi/session_commands.rb +38 -8
- data/lib/samagotchi/session_manager.rb +1 -16
- data/lib/samagotchi/terminal_ui/attached_loop.rb +21 -25
- data/lib/samagotchi/terminal_ui/event_renderer.rb +8 -3
- data/lib/samagotchi/terminal_ui/formatting.rb +9 -0
- data/lib/samagotchi/terminal_ui/input_support.rb +4 -19
- data/lib/samagotchi/terminal_ui/question_prompt.rb +35 -0
- data/lib/samagotchi/terminal_ui.rb +62 -248
- data/lib/samagotchi/text_diff.rb +181 -0
- data/lib/samagotchi/thinking.rb +115 -0
- data/lib/samagotchi/tool_runner.rb +34 -1
- data/lib/samagotchi/tools/ask_user_question.rb +41 -33
- data/lib/samagotchi/tools/edit.rb +23 -9
- data/lib/samagotchi/tools/write.rb +4 -0
- data/lib/samagotchi/turn_flow.rb +12 -2
- 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 +6 -4
- data/lib/samagotchi/web/app.rb +3 -3
- data/lib/samagotchi/web/message_parts.rb +8 -3
- data/lib/samagotchi/web/public/activity.js +3 -0
- data/lib/samagotchi/web/public/app.js +36 -24
- data/lib/samagotchi/web/public/chat_view.js +3 -0
- data/lib/samagotchi/web/public/data.js +2 -0
- data/lib/samagotchi/web/public/diff_view.js +58 -0
- data/lib/samagotchi/web/public/index.html +22 -1
- data/lib/samagotchi/web/public/question_card.js +3 -1
- data/lib/samagotchi/web/public/turn_events.js +29 -5
- data/lib/samagotchi/web/public/turn_view.js +2 -1
- data/lib/samagotchi/worker.rb +5 -4
- metadata +12 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 63f5d3415cd7f3cfe7f2811ab19bcabca4eafe62e349fd9d0d28fcd157c38340
|
|
4
|
+
data.tar.gz: a2fea7402c8a1cba19e795320c134e12a5cf58b026934cc954c4ecd80e6d765c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b8c4eb982683f47f10b9f77af3bc0b32518b8707860fcb796377870bb838ba13d326ece7b2e28f675097507478ec3723206ecd654fe8720e8653bf9a234f6930
|
|
7
|
+
data.tar.gz: fd059521495cca9d033924c818c8b35da945e6354b7806acdf65af7f275e51f9b20f5b228ff00dd81c2f16d73abd8de881d505b7eb3620e0a70792e28f4d7965
|
data/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,87 @@ and commands may change between minor versions. How releases are made:
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [0.4.0] - 2026-09-30
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- `chi update`: brings an installed chi up to date in one command: the gem
|
|
16
|
+
from rubygems, then the system bundle, the shipped bundles you installed and
|
|
17
|
+
the desktop helper (rebuilt only when its sources changed), shown in one
|
|
18
|
+
table. Your edits to bundle files are kept and reported, running workers and
|
|
19
|
+
an old `chi web` are only reported, `--dry-run` shows the plan, and
|
|
20
|
+
`--no-gem` / `--no-bundles` / `--no-desktop` (or `update.*` in config.yml)
|
|
21
|
+
skip parts. The first start of a new chi version says in one line when
|
|
22
|
+
something can be updated.
|
|
23
|
+
- A thinking level per model, host or run: `thinking: off | low | medium |
|
|
24
|
+
high | default` (`models.<key>.thinking`, `hosts.<name>.thinking`,
|
|
25
|
+
`thinking.level`, `--thinking LEVEL`). Chat hosts get the matching request
|
|
26
|
+
fields; native Qwen and Gemma turn thinking off. chi says once when a level
|
|
27
|
+
can't work on a host, and a host that refuses the thinking fields (gpt-oss
|
|
28
|
+
on OpenRouter) is asked again without them. `/model` and `chi self` show
|
|
29
|
+
the level.
|
|
30
|
+
- Edit previews: an edit/write approval shows the diff it would make, in the
|
|
31
|
+
web card and in the terminal, and every edit/write row gets a
|
|
32
|
+
"diff +3 −1" that opens to the change (live, after a reload and on a join).
|
|
33
|
+
- `chi send --image PATH` (repeatable, up to 20): images go with the message
|
|
34
|
+
as attachments, the same as the web composer's chips; converted and
|
|
35
|
+
downscaled once, then copied into each session. Works with `--new` (the
|
|
36
|
+
session starts idle, then gets the message with its images) and `--wait`.
|
|
37
|
+
A missing file or a non-image stops the send before anything goes out.
|
|
38
|
+
- The desktop helper takes images: a clipboard screenshot, image files from
|
|
39
|
+
Finder's Send to chi, other apps' image data, or a drop on the panel; they
|
|
40
|
+
show as thumbnails and go with the message.
|
|
41
|
+
- source-links 0.3.0: `#12` links to the current project's repo (from its git
|
|
42
|
+
remote) and `owner/repo#12` to that repo; `url:` templates take `{1}`,
|
|
43
|
+
`{name}`, `{repo}` and `{host}`, with `remote:` and `remote_host:` per
|
|
44
|
+
source, and the note lists each link once.
|
|
45
|
+
- The web shows when the provider is asked again after an error ("↻ retrying
|
|
46
|
+
(503) in 3 s, 1/2") or a turn waits for a plugin's setup.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- A model named with a host that isn't configured (`nosuch:org/model`, or a
|
|
51
|
+
provider's name like `openrouter:x`) is an error that names the host and
|
|
52
|
+
lists the configured ones, in the CLI, `chi send --new`, the web and
|
|
53
|
+
`/model`, instead of going to the default host.
|
|
54
|
+
- The terminal no longer rewrites `#word` into a memory reference: "PR #1"
|
|
55
|
+
and "#ff0000" reach the model as typed (Tab still completes `#name`).
|
|
56
|
+
- A question you dismiss reaches the model as dismissed, not as a tool
|
|
57
|
+
error, so it keeps asking when it should.
|
|
58
|
+
- `/quit` works in the REPL like `/exit`, and the web answers it too;
|
|
59
|
+
`/stats` and `/recap` take trailing words in both terminals.
|
|
60
|
+
- A delegated session gets reworded rules: the answer first, then evidence,
|
|
61
|
+
then what's unverified; follow-up messages arrive as new turns.
|
|
62
|
+
|
|
63
|
+
### Fixed
|
|
64
|
+
|
|
65
|
+
- A llama.cpp server started with `--api-key` works: the key in
|
|
66
|
+
`api_key_env` is sent on every request (it got 401). A 401/403 from any host
|
|
67
|
+
now says which variable to check or to set `api_key_env`.
|
|
68
|
+
- A bundle upgrade that keeps your edited file no longer disables the
|
|
69
|
+
bundle's plugin, and the system bundle stops warning about the same edit on
|
|
70
|
+
every start.
|
|
71
|
+
- One bundle with a broken manifest.json no longer stops the hooks of the
|
|
72
|
+
bundles after it from loading.
|
|
73
|
+
- A long-running worker picks up edited guardrail rules.
|
|
74
|
+
- `write` without content fails instead of emptying the file.
|
|
75
|
+
- Per-model `vision:` follows a model alias, like `profile:` and `sampling:`.
|
|
76
|
+
- A timeout of 0 in config means the default on llama.cpp hosts too (it was a
|
|
77
|
+
0-second timeout).
|
|
78
|
+
- A reminder turn drops a pending continue offer, so a later "no" can't roll
|
|
79
|
+
the reminder back.
|
|
80
|
+
- More than 8 options in `ask_user_question` is always an error (one path
|
|
81
|
+
silently used the first 8).
|
|
82
|
+
- A memory read with a comma list counts each name in the REPL and the web.
|
|
83
|
+
- `/archive` or `/quit` typed during a REPL turn no longer goes to the model
|
|
84
|
+
as text; `EXIT --DELETE` works in any case in an attached terminal.
|
|
85
|
+
- `chi bundle status` finds index lines again (it said "no-index" for every
|
|
86
|
+
file).
|
|
87
|
+
|
|
88
|
+
Update with `chi update` (new in this version: from 0.3.0, run
|
|
89
|
+
`gem install samagotchi` once, then `chi update`). Bundle moved:
|
|
90
|
+
source-links 0.3.0.
|
|
91
|
+
|
|
11
92
|
## [0.3.0] - 2026-09-29
|
|
12
93
|
|
|
13
94
|
### Added
|
|
@@ -153,6 +234,7 @@ and long-lived sessions.
|
|
|
153
234
|
- A macOS desktop helper (`chi desktop install`): a "Send to chi" Service and a
|
|
154
235
|
hotkey panel that send selected text or the clipboard to your sessions.
|
|
155
236
|
|
|
156
|
-
[Unreleased]: https://github.com/dm1try/samagotchi/compare/v0.
|
|
237
|
+
[Unreleased]: https://github.com/dm1try/samagotchi/compare/v0.4.0...HEAD
|
|
238
|
+
[0.4.0]: https://github.com/dm1try/samagotchi/compare/v0.3.0...v0.4.0
|
|
157
239
|
[0.3.0]: https://github.com/dm1try/samagotchi/compare/v0.2.0...v0.3.0
|
|
158
240
|
[0.2.0]: https://github.com/dm1try/samagotchi/releases/tag/v0.2.0
|
data/README.md
CHANGED
|
@@ -32,6 +32,22 @@ bin/chi self
|
|
|
32
32
|
`bin/chi` runs the checkout; `bundle exec rake gem:install` installs it as a
|
|
33
33
|
local gem, which puts `chi` on your PATH.
|
|
34
34
|
|
|
35
|
+
### Updating
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
chi update --dry-run # what would change
|
|
39
|
+
chi update # the gem, then the bundles and the desktop helper
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`chi update` installs the newest samagotchi from rubygems.org (old versions
|
|
43
|
+
stay installed: running sessions still use them), then brings the rest up to
|
|
44
|
+
the new version: the system bundle, the bundles chi ships that you installed,
|
|
45
|
+
and the macOS helper (rebuilt only when its sources changed). Memory files you
|
|
46
|
+
edited are kept, and the table says which. Running sessions move to the new
|
|
47
|
+
chi when their worker idles out (30 min) or on `chi sessions stop ID`; a
|
|
48
|
+
running `chi web` needs a restart. From a checkout, `git pull` instead. See
|
|
49
|
+
[CLI: Updating](docs/cli.md#updating).
|
|
50
|
+
|
|
35
51
|
## Set up
|
|
36
52
|
|
|
37
53
|
Point chi at your model server; it works out the rest and writes
|
data/bin/chi
CHANGED
|
@@ -257,6 +257,12 @@ if ARGV[0] == "bootstrap"
|
|
|
257
257
|
exit Samagotchi::BootstrapCommand.new(ARGV[1..] || []).run
|
|
258
258
|
end
|
|
259
259
|
|
|
260
|
+
# `chi update`: bring an installed chi up to date, before OptionParser (its own flags)
|
|
261
|
+
if ARGV[0] == "update"
|
|
262
|
+
require "samagotchi/update_command"
|
|
263
|
+
exit Samagotchi::UpdateCommand.new(ARGV[1..] || []).run
|
|
264
|
+
end
|
|
265
|
+
|
|
260
266
|
# `chi desktop`: the native "Send to chi" helper, before OptionParser (its own flags)
|
|
261
267
|
if ARGV[0] == "desktop"
|
|
262
268
|
require "samagotchi/desktop_command"
|
|
@@ -372,7 +378,7 @@ if ARGV[0] == "bundle"
|
|
|
372
378
|
lines << ""
|
|
373
379
|
lines << "Your task: resolve each conflict by editing the file in place using the memory_write tool."
|
|
374
380
|
lines << "Use memory_read to inspect current content if needed. The correct scope for memory_write is the bundle's scope."
|
|
375
|
-
lines << "When all conflicts are resolved, type /exit to finish. If you
|
|
381
|
+
lines << "When all conflicts are resolved, type /exit to finish. If you stop early, the files stay as they are (the rest of the upgrade is already applied)."
|
|
376
382
|
lines.join("\n")
|
|
377
383
|
end
|
|
378
384
|
|
|
@@ -529,7 +535,7 @@ if ARGV[0] == "bundle"
|
|
|
529
535
|
ans = begin; $stdin.gets; rescue => _e; nil; end
|
|
530
536
|
launch = ans && ans.strip.downcase.start_with?("y")
|
|
531
537
|
else
|
|
532
|
-
puts "Non-interactive terminal
|
|
538
|
+
puts "Non-interactive terminal: kept your edits in the file(s) above; the rest is upgraded. Re-run with --force to take the bundle's version, or --agent in a TTY to merge."
|
|
533
539
|
exit 2
|
|
534
540
|
end
|
|
535
541
|
if launch
|
|
@@ -537,37 +543,15 @@ if ARGV[0] == "bundle"
|
|
|
537
543
|
puts "Launching interactive session for conflict resolution… (/exit when done)"
|
|
538
544
|
require "samagotchi/terminal_ui"
|
|
539
545
|
Samagotchi::TerminalUI.new(prompt: prompt).run
|
|
540
|
-
#
|
|
541
|
-
#
|
|
542
|
-
#
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
# Re-collect provenance files from target dir for this bundle
|
|
546
|
-
prov_files = {}
|
|
547
|
-
target_scope = scope || provenance.read[:scope]&.to_s || "system"
|
|
548
|
-
target_dir = Samagotchi::MemoryBundle::Installer.new(source: expanded_source, name: bundle_name, scope: target_scope).send(:resolve_target_dir, target_scope)
|
|
549
|
-
# Actually reuse provenance write with current target files for bundle keys
|
|
550
|
-
bundle_files = installer.conflicts.keys + installer.results.select { |_, r| %w[installed updated].include?(r[:status]) }.keys
|
|
551
|
-
# Fallback: collect all md that exist and were in installer results
|
|
552
|
-
all_keys = installer.results.keys
|
|
553
|
-
all_keys.each do |k|
|
|
554
|
-
p = File.join(target_dir, k)
|
|
555
|
-
prov_files[k] = p if File.exist?(p)
|
|
556
|
-
end
|
|
557
|
-
if prov_files.any?
|
|
558
|
-
Samagotchi::MemoryBundle::Provenance.new(name: bundle_name).write(
|
|
559
|
-
files: prov_files,
|
|
560
|
-
scope: target_scope,
|
|
561
|
-
version: manifest.version,
|
|
562
|
-
source_path: expanded_source
|
|
563
|
-
)
|
|
564
|
-
puts "Provenance updated after interactive resolution."
|
|
565
|
-
end
|
|
566
|
-
end
|
|
546
|
+
# The installer already recorded the upgrade (conflicted files
|
|
547
|
+
# kept their old base); the resolved files now start from the
|
|
548
|
+
# bundle's version.
|
|
549
|
+
Samagotchi::MemoryBundle::Provenance.new(name: bundle_name).resolve_conflicts(installer.conflicts)
|
|
550
|
+
puts "Provenance updated after interactive resolution."
|
|
567
551
|
puts "Upgrade resolved interactively."
|
|
568
552
|
exit 0
|
|
569
553
|
else
|
|
570
|
-
puts "
|
|
554
|
+
puts "Kept your edits in the file(s) above; the rest is upgraded. chi bundle diff #{bundle_name} FILE shows the base; re-run with --force to take the bundle's version."
|
|
571
555
|
exit 2
|
|
572
556
|
end
|
|
573
557
|
end
|
|
@@ -637,6 +621,7 @@ if ARGV[0] == "bundle"
|
|
|
637
621
|
puts "Target: #{st[:target_dir]}"
|
|
638
622
|
st[:files].each do |k, info|
|
|
639
623
|
mods = []
|
|
624
|
+
mods << "conflict (kept your edits over v#{st[:provenance][:version]}: chi bundle diff #{name} #{k})" if info[:conflict]
|
|
640
625
|
mods << "modified" if info[:modified]
|
|
641
626
|
mods << "missing" if info[:missing]
|
|
642
627
|
mods << "no-index" unless info[:index_present]
|
|
@@ -806,6 +791,7 @@ if ARGV[0] == "bundle"
|
|
|
806
791
|
line += " (shipped v#{b.upgrade.version}: chi bundle upgrade #{b.upgrade.source})" if b.upgrade
|
|
807
792
|
puts line
|
|
808
793
|
end
|
|
794
|
+
puts " (or all at once: chi update)" if installed.any?(&:upgrade)
|
|
809
795
|
end
|
|
810
796
|
unless available.empty?
|
|
811
797
|
puts ""
|
|
@@ -930,7 +916,7 @@ ARGV.each do |arg|
|
|
|
930
916
|
base = arg.split("=", 2).first
|
|
931
917
|
# If dashed version is a known flag (registry or hardcoded), reject underscore variant
|
|
932
918
|
dashed = base.tr("_", "-")
|
|
933
|
-
known = %w[--prompt --resume --attach --shared --no-shared --model --memory --mute --no-interrupt --non-interactive --verbose --no-default-input --port --open] + Samagotchi::Config.cli_entries.map(&:cli_flag)
|
|
919
|
+
known = %w[--prompt --resume --attach --shared --no-shared --model --thinking --memory --mute --no-interrupt --non-interactive --verbose --no-default-input --port --open] + Samagotchi::Config.cli_entries.map(&:cli_flag)
|
|
934
920
|
if known.include?(dashed) || known.include?(base)
|
|
935
921
|
warn "Unknown option: #{arg} (did you mean #{dashed}?)"
|
|
936
922
|
exit 1
|
|
@@ -949,6 +935,7 @@ parser = OptionParser.new do |opts|
|
|
|
949
935
|
chi bundle <install|upgrade|uninstall|status|diff|list|build>
|
|
950
936
|
chi desktop <install|upgrade|uninstall|status> macOS "Send to chi" helper
|
|
951
937
|
chi self version, paths, model and bundles
|
|
938
|
+
chi update [--dry-run] update this chi, its bundles and the desktop helper
|
|
952
939
|
(each subcommand takes --help)
|
|
953
940
|
|
|
954
941
|
BANNER
|
|
@@ -959,6 +946,8 @@ parser = OptionParser.new do |opts|
|
|
|
959
946
|
opts.on("--model NAME", "Model selector (runtime only, overrides --resume) [alias for --default-model]") { |m| options[:model] = m; cli_overrides["default.model"] = m }
|
|
960
947
|
opts.on("--profile NAME", Samagotchi::ModelProfile::NAMES,
|
|
961
948
|
"Prompt profile for every model in this run (#{Samagotchi::ModelProfile::NAMES.join('|')}) [alias for --model-profile]") { |p| cli_overrides["model.profile"] = p }
|
|
949
|
+
opts.on("--thinking LEVEL", Samagotchi::Thinking::LEVELS.map(&:to_s), "How much the model thinks this run: off|low|medium|high|default (outranks config.yml; " \
|
|
950
|
+
"sessions already running keep theirs) [env SAMAGOTCHI_THINKING_LEVEL]") { |l| cli_overrides["thinking.level"] = l }
|
|
962
951
|
opts.on("--memory NAME", "Preload a memory entry into the system prompt (repeatable; a comma list too)") { |m| (options[:memories] ||= []) << m }
|
|
963
952
|
opts.on("--mute NAME", "Hide a memory from this session: not in the prompt, refused by memory_read (repeatable; a comma list too)") { |m| (options[:muted] ||= []) << m }
|
|
964
953
|
opts.on("--no-interrupt", "Raise the tool call limit to 1000 iterations (useful for long tasks)") { options[:no_interrupt] = true; cli_overrides["no_interrupt"] = true }
|
|
@@ -1074,7 +1063,18 @@ when "web"
|
|
|
1074
1063
|
end
|
|
1075
1064
|
end
|
|
1076
1065
|
|
|
1066
|
+
# The first interactive start of a new installed chi says what `chi update` would update.
|
|
1067
|
+
chi_update_hint = lambda do
|
|
1068
|
+
require "samagotchi/installed_gem"
|
|
1069
|
+
require "samagotchi/update_hint"
|
|
1070
|
+
if Samagotchi::UpdateHint.wanted?(prompt: options[:prompt], non_interactive: options[:non_interactive],
|
|
1071
|
+
tty: $stdin.tty? && $stdout.tty?, installed: Samagotchi::InstalledGem.spec)
|
|
1072
|
+
Samagotchi::UpdateHint.show
|
|
1073
|
+
end
|
|
1074
|
+
end
|
|
1075
|
+
|
|
1077
1076
|
if options[:web]
|
|
1077
|
+
chi_update_hint.call
|
|
1078
1078
|
require "samagotchi/web/server"
|
|
1079
1079
|
port = options[:web_port] || Samagotchi::Config.get("web.port") || 4567
|
|
1080
1080
|
# legacy env fallback
|
|
@@ -1143,6 +1143,7 @@ if options[:memories] || options[:muted]
|
|
|
1143
1143
|
end
|
|
1144
1144
|
end
|
|
1145
1145
|
|
|
1146
|
+
chi_update_hint.call
|
|
1146
1147
|
require "samagotchi/launch_mode"
|
|
1147
1148
|
launch, launch_note = if scratch
|
|
1148
1149
|
[:repl, nil]
|
data/docs/cli.md
CHANGED
|
@@ -16,9 +16,10 @@
|
|
|
16
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))
|
|
17
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))
|
|
18
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))
|
|
19
|
-
- `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)); `--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))
|
|
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))
|
|
20
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))
|
|
21
21
|
- `chi self` — print version, source dir (checkout or installed gem), config/memory/session paths, model/host and bundles
|
|
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))
|
|
22
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))
|
|
23
24
|
|
|
24
25
|
### First setup
|
|
@@ -57,6 +58,65 @@ chi bootstrap # try localhost 8080, 11434, 1234, 8000
|
|
|
57
58
|
or with anchors gets the lines printed to paste instead. `--dry-run` shows
|
|
58
59
|
what it would write.
|
|
59
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.
|
|
119
|
+
|
|
60
120
|
## Flags
|
|
61
121
|
|
|
62
122
|
Samagotchi exposes one flag that feeds a prompt (`-p`, `--prompt`) and one that
|
|
@@ -71,6 +131,7 @@ controls exit behavior (`--non-interactive`); `--resume` composes with both.
|
|
|
71
131
|
| `--no-shared` | Run the plain in-process REPL for this run. |
|
|
72
132
|
| `--attach SESSION_ID` | Attach to a session's worker, waking one if it has exited. |
|
|
73
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. |
|
|
74
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. |
|
|
75
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. |
|
|
76
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). |
|
|
@@ -279,7 +340,7 @@ REPL alike:
|
|
|
279
340
|
typed comes back once it closes. The choices then go, and one line stays:
|
|
280
341
|
`? Pick a fruit → Banana`.
|
|
281
342
|
- Ctrl-C cancels the turn and keeps what you typed.
|
|
282
|
-
- 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
|
|
283
344
|
exits once the turn ends: `(exits after this turn; Ctrl-C cancels it)`
|
|
284
345
|
(`/exit --delete` deletes the session then too). In an
|
|
285
346
|
attached terminal it detaches at once and the turn goes on in the worker
|
|
@@ -290,7 +351,7 @@ turns.
|
|
|
290
351
|
|
|
291
352
|
### Images
|
|
292
353
|
|
|
293
|
-
A model that can see images gets them
|
|
354
|
+
A model that can see images gets them these ways:
|
|
294
355
|
|
|
295
356
|
- **`@path` in a prompt** (REPL, attached terminal, `-p`): `what's wrong in
|
|
296
357
|
@shot.png?`, `@~/Desktop/a.jpg`, `@"my shot.png"`. Each `@` token that names an
|
|
@@ -305,6 +366,12 @@ A model that can see images gets them three ways:
|
|
|
305
366
|
- **The Web UI**: paste or drop images into the composer. Each shows as a chip
|
|
306
367
|
(× removes it) and is sent with the message; an image alone is sent as
|
|
307
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.
|
|
308
375
|
|
|
309
376
|
Images are downscaled to a 1568 px long side (with `sips` on macOS or
|
|
310
377
|
ImageMagick; without either, a larger image is refused with a hint) and stored
|
|
@@ -375,7 +442,10 @@ from the saved messages (each step's thinking, narration, tool parameters
|
|
|
375
442
|
and output, the output capped at 2000 characters) and the timing records
|
|
376
443
|
(status and duration per row). On an `api: openai` host the model's
|
|
377
444
|
reasoning is saved with each step for this (never sent back to the model);
|
|
378
|
-
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).
|
|
379
449
|
|
|
380
450
|
```sh
|
|
381
451
|
chi web --no-web-turn-view # the classic chat view; --web-turn-view is the default
|
|
@@ -582,7 +652,9 @@ During assist-mode thinking (while the spinner is active), you can cancel an in-
|
|
|
582
652
|
Behavior notes:
|
|
583
653
|
|
|
584
654
|
- Cancellation returns control to the prompt immediately; what you typed there stays.
|
|
585
|
-
-
|
|
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.
|
|
586
658
|
|
|
587
659
|
## Iteration Limit Behavior
|
|
588
660
|
|
data/docs/configuration.md
CHANGED
|
@@ -29,6 +29,7 @@ server: # the model server when there is no hosts: map below
|
|
|
29
29
|
port: 8081
|
|
30
30
|
thinking:
|
|
31
31
|
ui: spinner
|
|
32
|
+
level: default # off | low | medium | high | default; see "Thinking"
|
|
32
33
|
|
|
33
34
|
# Multi-host (optional): aggregated /models and per-model routing.
|
|
34
35
|
# A bare default.model uses the default host; host:model pins to a host.
|
|
@@ -214,6 +215,20 @@ hosts:
|
|
|
214
215
|
|
|
215
216
|
`chi self` shows the variable and whether it is set (`api key FIREWORKS_API_KEY (set)`).
|
|
216
217
|
|
|
218
|
+
Every host with `api_key_env:` sends `Authorization: Bearer <key>` on each request,
|
|
219
|
+
chat or raw-prompt alike, so a llama.cpp started with `--api-key` works as a native
|
|
220
|
+
host too (`chi bootstrap --key-env VAR` writes such an entry). An unset variable
|
|
221
|
+
fails the turn before any request (`set VAR`); a 401/403 names the variable to
|
|
222
|
+
check, or, on a host without `api_key_env:`, suggests adding it:
|
|
223
|
+
|
|
224
|
+
```yaml
|
|
225
|
+
hosts:
|
|
226
|
+
box:
|
|
227
|
+
host: 192.0.2.20
|
|
228
|
+
port: 8080
|
|
229
|
+
api_key_env: BOX_LLAMA_KEY
|
|
230
|
+
```
|
|
231
|
+
|
|
217
232
|
For models on that host, chi uses the chat loop (its own OpenAI chat adapter): it
|
|
218
233
|
takes the OpenAI base (`url:`, else `http://HOST:PORT/v1`) and streams messages plus
|
|
219
234
|
function schemas from `/v1/chat/completions`; the model's reasoning (`reasoning_content`)
|
|
@@ -355,6 +370,70 @@ models:
|
|
|
355
370
|
`SAMAGOTCHI_HOSTS_JSON`, and reads `models:` from the config file each turn: after changing a host's `sampling:`,
|
|
356
371
|
stop the session's worker (`chi sessions stop`) for it to take effect.
|
|
357
372
|
|
|
373
|
+
## Thinking
|
|
374
|
+
|
|
375
|
+
How much a model thinks before it answers. One level, `off`, `low`, `medium`, `high` or `default`, set per model,
|
|
376
|
+
per host or for everything:
|
|
377
|
+
|
|
378
|
+
```yaml
|
|
379
|
+
thinking:
|
|
380
|
+
level: default # every model without its own level
|
|
381
|
+
hosts:
|
|
382
|
+
openrouter:
|
|
383
|
+
url: https://openrouter.ai/api/v1
|
|
384
|
+
api: openai
|
|
385
|
+
api_key_env: OPENROUTER_API_KEY
|
|
386
|
+
thinking: low
|
|
387
|
+
models:
|
|
388
|
+
qwen3.6-35b-a3b:
|
|
389
|
+
thinking: off # unquoted off works (YAML reads it as false)
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
- `default` sends nothing: the provider's or the chat template's own default, which is chi's behaviour without the
|
|
393
|
+
setting. For some hybrid models that default is *no* thinking (DeepSeek V3.1 on OpenRouter); `medium` turns it on.
|
|
394
|
+
`on` isn't a level.
|
|
395
|
+
- Order, first set wins: `--thinking LEVEL` or `SAMAGOTCHI_THINKING_LEVEL`, then the `models:` entry (found the way
|
|
396
|
+
`profile:` is), then the `hosts:` entry, then `thinking.level` in the file, then `default`. Anything else than a
|
|
397
|
+
level warns once and counts as unset.
|
|
398
|
+
- The flag reaches the sessions that start with it; a session already running keeps its level. `models:` levels
|
|
399
|
+
and `thinking.level` in the file are read every turn; a host's `thinking:` reaches a worker when it starts, as
|
|
400
|
+
its `sampling:` does (`chi sessions stop` to change it).
|
|
401
|
+
- `/model` shows the level and where it came from (`thinking: off (models: qwen3.6-35b-a3b)`), `chi self` too.
|
|
402
|
+
- The idle recap and plugins' side questions always ask with thinking off, whatever the level.
|
|
403
|
+
|
|
404
|
+
What each backend gets:
|
|
405
|
+
|
|
406
|
+
| Backend | `off` | `low` / `medium` / `high` |
|
|
407
|
+
|---|---|---|
|
|
408
|
+
| native (`/completion`), `qwen36` | an empty thought after the assistant cue, and no turn preamble | no knob: thinking stays as the model has it, one notice |
|
|
409
|
+
| native, `gemma4` | no `<\|think\|>` token at the start of the system prompt | no knob, one notice |
|
|
410
|
+
| chat host (`api: openai`) | `chat_template_kwargs: {enable_thinking: false}` and `reasoning_effort: "none"` | `reasoning_effort: <level>` |
|
|
411
|
+
|
|
412
|
+
On chat hosts: llama.cpp honours both off switches but ignores the effort; Splash takes `reasoning_effort` (off only
|
|
413
|
+
through `none`) and scales with it; OpenRouter translates `reasoning_effort` per model (some can't turn thinking off:
|
|
414
|
+
Qwen3-30B-A3B thinks anyway, gpt-oss refuses).
|
|
415
|
+
|
|
416
|
+
When the model thinks although the level is `off`, chi says so once per session and host
|
|
417
|
+
(`thinking> warning: off wasn't honoured by … (N chars of thinking)`) and logs `thinking_not_honoured` each time.
|
|
418
|
+
When a host answers the thinking fields with an HTTP 400 about reasoning (gpt-oss: "Reasoning is mandatory"), chi
|
|
419
|
+
sends the request again without them, leaves them out for that model from then on, and says so once.
|
|
420
|
+
|
|
421
|
+
The fields go under the `sampling:` map ("Sampling"): a `sampling:` key wins over the level's, and
|
|
422
|
+
`chat_template_kwargs` merges per sub-key. A `null` there drops a field the level would send, at any depth, for a
|
|
423
|
+
host that refuses one of them:
|
|
424
|
+
|
|
425
|
+
```yaml
|
|
426
|
+
hosts:
|
|
427
|
+
strict:
|
|
428
|
+
url: https://llm.example.com/v1
|
|
429
|
+
api: openai
|
|
430
|
+
thinking: off
|
|
431
|
+
sampling: { reasoning_effort: null } # sends only enable_thinking: false
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
A different level changes a native model's system prompt (Gemma's token, Qwen's turn preamble), so the next turn
|
|
435
|
+
reads the whole context again once; on a chat host only the end of the prompt changes.
|
|
436
|
+
|
|
358
437
|
## Llama HTTP Timeouts
|
|
359
438
|
|
|
360
439
|
Long-running llama.cpp completions can exceed Ruby's default HTTP read timeout.
|
|
@@ -362,6 +441,7 @@ Raise these to avoid premature request failures:
|
|
|
362
441
|
|
|
363
442
|
- `server.open_timeout` (default: `10`, env `SAMAGOTCHI_SERVER_OPEN_TIMEOUT`) connection timeout in seconds.
|
|
364
443
|
- `server.read_timeout` (default: `600`, env `SAMAGOTCHI_SERVER_READ_TIMEOUT`) response read timeout in seconds.
|
|
444
|
+
Either timeout at `0` (or anything not a positive number) is its default, on every host.
|
|
365
445
|
|
|
366
446
|
```yaml
|
|
367
447
|
server:
|
|
@@ -409,15 +489,32 @@ the running server (llama.cpp's `/props`), else the window the host's model list
|
|
|
409
489
|
gives (`context_length`, `context_window`, `max_model_len` or llama.cpp's
|
|
410
490
|
`meta.n_ctx`), else `context.window_tokens`.
|
|
411
491
|
|
|
492
|
+
A `:` in a model name is often part of the id (`qwen3:8b`, `mistral:7b`,
|
|
493
|
+
`unsloth/Qwen3-8B-GGUF:Q4_K_M`), so the part before the first `:` picks a host
|
|
494
|
+
only when it is a configured host's name. An unknown prefix is refused with an
|
|
495
|
+
error naming it and the configured hosts (with a "did you mean" for a near
|
|
496
|
+
miss) when either
|
|
497
|
+
- the rest is an `org/model` id (`nosuch:anthropic/claude-sonnet-4`), or
|
|
498
|
+
- the prefix is a hosted provider's name: `openrouter`, `openai`, `anthropic`,
|
|
499
|
+
`google`, `gemini`, `groq`, `xai`, `together` or `fireworks`
|
|
500
|
+
(`openai:gpt-4o` with no `openai` host).
|
|
501
|
+
|
|
502
|
+
The check applies wherever the model comes in: `--model`, `default.model`, an
|
|
503
|
+
alias, `/model`, `chi send --new --model`, the web's new-session model and a
|
|
504
|
+
delegate's model. Any other unknown prefix (`nosuch:x`) is sent to the default
|
|
505
|
+
host as the model id.
|
|
506
|
+
|
|
412
507
|
## Llama Network Retry Behavior
|
|
413
508
|
|
|
414
509
|
Transient network failures are retried automatically with exponential backoff.
|
|
415
510
|
|
|
416
511
|
- Default retries: `5` (up to `6` total attempts including the first call).
|
|
417
512
|
- Default backoff: `0.5s`, `1s`, `2s`, `4s`, `8s`.
|
|
418
|
-
- Retry scope: transient network errors (timeouts,
|
|
513
|
+
- Retry scope: transient network errors (timeouts, reset connections, EOF/socket reachability failures),
|
|
419
514
|
HTTP 429 and HTTP 500/502/503/504/529. A `Retry-After` header replaces the backoff delay; one longer than
|
|
420
515
|
60s is not waited out and the error is reported instead.
|
|
516
|
+
- A refused connection (nothing listening) is not retried: the turn fails at once with `can't reach host <name> at
|
|
517
|
+
<address> (connection refused) — is the server running?`.
|
|
421
518
|
- A stream that has already produced output is never retried (the retry would repeat it); it fails the turn.
|
|
422
519
|
- Cancellation (`Ctrl-C`) is never retried.
|
|
423
520
|
|
|
@@ -455,7 +552,7 @@ message (before, a failed llama.cpp `/completion` ended the turn as
|
|
|
455
552
|
|
|
456
553
|
| Kind | When | Retried |
|
|
457
554
|
|---|---|---|
|
|
458
|
-
| connection |
|
|
555
|
+
| connection | reset, timed out, dropped mid-stream; refused | yes (network retry), not mid-stream; refused: no |
|
|
459
556
|
| rate limited | HTTP 429 | yes, honouring `Retry-After` |
|
|
460
557
|
| server | HTTP 5xx, llama.cpp's mid-stream `error:` event | 500/502/503/504/529 only |
|
|
461
558
|
| auth | HTTP 401/403 | no |
|
|
@@ -651,11 +748,16 @@ described in their own sections.
|
|
|
651
748
|
| `thinking.ui` | `spinner` | yes | `spinner` or `off`. |
|
|
652
749
|
| `thinking.render_interval` | `0.08` | yes | Seconds between thinking redraws. |
|
|
653
750
|
| `thinking.turn_preamble` | `true` | yes | Ask a `qwen36` model to open its thinking with a short `TURN:` line (the step label). |
|
|
751
|
+
| `thinking.level` | `default` | `--thinking` | `off`, `low`, `medium`, `high` or `default` for every model; the flag and env outrank the `models:`/`hosts:` entries, the file's value doesn't. See "Thinking". |
|
|
752
|
+
| `models.<key>.thinking`, `hosts.<name>.thinking` | none | | A model's or host's level. See "Thinking". |
|
|
654
753
|
| `max_tool_output_chars` | `10000` | yes | Tool output kept in the conversation; a top-level key (see below). |
|
|
655
754
|
| `retry.max` | `5` | yes | See "Llama Network Retry Behavior". |
|
|
656
755
|
| `retry.base_delay` | `0.5` | yes | |
|
|
657
756
|
| `retry.max_delay` | `8.0` | yes | |
|
|
658
757
|
| `retry.empty_answer` | `1` | | Times a turn asks again after an empty answer (at most 3, `0` = off). See "Llama Network Retry Behavior". |
|
|
758
|
+
| `update.gem` | `true` | | `false`: `chi update` never installs a newer gem (`--no-gem` for one run). See [CLI: Updating](cli.md#updating). |
|
|
759
|
+
| `update.bundles` | `true` | | `false`: `chi update` leaves the shipped bundles to `chi bundle upgrade` (`--no-bundles`). |
|
|
760
|
+
| `update.desktop` | `true` | | `false`: `chi update` leaves the desktop helper alone (`--no-desktop`). |
|
|
659
761
|
| `read.truncate_at_bytes` | `65536` | yes | A `read` result larger than this is cut to a preview. |
|
|
660
762
|
| `read.preview_bytes` | `12288` | yes | Size of that preview. |
|
|
661
763
|
| `read.hard_max_bytes` | `2097152` | yes | Largest file `read` opens. |
|