samagotchi 0.21.0 → 0.23.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 +62 -1
- data/bin/chi +9 -4
- data/docs/architecture.md +3 -2
- data/docs/configuration.md +15 -4
- data/docs/releasing.md +1 -1
- data/docs/sessions.md +1 -1
- data/docs/sub-agent.md +11 -5
- data/docs/testing.md +6 -0
- data/lib/samagotchi/answer_command.rb +11 -5
- data/lib/samagotchi/bootstrap/config_writer.rb +2 -1
- data/lib/samagotchi/bootstrap/probe.rb +1 -1
- data/lib/samagotchi/bootstrap_command.rb +2 -2
- data/lib/samagotchi/bridge/bounded_queue.rb +0 -2
- data/lib/samagotchi/bridge/sse_writer.rb +0 -6
- data/lib/samagotchi/bridge/turn_accumulator.rb +2 -2
- data/lib/samagotchi/bridge.rb +12 -9
- data/lib/samagotchi/bridge_client/event_stream.rb +2 -2
- data/lib/samagotchi/bridge_client.rb +1 -1
- data/lib/samagotchi/bundle_command.rb +39 -29
- data/lib/samagotchi/bundles/btw/manifest.yml +2 -2
- data/lib/samagotchi/bundles/btw/plugin.rb +2 -0
- data/lib/samagotchi/bundles/check-in/manifest.yml +2 -2
- data/lib/samagotchi/bundles/check-in/plugin.rb +2 -0
- data/lib/samagotchi/bundles/known-names/hooks/known_names.rb +6 -5
- data/lib/samagotchi/bundles/known-names/manifest.yml +2 -2
- data/lib/samagotchi/bundles/loop-guard/manifest.yml +2 -2
- data/lib/samagotchi/bundles/loop-guard/plugin.rb +2 -0
- data/lib/samagotchi/bundles/mcp/manifest.yml +2 -2
- data/lib/samagotchi/bundles/mcp/plugin.rb +2 -0
- data/lib/samagotchi/bundles/skills/manifest.yml +2 -2
- data/lib/samagotchi/bundles/skills/plugin.rb +5 -3
- data/lib/samagotchi/bundles/source-links/hooks/source_links.rb +7 -7
- data/lib/samagotchi/bundles/source-links/manifest.yml +2 -2
- data/lib/samagotchi/bundles/system/config_modification_protocol.md +1 -1
- data/lib/samagotchi/bundles/system/manifest.yml +2 -2
- data/lib/samagotchi/cancellation_controller.rb +1 -1
- data/lib/samagotchi/cli/command.rb +1 -1
- data/lib/samagotchi/cli/parent_wait.rb +9 -2
- data/lib/samagotchi/client.rb +3 -5
- data/lib/samagotchi/commands/registry.rb +2 -2
- data/lib/samagotchi/config.rb +38 -14
- data/lib/samagotchi/context_note.rb +1 -1
- data/lib/samagotchi/context_status.rb +6 -6
- data/lib/samagotchi/continue_offer.rb +44 -12
- data/lib/samagotchi/debug_log.rb +1 -1
- data/lib/samagotchi/desktop/macos.rb +5 -4
- data/lib/samagotchi/empty_answer_retry.rb +1 -1
- data/lib/samagotchi/engine.rb +49 -19
- data/lib/samagotchi/gem_update.rb +2 -1
- data/lib/samagotchi/guardrail_wiring.rb +1 -1
- data/lib/samagotchi/guardrails/approval.rb +5 -5
- data/lib/samagotchi/guardrails/approvals.rb +2 -2
- data/lib/samagotchi/guardrails/gate.rb +2 -2
- data/lib/samagotchi/guardrails/read_only_shell.rb +5 -3
- data/lib/samagotchi/guardrails/shell_git_dirs.rb +1 -1
- data/lib/samagotchi/guardrails/shell_lex.rb +2 -2
- data/lib/samagotchi/guardrails/shell_paths.rb +2 -2
- data/lib/samagotchi/hooks/bundle_loader.rb +9 -6
- data/lib/samagotchi/hooks/loader.rb +18 -16
- data/lib/samagotchi/hooks/registry.rb +10 -2
- data/lib/samagotchi/host_registry.rb +1 -3
- data/lib/samagotchi/idle_recap.rb +18 -15
- data/lib/samagotchi/idle_reminders.rb +6 -3
- data/lib/samagotchi/image_store.rb +5 -2
- data/lib/samagotchi/kernel_loop.rb +31 -31
- data/lib/samagotchi/llm/chat_loop.rb +9 -6
- data/lib/samagotchi/llm/errors.rb +33 -2
- data/lib/samagotchi/llm/http.rb +12 -12
- data/lib/samagotchi/llm/openai_chat.rb +53 -30
- data/lib/samagotchi/llm/prompt_cache.rb +83 -0
- data/lib/samagotchi/log.rb +2 -2
- data/lib/samagotchi/log_subscriber.rb +2 -1
- data/lib/samagotchi/memory_bundle/builder.rb +9 -3
- data/lib/samagotchi/memory_bundle/index_updater.rb +13 -1
- data/lib/samagotchi/memory_bundle/installer.rb +67 -57
- data/lib/samagotchi/memory_bundle/listing.rb +5 -1
- data/lib/samagotchi/memory_bundle/manifest.rb +14 -4
- data/lib/samagotchi/memory_bundle/merger.rb +6 -4
- data/lib/samagotchi/memory_bundle/provenance.rb +16 -13
- data/lib/samagotchi/memory_bundle/source.rb +7 -3
- data/lib/samagotchi/memory_bundle/status.rb +3 -1
- data/lib/samagotchi/memory_bundle/system_bundle.rb +3 -2
- data/lib/samagotchi/memory_bundle/trash.rb +5 -2
- data/lib/samagotchi/memory_bundle/uninstaller.rb +9 -6
- data/lib/samagotchi/memory_bundle.rb +1 -0
- data/lib/samagotchi/model_overlay.rb +3 -5
- data/lib/samagotchi/model_profile.rb +12 -8
- data/lib/samagotchi/note_command.rb +2 -1
- data/lib/samagotchi/output_formatter.rb +18 -17
- data/lib/samagotchi/owner_lock.rb +2 -1
- data/lib/samagotchi/parent_report.rb +24 -7
- data/lib/samagotchi/plugin/api.rb +8 -5
- data/lib/samagotchi/plugin/context.rb +1 -3
- data/lib/samagotchi/plugin/loader.rb +1 -1
- data/lib/samagotchi/plugin/service.rb +1 -1
- data/lib/samagotchi/plugin/sessions.rb +1 -0
- data/lib/samagotchi/plugin_tasks.rb +1 -1
- data/lib/samagotchi/prompt.rb +68 -12
- data/lib/samagotchi/prompt_literal_guard.rb +1 -1
- data/lib/samagotchi/question_desk.rb +7 -13
- data/lib/samagotchi/recap_setup.rb +1 -1
- data/lib/samagotchi/relay_desk.rb +1 -1
- data/lib/samagotchi/reminder_store.rb +2 -1
- data/lib/samagotchi/reply_wait.rb +12 -2
- data/lib/samagotchi/send_command.rb +4 -2
- data/lib/samagotchi/session.rb +2 -2
- data/lib/samagotchi/session_archive_command.rb +5 -1
- data/lib/samagotchi/session_commands.rb +1 -3
- data/lib/samagotchi/session_manager.rb +2 -4
- data/lib/samagotchi/session_metrics.rb +10 -10
- data/lib/samagotchi/session_observer.rb +3 -2
- data/lib/samagotchi/session_retention.rb +2 -2
- data/lib/samagotchi/sessions_command.rb +14 -5
- data/lib/samagotchi/system_prompt.rb +19 -8
- data/lib/samagotchi/terminal_ui/attach_launcher.rb +5 -5
- data/lib/samagotchi/terminal_ui/attached_loop.rb +2 -2
- data/lib/samagotchi/terminal_ui/event_renderer.rb +1 -2
- data/lib/samagotchi/terminal_ui/formatting.rb +10 -10
- data/lib/samagotchi/terminal_ui/input_support.rb +2 -2
- data/lib/samagotchi/terminal_ui/line_reader.rb +3 -3
- data/lib/samagotchi/terminal_ui/question_prompt.rb +23 -23
- data/lib/samagotchi/terminal_ui/question_slot.rb +10 -10
- data/lib/samagotchi/terminal_ui/reline_seam.rb +1 -1
- data/lib/samagotchi/terminal_ui/repl_input.rb +3 -2
- data/lib/samagotchi/terminal_ui.rb +9 -5
- data/lib/samagotchi/text_diff.rb +12 -12
- data/lib/samagotchi/thinking.rb +6 -2
- data/lib/samagotchi/thought_stream_splitter.rb +6 -3
- data/lib/samagotchi/tool_activity.rb +1 -0
- data/lib/samagotchi/tool_call_parser.rb +13 -14
- data/lib/samagotchi/tool_declarations.rb +36 -35
- data/lib/samagotchi/tools/ask_user_question.rb +3 -4
- data/lib/samagotchi/tools/builtin_calls.rb +1 -1
- data/lib/samagotchi/tools/delegate.rb +1 -1
- data/lib/samagotchi/tools/delegate_relay.rb +1 -1
- data/lib/samagotchi/tools/delegate_wait.rb +0 -1
- data/lib/samagotchi/tools/edit.rb +14 -13
- data/lib/samagotchi/tools/execute.rb +3 -5
- data/lib/samagotchi/tools/list_reminders.rb +1 -1
- data/lib/samagotchi/tools/memory.rb +21 -22
- data/lib/samagotchi/tools/read.rb +7 -7
- data/lib/samagotchi/tools/task_create.rb +1 -1
- data/lib/samagotchi/tools/task_get.rb +1 -1
- data/lib/samagotchi/tools/task_list.rb +1 -1
- data/lib/samagotchi/tools/task_runtime.rb +8 -9
- data/lib/samagotchi/tools/task_stop.rb +1 -1
- data/lib/samagotchi/tools/task_wait.rb +3 -4
- data/lib/samagotchi/tools/web_fetch.rb +2 -4
- data/lib/samagotchi/tools/write.rb +1 -1
- data/lib/samagotchi/turn_flow.rb +8 -8
- data/lib/samagotchi/turn_note.rb +5 -1
- data/lib/samagotchi/turn_state.rb +22 -0
- data/lib/samagotchi/version.rb +1 -1
- data/lib/samagotchi/vision_support.rb +2 -2
- data/lib/samagotchi/web/app.rb +13 -6
- data/lib/samagotchi/web/markdown_renderer.rb +2 -1
- data/lib/samagotchi/web/qr.rb +7 -1
- data/lib/samagotchi/web/server.rb +6 -2
- data/lib/samagotchi/worker.rb +10 -2
- metadata +21 -20
|
@@ -121,7 +121,7 @@ module Samagotchi
|
|
|
121
121
|
when "trash" then trash(@argv[1..])
|
|
122
122
|
else
|
|
123
123
|
@stderr.puts "Unknown bundle subcommand: #{sub}. Use: install, upgrade, uninstall, status, diff, list, build, trash"
|
|
124
|
-
|
|
124
|
+
CLI::Exit::USAGE
|
|
125
125
|
end
|
|
126
126
|
end
|
|
127
127
|
|
|
@@ -131,7 +131,8 @@ module Samagotchi
|
|
|
131
131
|
parsed = parse_flags(INSTALL_FLAGS, rest, "install", help: INSTALL_HELP)
|
|
132
132
|
return parsed if parsed.is_a?(Integer)
|
|
133
133
|
|
|
134
|
-
opts
|
|
134
|
+
opts = parsed.options
|
|
135
|
+
source = parsed.args.last
|
|
135
136
|
scope = opts[:scope]
|
|
136
137
|
force = opts.fetch(:force, false)
|
|
137
138
|
if source.nil? || source.empty?
|
|
@@ -142,6 +143,7 @@ module Samagotchi
|
|
|
142
143
|
if Samagotchi::MemoryBundle::Profile.shipped_meta?(expanded_source)
|
|
143
144
|
return install_profile(expanded_source, scope: scope, force: force, dry_run: false, word: "Install")
|
|
144
145
|
end
|
|
146
|
+
|
|
145
147
|
bundle_name = bundle_name_or_fail(expanded_source, "Install") or return 1
|
|
146
148
|
run_installer(installer_for(expanded_source, bundle_name, scope: scope, force: force), failed: "Install") do |manifest|
|
|
147
149
|
print_hooks_and_plugin(manifest)
|
|
@@ -153,7 +155,8 @@ module Samagotchi
|
|
|
153
155
|
parsed = parse_flags(UPGRADE_FLAGS, rest, "upgrade", help: UPGRADE_HELP)
|
|
154
156
|
return parsed if parsed.is_a?(Integer)
|
|
155
157
|
|
|
156
|
-
opts
|
|
158
|
+
opts = parsed.options
|
|
159
|
+
source = parsed.args.last
|
|
157
160
|
scope = opts[:scope]
|
|
158
161
|
force = opts.fetch(:force, false)
|
|
159
162
|
dry_run = opts.fetch(:dry_run, false)
|
|
@@ -166,6 +169,7 @@ module Samagotchi
|
|
|
166
169
|
if Samagotchi::MemoryBundle::Profile.shipped_meta?(expanded_source)
|
|
167
170
|
return install_profile(expanded_source, scope: scope, force: force, dry_run: dry_run, word: "Upgrade")
|
|
168
171
|
end
|
|
172
|
+
|
|
169
173
|
bundle_name = bundle_name_or_fail(expanded_source, "Upgrade") or return 1
|
|
170
174
|
unless Samagotchi::MemoryBundle::Provenance.new(name: bundle_name).installed?
|
|
171
175
|
@stderr.puts "Bundle '#{bundle_name}' not installed — falling back to install"
|
|
@@ -195,8 +199,8 @@ module Samagotchi
|
|
|
195
199
|
nil
|
|
196
200
|
end
|
|
197
201
|
|
|
198
|
-
def installer_for(source, name, scope:, force:, **
|
|
199
|
-
Samagotchi::MemoryBundle::Installer.new(source: source, name: name, scope: scope, force: force, strict: true, **
|
|
202
|
+
def installer_for(source, name, scope:, force:, **)
|
|
203
|
+
Samagotchi::MemoryBundle::Installer.new(source: source, name: name, scope: scope, force: force, strict: true, **)
|
|
200
204
|
end
|
|
201
205
|
|
|
202
206
|
# Runs +installer+, prints its summary, then yields the manifest.
|
|
@@ -217,7 +221,7 @@ module Samagotchi
|
|
|
217
221
|
end
|
|
218
222
|
|
|
219
223
|
def print_hooks_and_plugin(manifest, plugin: true)
|
|
220
|
-
@stdout.puts "Hooks: #{manifest.hooks.size} hook(s) (#{manifest.hooks.keys.join(
|
|
224
|
+
@stdout.puts "Hooks: #{manifest.hooks.size} hook(s) (#{manifest.hooks.keys.join(", ")})" if manifest&.hooks&.any?
|
|
221
225
|
@stdout.puts "Plugin: #{manifest.plugin[:file]} (loads at the next chi start)" if plugin && manifest&.plugin
|
|
222
226
|
end
|
|
223
227
|
|
|
@@ -245,7 +249,7 @@ module Samagotchi
|
|
|
245
249
|
installer.conflicts.each { |k, _| @stdout.puts " conflict: #{k}" }
|
|
246
250
|
launch = if agent.nil? && @stdin.tty?
|
|
247
251
|
@stdout.print "Conflicts detected — launch interactive agent to resolve? [y/N] "
|
|
248
|
-
ans = begin; @stdin.gets; rescue => _e; nil; end
|
|
252
|
+
ans = begin; @stdin.gets; rescue StandardError => _e; nil; end
|
|
249
253
|
ans && ans.strip.downcase.start_with?("y")
|
|
250
254
|
elsif agent.nil?
|
|
251
255
|
@stdout.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."
|
|
@@ -279,7 +283,8 @@ module Samagotchi
|
|
|
279
283
|
parsed = parse_flags(UNINSTALL_FLAGS, rest, "uninstall", help: UNINSTALL_HELP)
|
|
280
284
|
return parsed if parsed.is_a?(Integer)
|
|
281
285
|
|
|
282
|
-
opts
|
|
286
|
+
opts = parsed.options
|
|
287
|
+
bundle_name = parsed.args.last
|
|
283
288
|
scope = opts[:scope]
|
|
284
289
|
force = opts.fetch(:force, false)
|
|
285
290
|
if bundle_name.nil? || bundle_name.empty?
|
|
@@ -294,13 +299,13 @@ module Samagotchi
|
|
|
294
299
|
uninstaller.run
|
|
295
300
|
@stdout.puts "Uninstalled bundle '#{bundle_name}'"
|
|
296
301
|
puts_trashed(uninstaller.trashed_files, uninstaller.trash_dir)
|
|
297
|
-
@stdout.puts "Removed: #{uninstaller.removed_files.join(
|
|
302
|
+
@stdout.puts "Removed: #{uninstaller.removed_files.join(", ")}" unless uninstaller.removed_files.empty?
|
|
298
303
|
hook_removed = uninstaller.removed_files.count { |f| f.start_with?("hooks/") }
|
|
299
304
|
@stdout.puts "Hooks removed: #{hook_removed}" if hook_removed > 0
|
|
300
305
|
uninstaller.warnings.each { |w| @stdout.puts w }
|
|
301
|
-
|
|
306
|
+
0
|
|
302
307
|
rescue Samagotchi::MemoryBundle::Uninstaller::UninstallError => e
|
|
303
|
-
@stderr.puts "Uninstall failed: #{e.message}";
|
|
308
|
+
@stderr.puts "Uninstall failed: #{e.message}"; 1
|
|
304
309
|
end
|
|
305
310
|
end
|
|
306
311
|
|
|
@@ -432,7 +437,7 @@ module Samagotchi
|
|
|
432
437
|
@stdout.puts " #{bname} v#{st[:provenance][:version]} scope=#{status_scope(st)} files=#{st[:files].size}#{hook_info}#{plugin_info}#{includes_info} issues=#{mods}"
|
|
433
438
|
end
|
|
434
439
|
end
|
|
435
|
-
|
|
440
|
+
0
|
|
436
441
|
end
|
|
437
442
|
|
|
438
443
|
# "team (unknown)" for a scope this chi can't resolve (Status#bundle_status).
|
|
@@ -467,7 +472,7 @@ module Samagotchi
|
|
|
467
472
|
@stdout.puts File.exist?(base) ? File.read(base) : "(no base)"
|
|
468
473
|
@stdout.puts "--- current (on-disk) ---"
|
|
469
474
|
@stdout.puts File.exist?(plugin_path) ? File.read(plugin_path) : "(missing)"
|
|
470
|
-
@stdout.puts "--- metadata: sha256=#{data[:plugin][:sha256]}#{
|
|
475
|
+
@stdout.puts "--- metadata: sha256=#{data[:plugin][:sha256]}#{" requires_chi=#{data[:requires_chi]}" if data[:requires_chi]}"
|
|
471
476
|
end
|
|
472
477
|
if file_arg
|
|
473
478
|
# Try file first, then hook
|
|
@@ -491,7 +496,7 @@ module Samagotchi
|
|
|
491
496
|
meta = hooks[file_arg.to_sym] || hooks[file_arg]
|
|
492
497
|
if meta
|
|
493
498
|
m = meta.transform_keys(&:to_s)
|
|
494
|
-
@stdout.puts "--- metadata: event=#{m[
|
|
499
|
+
@stdout.puts "--- metadata: event=#{m["event"]} on_error=#{m["on_error"]} priority=#{m["priority"]} sha256=#{m["sha256"]}"
|
|
495
500
|
end
|
|
496
501
|
elsif plugin_file && [plugin_file, "plugin/#{plugin_file}"].include?(file_arg)
|
|
497
502
|
show_plugin.call
|
|
@@ -524,7 +529,7 @@ module Samagotchi
|
|
|
524
529
|
meta = hooks[k.to_sym] || hooks[k]
|
|
525
530
|
if meta
|
|
526
531
|
m = meta.transform_keys(&:to_s)
|
|
527
|
-
@stdout.puts "--- metadata: event=#{m[
|
|
532
|
+
@stdout.puts "--- metadata: event=#{m["event"]} on_error=#{m["on_error"]} priority=#{m["priority"]} sha256=#{m["sha256"]}"
|
|
528
533
|
end
|
|
529
534
|
@stdout.puts ""
|
|
530
535
|
end
|
|
@@ -533,7 +538,7 @@ module Samagotchi
|
|
|
533
538
|
@stdout.puts ""
|
|
534
539
|
end
|
|
535
540
|
end
|
|
536
|
-
|
|
541
|
+
0
|
|
537
542
|
end
|
|
538
543
|
|
|
539
544
|
def list
|
|
@@ -552,6 +557,7 @@ module Samagotchi
|
|
|
552
557
|
@stdout.puts "Installed:"
|
|
553
558
|
installed.each do |b|
|
|
554
559
|
next @stdout.puts(" #{b.name.ljust(name_w)} (#{b.error})") if b.error
|
|
560
|
+
|
|
555
561
|
line = " #{b.name.ljust(name_w)} #{"v#{b.version || "?"}".ljust(ver_w)} scope=#{b.scope || "?"} " \
|
|
556
562
|
"#{b.includes ? profile_members(b.includes, installed) : "files=#{b.files}"} installed=#{b.installed_at || "?"}"
|
|
557
563
|
line += " (shipped v#{b.upgrade.version}: chi bundle upgrade #{b.upgrade.source})" if b.upgrade
|
|
@@ -567,7 +573,7 @@ module Samagotchi
|
|
|
567
573
|
@stdout.puts " #{s.source.ljust(name_w)} #{"v#{s.version}".ljust(ver_w)} #{s.description}#{members}".rstrip
|
|
568
574
|
end
|
|
569
575
|
end
|
|
570
|
-
|
|
576
|
+
0
|
|
571
577
|
end
|
|
572
578
|
|
|
573
579
|
# An installed profile's list cell: its recorded members still
|
|
@@ -575,7 +581,7 @@ module Samagotchi
|
|
|
575
581
|
def profile_members(members, installed)
|
|
576
582
|
names = installed.map(&:name)
|
|
577
583
|
here, gone = members.partition { |m| names.include?(m) }
|
|
578
|
-
"includes=#{here.join(",")}#{
|
|
584
|
+
"includes=#{here.join(",")}#{" left out=#{gone.join(",")}" unless gone.empty?}"
|
|
579
585
|
end
|
|
580
586
|
|
|
581
587
|
def build(rest)
|
|
@@ -602,16 +608,16 @@ module Samagotchi
|
|
|
602
608
|
result = builder.run
|
|
603
609
|
@stdout.puts "Built #{result[:files].size} file(s) to #{result[:out_path]}"
|
|
604
610
|
@stdout.puts "Bundle: #{result[:name]} v#{result[:version]} scope=#{result[:scope]}"
|
|
605
|
-
@stdout.puts "Files: #{result[:files].join(
|
|
611
|
+
@stdout.puts "Files: #{result[:files].join(", ")}" unless result[:files].empty?
|
|
606
612
|
builder.warnings.each { |w| @stdout.puts w }
|
|
607
613
|
unless result[:placeholder_warnings].empty?
|
|
608
614
|
@stdout.puts "Placeholders:"
|
|
609
615
|
result[:placeholder_warnings].each { |w| @stdout.puts " #{w}" }
|
|
610
616
|
end
|
|
611
|
-
|
|
617
|
+
0
|
|
612
618
|
rescue Samagotchi::MemoryBundle::Builder::BuildError => e
|
|
613
619
|
@stderr.puts "Build failed: #{e.message}"
|
|
614
|
-
|
|
620
|
+
1
|
|
615
621
|
end
|
|
616
622
|
end
|
|
617
623
|
|
|
@@ -655,7 +661,7 @@ module Samagotchi
|
|
|
655
661
|
end
|
|
656
662
|
|
|
657
663
|
entries.each do |e|
|
|
658
|
-
@stdout.puts " #{e.name} #{e.files} file#{
|
|
664
|
+
@stdout.puts " #{e.name} #{e.files} file#{"s" unless e.files == 1} #{format_bytes(e.bytes)} #{format_age(e.time)}"
|
|
659
665
|
end
|
|
660
666
|
@stdout.puts "\nEmpty it with: chi bundle trash --empty [--older-than DAYS]"
|
|
661
667
|
0
|
|
@@ -664,7 +670,7 @@ module Samagotchi
|
|
|
664
670
|
def do_empty(older_than_days:, dry_run:)
|
|
665
671
|
entries = Samagotchi::MemoryBundle::Trash.empty!(
|
|
666
672
|
older_than_days: older_than_days,
|
|
667
|
-
dry_run: dry_run
|
|
673
|
+
dry_run: dry_run
|
|
668
674
|
)
|
|
669
675
|
if entries.empty?
|
|
670
676
|
@stdout.puts "The bundle trash is empty."
|
|
@@ -674,11 +680,11 @@ module Samagotchi
|
|
|
674
680
|
total_files = entries.sum(&:files)
|
|
675
681
|
if dry_run
|
|
676
682
|
entries.each do |e|
|
|
677
|
-
@stdout.puts "Would delete: #{e.name} (#{e.files} file#{
|
|
683
|
+
@stdout.puts "Would delete: #{e.name} (#{e.files} file#{"s" unless e.files == 1}, #{format_bytes(e.bytes)})"
|
|
678
684
|
end
|
|
679
|
-
@stdout.puts "\n(dry-run: #{entries.size} folder#{
|
|
685
|
+
@stdout.puts "\n(dry-run: #{entries.size} folder#{"s" unless entries.size == 1}, #{total_files} file#{"s" unless total_files == 1})"
|
|
680
686
|
else
|
|
681
|
-
@stdout.puts "Deleted #{entries.size} folder#{
|
|
687
|
+
@stdout.puts "Deleted #{entries.size} folder#{"s" unless entries.size == 1} (#{total_files} file#{"s" unless total_files == 1}) from the trash."
|
|
682
688
|
end
|
|
683
689
|
0
|
|
684
690
|
end
|
|
@@ -686,6 +692,7 @@ module Samagotchi
|
|
|
686
692
|
# Format bytes as human-readable (B, KB, MB with one decimal)
|
|
687
693
|
def format_bytes(bytes)
|
|
688
694
|
return "0 B" if bytes == 0
|
|
695
|
+
|
|
689
696
|
if bytes < 1024
|
|
690
697
|
"#{bytes} B"
|
|
691
698
|
elsif bytes < 1_048_576
|
|
@@ -731,6 +738,7 @@ module Samagotchi
|
|
|
731
738
|
# helpers for bundle_name derivation
|
|
732
739
|
def expand_source(src)
|
|
733
740
|
return src if Samagotchi::MemoryBundle::SourceNormalizer.git_url?(src)
|
|
741
|
+
|
|
734
742
|
Samagotchi::MemoryBundle::SourceNormalizer.shipped_bundle_dir(src) || File.expand_path(src)
|
|
735
743
|
end
|
|
736
744
|
|
|
@@ -749,13 +757,13 @@ module Samagotchi
|
|
|
749
757
|
begin
|
|
750
758
|
nd, owned = Samagotchi::MemoryBundle::SourceNormalizer.normalize(expanded_src)
|
|
751
759
|
m = Samagotchi::MemoryBundle::Manifest.read(dir: nd)
|
|
752
|
-
|
|
760
|
+
m.name
|
|
753
761
|
rescue Samagotchi::MemoryBundle::Manifest::ValidationError
|
|
754
762
|
# Fallback to source basename without archive extensions
|
|
755
763
|
src = expanded_src
|
|
756
764
|
name = File.basename(src)
|
|
757
765
|
name = name.sub(/\.tar\.gz\z/i, "").sub(/\.tgz\z/i, "").sub(/\.zip\z/i, "").sub(/\.tar\z/i, "")
|
|
758
|
-
|
|
766
|
+
name.empty? ? File.basename(nd || src) : name
|
|
759
767
|
ensure
|
|
760
768
|
Samagotchi::MemoryBundle::SourceNormalizer.cleanup(nd) if owned
|
|
761
769
|
end
|
|
@@ -785,6 +793,7 @@ module Samagotchi
|
|
|
785
793
|
preview = []
|
|
786
794
|
max.times do |i|
|
|
787
795
|
break if preview.size >= 30
|
|
796
|
+
|
|
788
797
|
c = cur_lines[i]
|
|
789
798
|
n = inc_lines[i]
|
|
790
799
|
if c != n
|
|
@@ -795,7 +804,8 @@ module Samagotchi
|
|
|
795
804
|
lines.concat(preview)
|
|
796
805
|
lines << " --- end preview ---"
|
|
797
806
|
end
|
|
798
|
-
rescue
|
|
807
|
+
rescue StandardError
|
|
808
|
+
# No preview for a file that can't be read: the diff lines stand alone.
|
|
799
809
|
end
|
|
800
810
|
end
|
|
801
811
|
lines << ""
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: btw
|
|
3
|
-
version: 0.1.
|
|
3
|
+
version: 0.1.2
|
|
4
4
|
scope: system
|
|
5
5
|
description: "/btw <question>: a side answer about the conversation, as a card in every UI, even mid-turn; Keep as session forks it into a child session"
|
|
6
6
|
trust_level: reviewed
|
|
7
7
|
plugin:
|
|
8
8
|
file: plugin.rb
|
|
9
|
-
sha256: sha256:
|
|
9
|
+
sha256: sha256:226a251865695a86cdb05d6b6318fc062e0ab54518bb25733699db964cbed80b
|
|
10
10
|
requires_chi: ">= 0.1.30"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: check-in
|
|
3
|
-
version: 0.2.
|
|
3
|
+
version: 0.2.2
|
|
4
4
|
scope: system
|
|
5
5
|
description: "Checks on a long turn: after N tool calls with no answer, a card asks the user (Nudge / Keep going / Stop), or the model is nudged to say what it has found"
|
|
6
6
|
trust_level: reviewed
|
|
7
7
|
plugin:
|
|
8
8
|
file: plugin.rb
|
|
9
|
-
sha256: sha256:
|
|
9
|
+
sha256: sha256:52fcb0a3beccfee1e70e7d73162eace603da11bee43e535b1bc17d55eae98334
|
|
10
10
|
requires_chi: ">= 0.3.0"
|
|
@@ -24,11 +24,11 @@ class KnownNames
|
|
|
24
24
|
# Splits a command or path into tokens; each token's [-_.] parts are
|
|
25
25
|
# candidates too. "~" splits: in "~name" (that user's home) the name
|
|
26
26
|
# after it is what is checked.
|
|
27
|
-
TOKEN_SPLIT = %r{[/\s"'=:,;|&()<>@~]+}
|
|
28
|
-
PART_SPLIT = /[-_.]
|
|
27
|
+
TOKEN_SPLIT = %r{[/\s"'=:,;|&()<>@~]+}
|
|
28
|
+
PART_SPLIT = /[-_.]+/
|
|
29
29
|
# A candidate with a shell glob character is not checked: `workato*`
|
|
30
30
|
# is a pattern over the name, not a misspelling of it.
|
|
31
|
-
GLOB = /[*?\[\]{}]
|
|
31
|
+
GLOB = /[*?\[\]{}]/
|
|
32
32
|
ASK_OPTIONS = ["Correct it and run", "Run as is", "Deny"].freeze
|
|
33
33
|
|
|
34
34
|
def initialize(settings = {})
|
|
@@ -134,6 +134,7 @@ class KnownNames
|
|
|
134
134
|
names = @names + derived_names(event)
|
|
135
135
|
names.each_with_object({}) do |name, acc|
|
|
136
136
|
next if name.length < @min_length
|
|
137
|
+
|
|
137
138
|
down = name.downcase
|
|
138
139
|
next if @ignore.include?(down) || acc.key?(down)
|
|
139
140
|
|
|
@@ -149,7 +150,7 @@ class KnownNames
|
|
|
149
150
|
root = context[:repo_root].to_s
|
|
150
151
|
names << File.basename(root) if @derive.include?("repo") && !root.empty?
|
|
151
152
|
names.concat(git_names(root)) if @derive.include?("git") && !root.empty?
|
|
152
|
-
names.map
|
|
153
|
+
names.map { |name| name.to_s.strip }.reject(&:empty?)
|
|
153
154
|
rescue StandardError
|
|
154
155
|
names
|
|
155
156
|
end
|
|
@@ -216,6 +217,6 @@ class KnownNames
|
|
|
216
217
|
end
|
|
217
218
|
|
|
218
219
|
def list(value)
|
|
219
|
-
Array(value).map
|
|
220
|
+
Array(value).map { |name| name.to_s.strip }.reject(&:empty?)
|
|
220
221
|
end
|
|
221
222
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: known-names
|
|
3
|
-
version: 0.1.
|
|
3
|
+
version: 0.1.5
|
|
4
4
|
scope: system
|
|
5
5
|
description: Catches a near-miss of a protected name (home folder, login, git name, repo name, names from config) in a tool call and rejects it with the right spelling; mode ask / correct optional
|
|
6
6
|
trust_level: reviewed
|
|
@@ -8,7 +8,7 @@ files:
|
|
|
8
8
|
known_names.md: sha256:d5348b95b6c655017b541910b36e384220da280818160201f6ec9a50e1e4287c
|
|
9
9
|
hooks:
|
|
10
10
|
known_names.rb:
|
|
11
|
-
sha256: sha256:
|
|
11
|
+
sha256: sha256:acff04fbe284b44644ca7140d574c1c0ebd2d999ede1243cd3fe0f432bfbb6d2
|
|
12
12
|
event: before_tool_call
|
|
13
13
|
on_error: log
|
|
14
14
|
priority: 50
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: loop-guard
|
|
3
|
-
version: 0.3.
|
|
3
|
+
version: 0.3.2
|
|
4
4
|
scope: system
|
|
5
5
|
description: "Breaks loops: the same tool call with the same result again and again in one turn is denied with advice (after a few denies the turn stops with a card), and thinking that repeats itself while it streams is cut and the model asked again"
|
|
6
6
|
trust_level: reviewed
|
|
7
7
|
plugin:
|
|
8
8
|
file: plugin.rb
|
|
9
|
-
sha256: sha256:
|
|
9
|
+
sha256: sha256:27b135c462d8462313edaa1faa90f3104a1bff3c421d6965e9e71955f347d55b
|
|
10
10
|
requires_chi: ">= 0.6.0"
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mcp
|
|
3
|
-
version: 0.4.
|
|
3
|
+
version: 0.4.2
|
|
4
4
|
scope: system
|
|
5
5
|
description: "Tools from MCP servers (stdio): each server in config.yml bundles: mcp: servers: runs for the session, its tools are mcp_<server>_<tool>; /mcp lists them"
|
|
6
6
|
trust_level: reviewed
|
|
7
7
|
files: {}
|
|
8
8
|
plugin:
|
|
9
9
|
file: plugin.rb
|
|
10
|
-
sha256: sha256:
|
|
10
|
+
sha256: sha256:d0491b038e7f111f9f8c629729a2b0525d573fd0b17d48ea8ec59c4a2b8b821b
|
|
11
11
|
requires_chi: ">= 0.8.0"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: skills
|
|
3
|
-
version: 0.1.
|
|
3
|
+
version: 0.1.6
|
|
4
4
|
scope: system
|
|
5
5
|
description: "Skills (skill_<name> memories, the steps of a task done together): /skill save, list, show and diff; older versions kept with a short diff line on every update; a nudge when a followed skill's step fails"
|
|
6
6
|
trust_level: reviewed
|
|
7
7
|
plugin:
|
|
8
8
|
file: plugin.rb
|
|
9
|
-
sha256: sha256:
|
|
9
|
+
sha256: sha256:16aefdff7d7702a5feb9b2bafb9d975ceaa47f2864ad40f6df3624f4ba714136
|
|
10
10
|
requires_chi: ">= 0.11.0"
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# The skills bundle (docs/plugins.md, The skills bundle): a skill is a memory
|
|
2
4
|
# named skill_<name> that holds the steps of a task done with the user
|
|
3
5
|
# (docs/memory.md, Skills). The system bundle's identity already tells the
|
|
@@ -128,7 +130,7 @@ class Plugin
|
|
|
128
130
|
removed = ops.count { |op, _| op == :del }
|
|
129
131
|
first = ops.find { |op, _| op == :add } || ops.find { |op, _| op == :del }
|
|
130
132
|
line = first ? cut(first.last.strip) : ""
|
|
131
|
-
"skill #{name} updated (+#{added} −#{removed})#{
|
|
133
|
+
"skill #{name} updated (+#{added} −#{removed})#{": #{line}" unless line.empty?} · /skill diff #{name}"
|
|
132
134
|
end
|
|
133
135
|
|
|
134
136
|
# --- the nudge ------------------------------------------------------------
|
|
@@ -289,7 +291,7 @@ class Plugin
|
|
|
289
291
|
next unless skill_name(name) == name
|
|
290
292
|
|
|
291
293
|
date, description = index.fetch("skill_#{name}", [nil, nil])
|
|
292
|
-
line =
|
|
294
|
+
line = "#{name} · #{scope}"
|
|
293
295
|
line << " · #{date}" if date
|
|
294
296
|
line << " — #{description}" if description
|
|
295
297
|
line
|
|
@@ -338,7 +340,7 @@ class Plugin
|
|
|
338
340
|
return "" if changed.empty?
|
|
339
341
|
|
|
340
342
|
# Group changes whose context would touch into one hunk.
|
|
341
|
-
groups = changed.slice_when { |x, y| y - x > 2 * CONTEXT + 1 }.to_a
|
|
343
|
+
groups = changed.slice_when { |x, y| y - x > (2 * CONTEXT) + 1 }.to_a
|
|
342
344
|
old_at = new_at = 0
|
|
343
345
|
positions = ops.map do |op, _|
|
|
344
346
|
at = [old_at, new_at]
|
|
@@ -60,7 +60,7 @@ class SourceLinks
|
|
|
60
60
|
REGEX_TIMEOUT = 0.5
|
|
61
61
|
# A bare URL (scheme-anchored, so it can't start inside a markdown label),
|
|
62
62
|
# and a markdown link (label in group 1, target in group 2).
|
|
63
|
-
URL_SPAN = %r{[a-z][a-z0-9
|
|
63
|
+
URL_SPAN = %r{[a-z][a-z0-9+.-]*://\S+}i
|
|
64
64
|
MARKDOWN_LINK = /\[([^\]]*)\]\(([^)]*)\)/
|
|
65
65
|
# A fenced code block's opening line (up to 3 spaces, then ``` or ~~~).
|
|
66
66
|
FENCE_OPEN = /\A {0,3}(`{3,}|~{3,})/
|
|
@@ -84,7 +84,7 @@ class SourceLinks
|
|
|
84
84
|
return nil unless match
|
|
85
85
|
|
|
86
86
|
host = match[1]
|
|
87
|
-
repo = match[2].to_s.sub(%r{\A/+}, "").sub(%r{/+\z}, "").
|
|
87
|
+
repo = match[2].to_s.sub(%r{\A/+}, "").sub(%r{/+\z}, "").delete_suffix(".git").sub(%r{/+\z}, "")
|
|
88
88
|
segments = repo.split("/", -1)
|
|
89
89
|
return nil if host.empty? || segments.empty? || segments.any? { |segment| ["", ".", ".."].include?(segment) }
|
|
90
90
|
|
|
@@ -322,7 +322,7 @@ class SourceLinks
|
|
|
322
322
|
in_target = start >= link[:target][0] && finish <= link[:target][1]
|
|
323
323
|
in_label = start >= link[:label][0] && finish <= link[:label][1]
|
|
324
324
|
in_target || (in_label && target_names_ref?(link[:target_text], text[start...finish],
|
|
325
|
-
|
|
325
|
+
case_insensitive: match.regexp.casefold?))
|
|
326
326
|
end
|
|
327
327
|
end
|
|
328
328
|
|
|
@@ -354,7 +354,7 @@ class SourceLinks
|
|
|
354
354
|
|
|
355
355
|
def line(found)
|
|
356
356
|
shown = found.first(@max)
|
|
357
|
-
text = "sources: #{shown.map { |name, ref, url| "#{name} #{ref} → #{url}" }.join(
|
|
357
|
+
text = "sources: #{shown.map { |name, ref, url| "#{name} #{ref} → #{url}" }.join(", ")}"
|
|
358
358
|
extra = found.size - shown.size
|
|
359
359
|
text += ", … +#{extra} more" if extra.positive?
|
|
360
360
|
text
|
|
@@ -411,7 +411,7 @@ class SourceLinks
|
|
|
411
411
|
groups = group_count(regex)
|
|
412
412
|
known, unknown = used.partition do |word|
|
|
413
413
|
if word.match?(/\A\d+\z/)
|
|
414
|
-
groups.nil? ||
|
|
414
|
+
groups.nil? || word.to_i.between?(1, groups)
|
|
415
415
|
else
|
|
416
416
|
BUILTIN_PLACEHOLDERS.include?(word) || regex.names.include?(word)
|
|
417
417
|
end
|
|
@@ -430,7 +430,7 @@ class SourceLinks
|
|
|
430
430
|
def group_count(regex)
|
|
431
431
|
probe = Regexp.new("(?:#{regex.source}\n)|", regex.options, timeout: REGEX_TIMEOUT)
|
|
432
432
|
probe.match("").size - 1
|
|
433
|
-
rescue RegexpError
|
|
433
|
+
rescue RegexpError # Regexp::TimeoutError is one
|
|
434
434
|
nil
|
|
435
435
|
end
|
|
436
436
|
|
|
@@ -528,6 +528,6 @@ class SourceLinks
|
|
|
528
528
|
|
|
529
529
|
# A capture group is free-form, so escape what goes into the URL path.
|
|
530
530
|
def escape_url(value)
|
|
531
|
-
value.to_s.gsub(
|
|
531
|
+
value.to_s.gsub(/[^A-Za-z0-9\-._~]/) { |c| c.bytes.map { |b| format("%%%02X", b) }.join }
|
|
532
532
|
end
|
|
533
533
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: source-links
|
|
3
|
-
version: 0.3.
|
|
3
|
+
version: 0.3.3
|
|
4
4
|
scope: system
|
|
5
5
|
description: Links source refs (JIRA tickets, GitHub issues, …) in the model's answer — inline links in the web, and a one-line note after the turn (note false turns it off); sources are configured patterns
|
|
6
6
|
trust_level: reviewed
|
|
@@ -8,7 +8,7 @@ files:
|
|
|
8
8
|
source_links.md: sha256:aebd37f1e25491780994ecc4afc20ed6e8db32b724dc038302bb050177efada8
|
|
9
9
|
hooks:
|
|
10
10
|
source_links.rb:
|
|
11
|
-
sha256: sha256:
|
|
11
|
+
sha256: sha256:454d3512a4aa078b288ff6d0ed25867222a56ead1a57ef1eaa14918e631fec23
|
|
12
12
|
event: after_turn
|
|
13
13
|
on_error: log
|
|
14
14
|
priority: 90
|
|
@@ -18,7 +18,7 @@ Single registry `Samagotchi::Config` (`Config::ENTRIES` in `lib/samagotchi/confi
|
|
|
18
18
|
|
|
19
19
|
Sections forbid `_`/`-` (`SECTION_RE` `/\A[a-z0-9]+\z/`); leaves keep `snake_case` in YAML (`base_url`) and become kebab in CLI (`base-url`) via registry derivation — no generic string split, registry lookup avoids flat vs nested collision.
|
|
20
20
|
|
|
21
|
-
**Universal entries** (`expose: [:env,:config,:cli]`): `default.model`, `server.host/port/transport/open_timeout/read_timeout`, `server.first_token_timeout` (env and config only), `recap.model/base_url/host_ref/inactivity/timeout/min_user_turns/sentences`, `session.retention_days/max_count/keep_status/sweep_interval_hours/idle_exit_minutes`, `session.shared/keep_empty/max_children` (env and config only), `log.file/disable`, `status.line`, `context.status/window_tokens/chars_per_token/status_thresholds/status_cadence`, `thinking.turn_preamble`, `default.
|
|
21
|
+
**Universal entries** (`expose: [:env,:config,:cli]`): `default.model`, `server.host/port/transport/open_timeout/read_timeout`, `server.first_token_timeout` (env and config only), `recap.model/base_url/host_ref/inactivity/timeout/min_user_turns/sentences`, `session.retention_days/max_count/keep_status/sweep_interval_hours/idle_exit_minutes`, `session.shared/keep_empty/max_children` (env and config only), `log.file/disable`, `status.line`, `context.status/window_tokens/chars_per_token/status_thresholds/status_cadence`, `thinking.turn_preamble`, `default.max_tokens`, `max_tool_output_chars`, `retry.max/base_delay/max_delay`, `read.*`, `execute.*`, `web.port/host`, `no_interrupt`, `no_default_input` etc. (`Config::ENTRIES`; `expose` says which of env/config/cli each takes). Precedence is `CLI > ENV > file > default`.
|
|
22
22
|
|
|
23
23
|
Example `config.yml` (new nested form, preferred):
|
|
24
24
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: samagotchi-system
|
|
3
|
-
version: 0.
|
|
3
|
+
version: 0.23.0
|
|
4
4
|
scope: system
|
|
5
5
|
description: Default system memories — identity, self map, config modification protocol, memory guide and the delegated-session rules
|
|
6
6
|
files:
|
|
7
7
|
identity.md: sha256:29c2f7df9f6c5acbc5ec17000a4490741e55e426af15ca0d81c8706edd9bd027
|
|
8
8
|
self_map.md: sha256:69bc0ec091fdaeedf6e3aa7365275461fe3eba32b2dedc9cf45044176c356af5
|
|
9
|
-
config_modification_protocol.md: sha256:
|
|
9
|
+
config_modification_protocol.md: sha256:ec0b0c7023dbf03b93879e51cd5cdc38b22d43a2e5984ee11e8542ace077c3be
|
|
10
10
|
memory_guide.md: sha256:17126f5adb9ef7b33c40e920ef339388c8c8c045b38a7de825b08760604db4e4
|
|
11
11
|
delegated.md: sha256:0a71d5dfa7127df2d51cb5f0e7214240ed88777e36559430a8724c796d7ae561
|
|
@@ -29,7 +29,7 @@ module Samagotchi
|
|
|
29
29
|
# @return [Integer] the usage exit status
|
|
30
30
|
def usage_error(message)
|
|
31
31
|
usage = usage_on_error
|
|
32
|
-
error_line("#{command_name}: #{message}#{
|
|
32
|
+
error_line("#{command_name}: #{message}#{" (see #{command_name} --help)" unless usage}")
|
|
33
33
|
@stderr.puts(usage) if usage
|
|
34
34
|
Exit::USAGE
|
|
35
35
|
end
|
|
@@ -64,10 +64,11 @@ module Samagotchi
|
|
|
64
64
|
result.text = result.text&.dup&.force_encoding(Encoding::UTF_8)&.scrub
|
|
65
65
|
@reported = true
|
|
66
66
|
ParentReport.report(result, session_id: id, stdout: @stdout, stderr: @stderr, command: command_name,
|
|
67
|
-
json: @json, timeout: timeout)
|
|
67
|
+
json: @json, timeout: timeout, extra: report_extra)
|
|
68
68
|
rescue Interrupt
|
|
69
69
|
if @json
|
|
70
|
-
@stdout.puts(ParentReport.json_line(ReplyWait::Result.new(status: :canceled), session_id: id
|
|
70
|
+
@stdout.puts(ParentReport.json_line(ReplyWait::Result.new(status: :canceled), session_id: id,
|
|
71
|
+
extra: report_extra))
|
|
71
72
|
@stdout.flush
|
|
72
73
|
@reported = true
|
|
73
74
|
end
|
|
@@ -77,6 +78,12 @@ module Samagotchi
|
|
|
77
78
|
error_line("#{command_name}: the session is gone (deleted while waiting)")
|
|
78
79
|
Exit::FAILED
|
|
79
80
|
end
|
|
81
|
+
|
|
82
|
+
# More keys for the JSON object: answered_here: false when chi
|
|
83
|
+
# answer's answer didn't go in (the question was no longer open).
|
|
84
|
+
def report_extra
|
|
85
|
+
@answered_here == false ? { answered_here: false } : {}
|
|
86
|
+
end
|
|
80
87
|
end
|
|
81
88
|
end
|
|
82
89
|
end
|
data/lib/samagotchi/client.rb
CHANGED
|
@@ -224,9 +224,7 @@ module Samagotchi
|
|
|
224
224
|
attr_reader :host_name
|
|
225
225
|
|
|
226
226
|
# The wire-format strategy for this client's transport.
|
|
227
|
-
|
|
228
|
-
@transport
|
|
229
|
-
end
|
|
227
|
+
attr_reader :transport
|
|
230
228
|
|
|
231
229
|
# Send a raw prompt and return the model's completion text.
|
|
232
230
|
#
|
|
@@ -246,7 +244,7 @@ module Samagotchi
|
|
|
246
244
|
# @param sampling [Hash] request fields to add (SamplingSettings):
|
|
247
245
|
# temperature, penalties, …; they can't replace the fields above
|
|
248
246
|
# @return [String] the generated text
|
|
249
|
-
def complete(prompt, stop: [
|
|
247
|
+
def complete(prompt, stop: [], n_predict: nil, model: nil, on_chunk: nil, cancel_controller: nil, on_retry: nil,
|
|
250
248
|
images: [], sampling: {})
|
|
251
249
|
images = Array(images)
|
|
252
250
|
request = { stop: stop, n_predict: n_predict, model: model, sampling: sampling }
|
|
@@ -449,7 +447,7 @@ module Samagotchi
|
|
|
449
447
|
when :omlx
|
|
450
448
|
->(model) { resolve_omlx_model(model) }
|
|
451
449
|
when :mlx
|
|
452
|
-
->(_model) {
|
|
450
|
+
->(_model) {}
|
|
453
451
|
end
|
|
454
452
|
Transport.new(name, model_resolver: resolver)
|
|
455
453
|
end
|