samagotchi 0.37.0 → 0.38.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.
@@ -4,9 +4,9 @@ module Samagotchi
4
4
  # A tool batch and the conversation entries its results become, for both
5
5
  # loops. The calls run through ToolRunner between the dispatch events;
6
6
  # what the model gets back is per format: the native loop answers a batch
7
- # with ONE tool_response (#joined: the full outputs), the chat loop each
8
- # call with its own, paired by tool_call_id (#single: the capped output,
9
- # D-P2-6).
7
+ # with ONE tool_response (#joined), the chat loop each call with its own,
8
+ # paired by tool_call_id (#single). Both feed the capped outputs
9
+ # (max_tool_output_chars).
10
10
  module ToolResponse
11
11
  SEPARATOR = "\n\n---\n\n"
12
12
  # Saved with a result for the web's reload (a plugin tool's params line
@@ -37,12 +37,12 @@ module Samagotchi
37
37
  runs.filter_map { |run| run[:activity] }
38
38
  end
39
39
 
40
- # The native loop's entry for a batch: the outputs joined, every image
40
+ # The native loop's entry for a batch: the capped outputs joined, every image
41
41
  # in call order with how many each call returned (the web's reload puts
42
42
  # each on its own tool row), and the saved-only fields one per call.
43
43
  def joined(runs)
44
44
  images = runs.flat_map { |run| Array(run[:images]) }
45
- entry = { role: "tool_response", content: runs.map { |run| run[:output] }.join(SEPARATOR) }
45
+ entry = { role: "tool_response", content: runs.map { |run| run[:capped_output] }.join(SEPARATOR) }
46
46
  unless images.empty?
47
47
  entry[:images] = images
48
48
  entry[:image_counts] = runs.map { |run| Array(run[:images]).size }
@@ -13,9 +13,9 @@ module Samagotchi
13
13
  # The single per-call path both loops use: the tool_call_started and
14
14
  # tool_call_completed events, the guardrail gate (before_tool_call hooks
15
15
  # and their veto), dispatch through KernelLoop, the after_tool_call hook
16
- # and the output cap. Each loop picks what the model gets back: native
17
- # feeds the full `output:`, the chat loop feeds `capped_output:` (the cap
18
- # on the event applies to both).
16
+ # and the output cap. Both loops feed the model `capped_output:` (cut to
17
+ # the cap with a "[cut: N of M chars …]" line), the text the event and
18
+ # the hook get too.
19
19
  class ToolRunner
20
20
  # More images in one result are left out, each with a line (a tool
21
21
  # that returns many screenshots can't flood the context).
@@ -83,12 +83,8 @@ module Samagotchi
83
83
  if (changed = changed_call_line(original, call))
84
84
  output = "#{changed}\n#{output}"
85
85
  end
86
- capped = output
87
- truncated = false
88
- if max_tool_output_chars && output.length > max_tool_output_chars
89
- truncated = true
90
- capped = output[0, max_tool_output_chars]
91
- end
86
+ truncated = !max_tool_output_chars.nil? && output.length > max_tool_output_chars
87
+ capped = truncated ? cut(output, max_tool_output_chars) : output
92
88
 
93
89
  # The call's outcome as its activity line has it (worked out from the
94
90
  # full output: ok, error, blocked, stopped); a dispatcher that raised
@@ -118,6 +114,19 @@ module Samagotchi
118
114
 
119
115
  private
120
116
 
117
+ # +output+ cut to +cap+ chars, the cut line included: the model knows
118
+ # what it didn't get. A cap smaller than the line keeps +cap+ chars and
119
+ # the line goes past it.
120
+ def cut(output, cap)
121
+ keep = cap - cut_line(cap, output.length).length
122
+ keep = cap unless keep.positive?
123
+ "#{output[0, keep]}#{cut_line(keep, output.length)}"
124
+ end
125
+
126
+ def cut_line(kept, total)
127
+ "\n[cut: #{kept} of #{total} chars; read it in parts]"
128
+ end
129
+
121
130
  # edit/write only: the file just before the call runs. The row diffs it
122
131
  # with the file after, whatever the result says, so an edit that fails
123
132
  # after writing still shows its change and one that wrote nothing shows
@@ -80,7 +80,7 @@ module Samagotchi
80
80
  @stderr = stderr
81
81
  @gem_spec = gem_spec
82
82
  @shipped_dir = shipped_dir
83
- @platform = platform || ->(register:) { Desktop::MacOS.new(register: register, kitty: Desktop::MacOS.kitty_settings) }
83
+ @platform = platform || Desktop::MacOS.method(:from_config)
84
84
  @supported = supported
85
85
  @state_dir = state_dir
86
86
  @web = web || [Web::Lan.local_host(Config.get("web.host")), Config.get("web.port").to_i]
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Samagotchi
4
- VERSION = "0.37.0"
4
+ VERSION = "0.38.0"
5
5
  # Sent as the User-Agent of every HTTP request chi makes.
6
6
  USER_AGENT = "chi/#{VERSION}"
7
7
  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.37.0
4
+ version: 0.38.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Dedov
@@ -237,6 +237,7 @@ files:
237
237
  - lib/samagotchi/desktop.rb
238
238
  - lib/samagotchi/desktop/macos.rb
239
239
  - lib/samagotchi/desktop/macos/App.swift
240
+ - lib/samagotchi/desktop/macos/Broadcast.swift
240
241
  - lib/samagotchi/desktop/macos/ChiRunner.swift
241
242
  - lib/samagotchi/desktop/macos/Hotkey.swift
242
243
  - lib/samagotchi/desktop/macos/Images.swift