samagotchi 0.22.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 +33 -1
- data/bin/chi +9 -4
- data/docs/configuration.md +4 -4
- data/docs/releasing.md +1 -1
- data/docs/testing.md +6 -0
- data/lib/samagotchi/answer_command.rb +4 -2
- 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/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 +15 -8
- 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 +17 -17
- 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 +2 -2
- data/lib/samagotchi/llm/http.rb +12 -12
- data/lib/samagotchi/llm/openai_chat.rb +39 -28
- data/lib/samagotchi/llm/prompt_cache.rb +1 -1
- 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/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 -7
- 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/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/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 +20 -20
data/lib/samagotchi/turn_flow.rb
CHANGED
|
@@ -27,10 +27,10 @@ module Samagotchi
|
|
|
27
27
|
return [:resume, nil] if normalized.empty?
|
|
28
28
|
|
|
29
29
|
lowered = normalized.downcase
|
|
30
|
-
return [:resume, nil] if
|
|
31
|
-
return [:abort, nil] if
|
|
30
|
+
return [:resume, nil] if [CONTINUE_COMMAND, "yes", "y"].include?(lowered)
|
|
31
|
+
return [:abort, nil] if %w[no n].include?(lowered)
|
|
32
32
|
|
|
33
|
-
reason_match = normalized.match(/\A(?:no|n)\s*[
|
|
33
|
+
reason_match = normalized.match(/\A(?:no|n)\s*[,:-]\s*(.+)\z/i)
|
|
34
34
|
if reason_match
|
|
35
35
|
reason = reason_match[1].to_s.strip
|
|
36
36
|
return [:abort, nil] if reason.empty?
|
|
@@ -220,11 +220,11 @@ module Samagotchi
|
|
|
220
220
|
lines << "- original_prompt: #{original_prompt.to_s.empty? ? "(unavailable)" : original_prompt}"
|
|
221
221
|
|
|
222
222
|
tool_trace = context ? Array(context[:tool_trace]) : []
|
|
223
|
-
if tool_trace.empty?
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
223
|
+
lines << if tool_trace.empty?
|
|
224
|
+
"- interrupted_tools: (none)"
|
|
225
|
+
else
|
|
226
|
+
"- interrupted_tools: #{tool_trace.join("; ")}"
|
|
227
|
+
end
|
|
228
228
|
|
|
229
229
|
model_intent = context && context[:last_model_intent]
|
|
230
230
|
lines << "- last_model_intent: #{model_intent.to_s.empty? ? "(unavailable)" : model_intent}"
|
data/lib/samagotchi/turn_note.rb
CHANGED
|
@@ -98,7 +98,11 @@ module Samagotchi
|
|
|
98
98
|
# emptyAnswerLine words it the same).
|
|
99
99
|
def empty_answer_line(retries)
|
|
100
100
|
count = retries.to_i
|
|
101
|
-
after = count.positive?
|
|
101
|
+
after = if count.positive?
|
|
102
|
+
" (after #{count} #{count == 1 ? "retry" : "retries"})"
|
|
103
|
+
else
|
|
104
|
+
""
|
|
105
|
+
end
|
|
102
106
|
"no answer: the model returned nothing#{after}"
|
|
103
107
|
end
|
|
104
108
|
|
data/lib/samagotchi/version.rb
CHANGED
|
@@ -45,7 +45,7 @@ module Samagotchi
|
|
|
45
45
|
marker.is_a?(String) && !marker.empty? ? marker : nil
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
def self.configured(
|
|
48
|
+
def self.configured(_target, entry, models, names)
|
|
49
49
|
models ||= begin
|
|
50
50
|
ConfigFile.model_settings
|
|
51
51
|
rescue StandardError
|
|
@@ -58,7 +58,7 @@ module Samagotchi
|
|
|
58
58
|
Answer.new(value: entry.vision, reason: entry.vision ? nil : "hosts.#{entry.name} sets vision: false")
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
def self.native(target,
|
|
61
|
+
def self.native(target, _entry, profile, trust_config:)
|
|
62
62
|
client = target.client
|
|
63
63
|
transport = client.transport.name
|
|
64
64
|
return no("#{transport} hosts take no images (only llama.cpp does)") unless transport == :llama_cpp
|
data/lib/samagotchi/web/app.rb
CHANGED
|
@@ -157,6 +157,7 @@ module Samagotchi
|
|
|
157
157
|
req = Rack::Request.new(env)
|
|
158
158
|
return forbidden unless local_host_header?(env)
|
|
159
159
|
return cross_origin if cross_site?(env)
|
|
160
|
+
|
|
160
161
|
if @lan && !LOOPBACK_PEERS.include?(env["REMOTE_ADDR"].to_s)
|
|
161
162
|
denied = token_gate(req)
|
|
162
163
|
return denied if denied
|
|
@@ -506,13 +507,16 @@ module Samagotchi
|
|
|
506
507
|
|
|
507
508
|
def sanitize_limit(val)
|
|
508
509
|
return nil if val.nil? || val.to_s.strip.empty?
|
|
510
|
+
|
|
509
511
|
n = val.to_i
|
|
510
512
|
return nil if n <= 0
|
|
513
|
+
|
|
511
514
|
[n, 1000].min
|
|
512
515
|
end
|
|
513
516
|
|
|
514
517
|
def sanitize_offset(val)
|
|
515
518
|
return 0 if val.nil? || val.to_s.strip.empty?
|
|
519
|
+
|
|
516
520
|
n = val.to_i
|
|
517
521
|
n.positive? ? n : 0
|
|
518
522
|
end
|
|
@@ -522,6 +526,7 @@ module Samagotchi
|
|
|
522
526
|
unless body.is_a?(Hash)
|
|
523
527
|
return error_response(400, "invalid_json", "invalid JSON body")
|
|
524
528
|
end
|
|
529
|
+
|
|
525
530
|
prompt = body["prompt"] || body[:prompt]
|
|
526
531
|
# idle: a session with no first turn, for a first message with
|
|
527
532
|
# images (the page uploads them into it, then sends the turn).
|
|
@@ -529,6 +534,7 @@ module Samagotchi
|
|
|
529
534
|
if prompt.to_s.strip.empty? && !idle
|
|
530
535
|
return error_response(400, "missing_fields", "prompt is required")
|
|
531
536
|
end
|
|
537
|
+
|
|
532
538
|
# dir: the folder the chat starts in (the page's scope); without it,
|
|
533
539
|
# the server's own cwd.
|
|
534
540
|
dir, error = scope_dir(body["dir"])
|
|
@@ -891,11 +897,13 @@ module Samagotchi
|
|
|
891
897
|
unless body.is_a?(Hash)
|
|
892
898
|
return error_response(400, "invalid_json", "invalid JSON body")
|
|
893
899
|
end
|
|
900
|
+
|
|
894
901
|
prompt = body["prompt"] || body[:prompt]
|
|
895
902
|
client_id = body["client_id"] || body[:client_id]
|
|
896
903
|
if prompt.to_s.strip.empty?
|
|
897
904
|
return error_response(400, "missing_fields", "prompt is required")
|
|
898
905
|
end
|
|
906
|
+
|
|
899
907
|
images = turn_images(id, body["images"])
|
|
900
908
|
return error_response(400, "bad_images", images) if images.is_a?(String)
|
|
901
909
|
|
|
@@ -1173,7 +1181,7 @@ module Samagotchi
|
|
|
1173
1181
|
lambda do |io|
|
|
1174
1182
|
query = req.query_string.to_s.empty? ? "" : "?#{req.query_string}"
|
|
1175
1183
|
body = ProxyStreamBody.new(host: DEFAULT_HOST, port: port, session_id: id, query: query, headers: req.env,
|
|
1176
|
-
|
|
1184
|
+
server_running: @server_running)
|
|
1177
1185
|
body.each { |chunk| io.write(chunk) }
|
|
1178
1186
|
rescue Errno::EPIPE, Errno::ECONNRESET, IOError
|
|
1179
1187
|
nil # client went away — end the stream quietly
|
|
@@ -1249,7 +1257,7 @@ module Samagotchi
|
|
|
1249
1257
|
def serve_static(req)
|
|
1250
1258
|
# Serve files under public_dir for /assets/* and bare paths
|
|
1251
1259
|
rel = req.path_info.sub(%r{\A/(assets|public)/}, "")
|
|
1252
|
-
rel = req.path_info.
|
|
1260
|
+
rel = req.path_info.delete_prefix("/") if rel == req.path_info
|
|
1253
1261
|
# Prevent directory traversal
|
|
1254
1262
|
rel = rel.split("/").reject { |p| p == ".." || p.empty? }.join("/")
|
|
1255
1263
|
full = File.join(@public_dir, rel)
|
|
@@ -1483,7 +1491,7 @@ module Samagotchi
|
|
|
1483
1491
|
|
|
1484
1492
|
norm_role = role == "model" ? "assistant" : role
|
|
1485
1493
|
# normalize assistant vs model, keep user as is
|
|
1486
|
-
norm_role = "assistant" if
|
|
1494
|
+
norm_role = "assistant" if %w[assistant model].include?(norm_role)
|
|
1487
1495
|
norm_role = "user" if norm_role == "user"
|
|
1488
1496
|
next unless %w[user assistant].include?(norm_role)
|
|
1489
1497
|
|
|
@@ -1644,7 +1652,6 @@ module Samagotchi
|
|
|
1644
1652
|
json_response(status, { error: code, detail: detail })
|
|
1645
1653
|
end
|
|
1646
1654
|
|
|
1647
|
-
|
|
1648
1655
|
def not_found(path:)
|
|
1649
1656
|
error_response(404, "not_found", "not found: #{path}")
|
|
1650
1657
|
end
|
|
@@ -1740,12 +1747,12 @@ module Samagotchi
|
|
|
1740
1747
|
@server_running = server_running
|
|
1741
1748
|
end
|
|
1742
1749
|
|
|
1743
|
-
def each(&
|
|
1750
|
+
def each(&)
|
|
1744
1751
|
# Forward the browser's auto-reconnect cursor: the bridge prefers the
|
|
1745
1752
|
# Last-Event-ID header over ?from_seq, and the reconnect URL carries a
|
|
1746
1753
|
# stale initial cursor — without this the bridge would replay content
|
|
1747
1754
|
# already delivered (duplicate bubbles).
|
|
1748
|
-
@client.stream(query: @query, last_event_id: @headers["HTTP_LAST_EVENT_ID"], running: @server_running, &
|
|
1755
|
+
@client.stream(query: @query, last_event_id: @headers["HTTP_LAST_EVENT_ID"], running: @server_running, &)
|
|
1749
1756
|
end
|
|
1750
1757
|
end
|
|
1751
1758
|
end
|
|
@@ -34,7 +34,7 @@ module Samagotchi
|
|
|
34
34
|
|
|
35
35
|
html = Commonmarker.to_html(markdown.to_s, options: {
|
|
36
36
|
render: { escape: true }, # escape raw HTML from source; highlighter output is still emitted
|
|
37
|
-
extension: { header_ids: nil }
|
|
37
|
+
extension: { header_ids: nil }
|
|
38
38
|
})
|
|
39
39
|
return nil unless html
|
|
40
40
|
|
|
@@ -71,6 +71,7 @@ module Samagotchi
|
|
|
71
71
|
def sanitize_attributes(node)
|
|
72
72
|
node.attribute_nodes.each do |attribute|
|
|
73
73
|
next if allowed_attribute?(node, attribute.name)
|
|
74
|
+
|
|
74
75
|
node.remove_attribute(attribute.name)
|
|
75
76
|
end
|
|
76
77
|
return unless node.name == "a"
|
data/lib/samagotchi/web/qr.rb
CHANGED
|
@@ -21,7 +21,13 @@ module Samagotchi
|
|
|
21
21
|
rows = matrix(text, quiet: quiet)
|
|
22
22
|
rows << Array.new(rows.first.size, false) if rows.size.odd?
|
|
23
23
|
rows.each_slice(2).map do |top, bottom|
|
|
24
|
-
line = top.zip(bottom).map
|
|
24
|
+
line = top.zip(bottom).map do |t, b|
|
|
25
|
+
if t
|
|
26
|
+
b ? "█" : "▀"
|
|
27
|
+
else
|
|
28
|
+
(b ? "▄" : " ")
|
|
29
|
+
end
|
|
30
|
+
end.join
|
|
25
31
|
color ? "#{COLORS}#{line}#{RESET}" : line
|
|
26
32
|
end
|
|
27
33
|
end
|
|
@@ -94,8 +94,12 @@ module Samagotchi
|
|
|
94
94
|
puts lan_off_line(setting)
|
|
95
95
|
return 0
|
|
96
96
|
end
|
|
97
|
-
start(port: port, host: host, url: url, open_browser: open_browser, markdown: markdown, view: view,
|
|
98
|
-
|
|
97
|
+
if start(port: port, host: host, url: url, open_browser: open_browser, markdown: markdown, view: view,
|
|
98
|
+
annotate_presets: annotate_presets, lan: lan)
|
|
99
|
+
0
|
|
100
|
+
else
|
|
101
|
+
1
|
|
102
|
+
end
|
|
99
103
|
end
|
|
100
104
|
rescue Lan::Error => e
|
|
101
105
|
warn "Error: #{e.message}"
|
data/lib/samagotchi/worker.rb
CHANGED
|
@@ -166,6 +166,7 @@ module Samagotchi
|
|
|
166
166
|
# A session stopped before this worker took the lock (e.g. a stop
|
|
167
167
|
# right after create) must not run its initial prompt.
|
|
168
168
|
return :stopped if stopped_on_disk?
|
|
169
|
+
|
|
169
170
|
# Plugins' slow setup (chi.init: an MCP server's first start), in
|
|
170
171
|
# the background, shown by the UIs; a turn waits only for the ones
|
|
171
172
|
# that bring tools.
|
|
@@ -483,15 +484,22 @@ module Samagotchi
|
|
|
483
484
|
# queued while it ran are refused, then the caller's block takes the
|
|
484
485
|
# result (or the error the Engine announced as :turn_failed), the
|
|
485
486
|
# answer goes to the output file and the session is saved.
|
|
487
|
+
# A failure before the Engine's turn began (this save, say) goes to the
|
|
488
|
+
# block too, with no :turn_failed: it is logged, the session idle again.
|
|
486
489
|
# @yieldparam result [Object, nil] Engine#run_turn's, nil on a failure
|
|
487
490
|
# @yieldparam error [StandardError, nil]
|
|
488
491
|
def run_engine_turn(prompt, **turn_args)
|
|
489
|
-
@session.status = Session::STATUS_RUNNING
|
|
490
|
-
@session.save(state_dir: @state_dir)
|
|
491
492
|
begin
|
|
493
|
+
@session.status = Session::STATUS_RUNNING
|
|
494
|
+
@session.save(state_dir: @state_dir)
|
|
492
495
|
result = @engine.run_turn(@session, prompt, pending_input: pending_input_drain, **turn_args)
|
|
493
496
|
rescue StandardError => e
|
|
494
497
|
error = e
|
|
498
|
+
# Still running: no turn of the Engine's ended (it never began).
|
|
499
|
+
if @session.status == Session::STATUS_RUNNING
|
|
500
|
+
@session.status = Session::STATUS_IDLE
|
|
501
|
+
Log.warn(:worker, "turn_not_begun", error: e.class.name, msg: e.message)
|
|
502
|
+
end
|
|
495
503
|
ensure
|
|
496
504
|
refuse_queued_commands
|
|
497
505
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: samagotchi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.23.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dmitry Dedov
|
|
@@ -9,20 +9,6 @@ bindir: bin
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
-
- !ruby/object:Gem::Dependency
|
|
13
|
-
name: reline
|
|
14
|
-
requirement: !ruby/object:Gem::Requirement
|
|
15
|
-
requirements:
|
|
16
|
-
- - "~>"
|
|
17
|
-
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.6.3
|
|
19
|
-
type: :runtime
|
|
20
|
-
prerelease: false
|
|
21
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
-
requirements:
|
|
23
|
-
- - "~>"
|
|
24
|
-
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.6.3
|
|
26
12
|
- !ruby/object:Gem::Dependency
|
|
27
13
|
name: json
|
|
28
14
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -80,19 +66,19 @@ dependencies:
|
|
|
80
66
|
- !ruby/object:Gem::Version
|
|
81
67
|
version: '0'
|
|
82
68
|
- !ruby/object:Gem::Dependency
|
|
83
|
-
name:
|
|
69
|
+
name: reline
|
|
84
70
|
requirement: !ruby/object:Gem::Requirement
|
|
85
71
|
requirements:
|
|
86
|
-
- - "
|
|
72
|
+
- - "~>"
|
|
87
73
|
- !ruby/object:Gem::Version
|
|
88
|
-
version:
|
|
74
|
+
version: 0.6.3
|
|
89
75
|
type: :runtime
|
|
90
76
|
prerelease: false
|
|
91
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
92
78
|
requirements:
|
|
93
|
-
- - "
|
|
79
|
+
- - "~>"
|
|
94
80
|
- !ruby/object:Gem::Version
|
|
95
|
-
version:
|
|
81
|
+
version: 0.6.3
|
|
96
82
|
- !ruby/object:Gem::Dependency
|
|
97
83
|
name: rqrcode_core
|
|
98
84
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -107,6 +93,20 @@ dependencies:
|
|
|
107
93
|
- - "~>"
|
|
108
94
|
- !ruby/object:Gem::Version
|
|
109
95
|
version: '2.0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: webrick
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0'
|
|
103
|
+
type: :runtime
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
110
110
|
description: chi is an agent harness for local and OpenAI-compatible models (llama.cpp,
|
|
111
111
|
mlx, oMLX, hosted APIs). It runs sessions in a terminal REPL or in background workers
|
|
112
112
|
you can attach to from the terminal and a web UI, keeps memories in plain files
|