samagotchi 0.66.0 → 0.67.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.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +60 -1
  3. data/docs/architecture.md +50 -28
  4. data/docs/cli.md +3 -1
  5. data/docs/configuration.md +50 -9
  6. data/docs/context.md +35 -1
  7. data/docs/desktop.md +90 -22
  8. data/docs/guardrails.md +8 -5
  9. data/docs/hooks.md +2 -2
  10. data/docs/internals/anthropic.md +156 -0
  11. data/docs/internals/background-tasks.md +1 -1
  12. data/docs/internals/bundles.md +2 -0
  13. data/docs/internals/engine.md +71 -29
  14. data/docs/internals/gemma4-contract.md +1 -1
  15. data/docs/internals/llm-context-bench.md +5 -4
  16. data/docs/internals/prompt-caching.md +26 -11
  17. data/docs/plugins.md +126 -23
  18. data/docs/sessions.md +6 -6
  19. data/docs/sub-agent.md +4 -1
  20. data/docs/testing.md +17 -3
  21. data/lib/samagotchi/bootstrap/probe.rb +4 -3
  22. data/lib/samagotchi/bootstrap_command.rb +13 -3
  23. data/lib/samagotchi/bridge/ring_buffer.rb +0 -5
  24. data/lib/samagotchi/bridge.rb +6 -3
  25. data/lib/samagotchi/bundles/claude-peer/manifest.yml +7 -6
  26. data/lib/samagotchi/bundles/claude-peer/plugin.rb +34 -313
  27. data/lib/samagotchi/bundles/claude-peer/scripts/chi-peer-SKILL.md +8 -3
  28. data/lib/samagotchi/bundles/claude-peer/skill_claude_peer.md +14 -6
  29. data/lib/samagotchi/bundles/codex-peer/manifest.yml +7 -6
  30. data/lib/samagotchi/bundles/codex-peer/plugin.rb +37 -312
  31. data/lib/samagotchi/bundles/codex-peer/scripts/chi-peer-SKILL.md +8 -3
  32. data/lib/samagotchi/bundles/codex-peer/skill_codex_peer.md +14 -6
  33. data/lib/samagotchi/bundles/mcp/manifest.yml +5 -5
  34. data/lib/samagotchi/bundles/mcp/plugin.rb +82 -294
  35. data/lib/samagotchi/bundles/system/config_modification_protocol.md +7 -3
  36. data/lib/samagotchi/bundles/system/manifest.yml +3 -3
  37. data/lib/samagotchi/bundles/system/self_map.md +1 -1
  38. data/lib/samagotchi/config.rb +15 -7
  39. data/lib/samagotchi/context_absorber.rb +66 -13
  40. data/lib/samagotchi/desktop/macos/AgentTerminal.swift +260 -0
  41. data/lib/samagotchi/desktop/macos/App.swift +3 -3
  42. data/lib/samagotchi/desktop/macos/ChiRunner.swift +5 -2
  43. data/lib/samagotchi/desktop/macos/Images.swift +2 -2
  44. data/lib/samagotchi/desktop/macos/Kitty.swift +33 -197
  45. data/lib/samagotchi/desktop/macos/Panel.swift +118 -82
  46. data/lib/samagotchi/desktop/macos/ProcessRunner.swift +1 -1
  47. data/lib/samagotchi/desktop/macos/Tmux.swift +239 -0
  48. data/lib/samagotchi/desktop/macos.rb +84 -13
  49. data/lib/samagotchi/desktop_command.rb +14 -3
  50. data/lib/samagotchi/engine.rb +96 -191
  51. data/lib/samagotchi/engine_peers.rb +3 -0
  52. data/lib/samagotchi/guardrail_wiring.rb +1 -1
  53. data/lib/samagotchi/guardrails/approval.rb +1 -1
  54. data/lib/samagotchi/guardrails/approvals.rb +1 -1
  55. data/lib/samagotchi/guardrails/rules.rb +1 -1
  56. data/lib/samagotchi/guardrails/targets.rb +1 -1
  57. data/lib/samagotchi/hook_routes.rb +151 -0
  58. data/lib/samagotchi/hooks/registry.rb +2 -2
  59. data/lib/samagotchi/host_keys.rb +147 -0
  60. data/lib/samagotchi/llm/adapter_common.rb +138 -0
  61. data/lib/samagotchi/llm/anthropic_messages.rb +28 -105
  62. data/lib/samagotchi/llm/api_key.rb +23 -7
  63. data/lib/samagotchi/llm/chat_loop.rb +10 -6
  64. data/lib/samagotchi/llm/openai_chat.rb +9 -92
  65. data/lib/samagotchi/llm/refusal_memo.rb +29 -0
  66. data/lib/samagotchi/llm_context_override.rb +1 -0
  67. data/lib/samagotchi/peer_sources.rb +58 -0
  68. data/lib/samagotchi/plugin/api.rb +64 -155
  69. data/lib/samagotchi/plugin/loader.rb +4 -2
  70. data/lib/samagotchi/plugin/peer.rb +394 -0
  71. data/lib/samagotchi/plugin/tool_spec.rb +166 -0
  72. data/lib/samagotchi/plugin_tasks.rb +2 -2
  73. data/lib/samagotchi/row_refs.rb +1 -1
  74. data/lib/samagotchi/self_report.rb +5 -3
  75. data/lib/samagotchi/send_command.rb +21 -11
  76. data/lib/samagotchi/session_continue.rb +58 -15
  77. data/lib/samagotchi/session_inbox.rb +0 -13
  78. data/lib/samagotchi/tool_call_parser.rb +1 -1
  79. data/lib/samagotchi/toolkit_binding.rb +138 -0
  80. data/lib/samagotchi/tools/context_read.rb +14 -0
  81. data/lib/samagotchi/tools/execute.rb +12 -12
  82. data/lib/samagotchi/tools/registry.rb +1 -1
  83. data/lib/samagotchi/tools/task_create.rb +6 -6
  84. data/lib/samagotchi/tools/task_get.rb +13 -13
  85. data/lib/samagotchi/tools/task_list.rb +6 -6
  86. data/lib/samagotchi/tools/task_record.rb +52 -0
  87. data/lib/samagotchi/tools/task_runtime.rb +55 -91
  88. data/lib/samagotchi/tools/task_stop.rb +6 -6
  89. data/lib/samagotchi/tools/task_wait.rb +12 -13
  90. data/lib/samagotchi/tools/tool_index.rb +454 -0
  91. data/lib/samagotchi/update_command.rb +9 -6
  92. data/lib/samagotchi/version.rb +1 -1
  93. data/lib/samagotchi/web/app.rb +16 -9
  94. data/lib/samagotchi/web/capabilities.rb +1 -1
  95. data/lib/samagotchi/web/public/activity.js +2 -2
  96. data/lib/samagotchi/web/public/annotate_actions.js +1 -1
  97. data/lib/samagotchi/web/public/app.js +31 -36
  98. data/lib/samagotchi/web/public/chains.js +1 -1
  99. data/lib/samagotchi/web/public/commands.js +2 -2
  100. data/lib/samagotchi/web/public/composer_size.js +2 -2
  101. data/lib/samagotchi/web/public/copy.js +1 -1
  102. data/lib/samagotchi/web/public/ctx.js +1 -1
  103. data/lib/samagotchi/web/public/delivery_line.js +4 -4
  104. data/lib/samagotchi/web/public/families_view.js +1 -1
  105. data/lib/samagotchi/web/public/format.js +11 -7
  106. data/lib/samagotchi/web/public/images.js +25 -2
  107. data/lib/samagotchi/web/public/llm_context_chip.js +2 -2
  108. data/lib/samagotchi/web/public/notify.js +6 -4
  109. data/lib/samagotchi/web/public/question_card.js +1 -1
  110. data/lib/samagotchi/web/public/ref_scan.js +1 -1
  111. data/lib/samagotchi/web/public/session_state.js +14 -0
  112. data/lib/samagotchi/web/public/session_title.js +2 -3
  113. data/lib/samagotchi/web/public/sessions_list.js +0 -8
  114. data/lib/samagotchi/web/public/stage_model.js +2 -2
  115. data/lib/samagotchi/web/public/strip.js +3 -3
  116. data/lib/samagotchi/web/public/task_stop.js +3 -2
  117. data/lib/samagotchi/web/public/turn_events.js +1 -1
  118. data/lib/samagotchi/web/public/turn_html.js +2 -2
  119. data/lib/samagotchi/web/public/turn_model.js +2 -2
  120. data/lib/samagotchi/web/public/turn_view.js +1 -1
  121. data/lib/samagotchi/web/server.rb +0 -4
  122. data/lib/samagotchi/worker.rb +11 -8
  123. data/lib/samagotchi/worker_inbound.rb +36 -4
  124. data/lib/samagotchi/worker_wakes.rb +67 -7
  125. metadata +14 -1
@@ -218,7 +218,7 @@ module Samagotchi
218
218
  # The session, its Engine and what runs its turns, before anyone can
219
219
  # reach it.
220
220
  def start
221
- # The wake turns' budget (delegate reports, attached context), from now.
221
+ # The wake turns' budget (delegate reports, attached context, peers), from now.
222
222
  @wakes = WorkerWakes.new(grace: WAKE_START_GRACE)
223
223
  # This worker holds the session now (a continue's starting marker held
224
224
  # off any other until it did), and a continue that died moving
@@ -272,7 +272,8 @@ module Samagotchi
272
272
  predecessor: @session.continues)
273
273
  # Its attached context's notes (ContextSources).
274
274
  @context_absorber = ContextAbsorber.new(session_id: @session_id, state_dir: @state_dir,
275
- project_root: @session.project_root)
275
+ project_root: @session.project_root,
276
+ peer_sources: @engine.peer_sources, peer_turns: -> { @wakes.peer_turns })
276
277
  # What comes in between turns, and how each kind is saved.
277
278
  @inbound = WorkerInbound.new(session: @session, state_dir: @state_dir, session_dir: @session_dir, engine: @engine,
278
279
  context_absorber: @context_absorber, wakes: @wakes,
@@ -496,13 +497,14 @@ module Samagotchi
496
497
  # A turn nobody typed for a changed source (a context wake): a continue
497
498
  # turn from context:<name> whose first message is the wake note already
498
499
  # in the conversation (named by +turn_id+), on the same rules as a
499
- # delegate report's wake turn: it counts toward session.max_wakes, and
500
- # a failure goes back to before the turn (the note stays, as a plain
501
- # one: WorkerInbound#unmark_wake) and pauses wakes until a human's input.
500
+ # delegate report's wake turn: it counts toward session.max_wakes (a
501
+ # peer's answer toward context.peer_turns too), and a failure goes back
502
+ # to before the turn (the note stays, as a plain one:
503
+ # WorkerInbound#unmark_wake) and pauses wakes until a human's input.
502
504
  # +context_wake+: a WorkerInbound::ContextWake.
503
505
  def run_context_wake_turn(context_wake)
504
506
  name = context_wake.name
505
- Log.info(:worker, "context_wake_turn", name: name, in_a_row: @wakes.count!)
507
+ Log.info(:worker, "context_wake_turn", name: name, in_a_row: @wakes.count!(peer: context_wake.peer?))
506
508
  @turn_flow.before_prompt_turn
507
509
  run_engine_turn(nil, continue: true, origin: context_wake.origin,
508
510
  id: context_wake.turn_id, max_iterations: IterationLimit.for) do |result, error|
@@ -1220,12 +1222,13 @@ module Samagotchi
1220
1222
 
1221
1223
  # A human's input (ClientId.human?) un-archives the session;
1222
1224
  # a delegate's, a plugin's or a reminder's doesn't.
1223
- # It also resets the delegate-report wakes (budget and pause).
1225
+ # It also resets the wakes (budget and pause); input typed in the web or
1226
+ # a TUI the peer wakes too (chi send doesn't: a peer can run it).
1224
1227
  def user_input(client_id)
1225
1228
  return unless ClientId.human?(client_id)
1226
1229
 
1227
1230
  ArchiveStore.user_input(@session_id, state_dir: @state_dir)
1228
- @wakes.human_input!
1231
+ @wakes.human_input!(interactive: ClientId.interactive?(client_id))
1229
1232
  end
1230
1233
 
1231
1234
  def stopped_on_disk?
@@ -4,12 +4,14 @@ require "fileutils"
4
4
  require "securerandom"
5
5
  require "time"
6
6
 
7
+ require_relative "child_reports"
7
8
  require_relative "client_id"
8
9
  require_relative "config"
9
10
  require_relative "context_note"
10
11
  require_relative "log"
11
12
  require_relative "session"
12
13
  require_relative "session_inbox"
14
+ require_relative "worker_wakes"
13
15
 
14
16
  module Samagotchi
15
17
  # What comes into a worker's session between turns, each kind with its
@@ -43,6 +45,8 @@ module Samagotchi
43
45
  # the turn +turn_id+.
44
46
  ContextWake = Data.define(:delivery, :turn_id) do
45
47
  def name = delivery.name
48
+ # For a peer agent's answer (its own budget, WorkerWakes#peer_open?).
49
+ def peer? = !delivery.peer.nil?
46
50
  def origin = { client_id: "#{ClientId::CONTEXT_PREFIX}#{name}" }
47
51
  end
48
52
 
@@ -230,14 +234,42 @@ module Samagotchi
230
234
  # context.wake is on, the wake budget is open (WorkerWakes#context_open?:
231
235
  # no continue offer, not paused, under session.max_wakes, past the start
232
236
  # grace) and the source hasn't woken the session in the last
233
- # CONTEXT_WAKE_WINDOW. The others stay plain notes. Within the start
234
- # grace a change is a note: it came while the session was away.
237
+ # CONTEXT_WAKE_WINDOW; a peer's answer (Delivery#peer) has no window but
238
+ # the peer budget (WorkerWakes#peer_open?). The others stay plain notes.
239
+ # Within the start grace a change is a note: it came while the session
240
+ # was away. A peer's answer held by either budget is announced once.
235
241
  def context_wake_for(batch, now: Time.now)
236
242
  candidates = batch.deliveries.select(&:wake_note)
237
243
  return nil if candidates.empty? || !context_wakes_on?
238
- return nil unless @wakes.context_open?(awaiting_continue: @awaiting_continue.call, names: candidates.map(&:name))
239
244
 
240
- candidates.find { |delivery| !woke_lately?(delivery.subscription, now) }
245
+ unless @wakes.context_open?(awaiting_continue: @awaiting_continue.call, names: candidates.map(&:name))
246
+ peer_held(candidates.find(&:peer), ChildRing::MAX_WAKES_KEY) if @wakes.spent?
247
+ return nil
248
+ end
249
+
250
+ held = []
251
+ waking = candidates.select do |delivery|
252
+ next !woke_lately?(delivery.subscription, now) unless delivery.peer
253
+
254
+ next true if @wakes.peer_open?(name: delivery.name)
255
+
256
+ held << delivery
257
+ false
258
+ end
259
+ peer_held(held.first, WorkerWakes::PEER_TURNS_KEY)
260
+ waking.first
261
+ end
262
+
263
+ # A peer's answer waits as a note: the UIs hear it once per
264
+ # interactive input (WorkerWakes#notice_peer_budget!). +key+: the
265
+ # budget that holds it.
266
+ def peer_held(delivery, key)
267
+ return unless delivery && @wakes.notice_peer_budget!
268
+
269
+ turns = key == ChildRing::MAX_WAKES_KEY ? @wakes.max : @wakes.peer_turns
270
+ @engine.announce(type: :hook_notice, hook: "context", level: :info, between_turns: true,
271
+ text: "#{delivery.peer} answered again; it waits as a note for your next message " \
272
+ "(#{turns} wake turn#{"s" if turns != 1} in a row, #{key})")
241
273
  end
242
274
 
243
275
  def context_wakes_on? = Config.get("context.wake") != false
@@ -13,23 +13,36 @@ module Samagotchi
13
13
  # it what happened. It also holds the reports a delegate wake turn was
14
14
  # started for until the turn's first boundary takes them (#hand_over,
15
15
  # #take_handed).
16
+ #
17
+ # A peer agent's answers (PeerSources) have a budget of their own on top:
18
+ # context.peer_turns wake turns in a row, reset only by input typed in the
19
+ # web or a TUI (ClientId.interactive?), not by chi send, which a peer can
20
+ # run (docs/context.md, Waking).
16
21
  class WorkerWakes
22
+ PEER_TURNS_KEY = "context.peer_turns"
23
+ PEER_TURNS_DEFAULT = 3
24
+
17
25
  # @param grace [Numeric] seconds after the start with no wake turn
18
26
  # @param clock [#call] monotonic seconds
19
27
  # @param max [#call, nil] the budget; nil reads session.max_wakes
20
- def initialize(grace:, clock: -> { Process.clock_gettime(Process::CLOCK_MONOTONIC) }, max: nil)
28
+ # @param peer_max [#call, nil] the peer budget; nil reads context.peer_turns
29
+ def initialize(grace:, clock: -> { Process.clock_gettime(Process::CLOCK_MONOTONIC) }, max: nil, peer_max: nil)
21
30
  @grace = grace
22
31
  @clock = clock
23
32
  @max = max
33
+ @peer_max = peer_max
24
34
  @started_at = clock.call
25
35
  @in_a_row = 0
36
+ @peer_in_a_row = 0
26
37
  @paused = false
27
38
  @budget_noticed = false
39
+ @peer_noticed = false
28
40
  @handed = nil
29
41
  end
30
42
 
31
- # Wake turns run since the last human input.
32
- attr_reader :in_a_row
43
+ # Wake turns run since the last human input; peer wake turns since the
44
+ # last interactive one.
45
+ attr_reader :in_a_row, :peer_in_a_row
33
46
 
34
47
  def grace_left = @grace - (@clock.call - @started_at)
35
48
 
@@ -44,6 +57,35 @@ module Samagotchi
44
57
  ChildRing::MAX_WAKES_DEFAULT
45
58
  end
46
59
 
60
+ # context.peer_turns: 0 (or less) is 0, the peer policy off.
61
+ def peer_max
62
+ return @peer_max.call if @peer_max
63
+
64
+ value = Integer(Config.get(PEER_TURNS_KEY), exception: false)
65
+ value ? [value, 0].max : PEER_TURNS_DEFAULT
66
+ rescue StandardError
67
+ PEER_TURNS_DEFAULT
68
+ end
69
+
70
+ # The peer wake turns that may run in a row: context.peer_turns, or
71
+ # session.max_wakes when it is lower; 0 when the peer policy is off.
72
+ def peer_turns
73
+ peers = peer_max
74
+ peers.zero? ? 0 : [peers, max].min
75
+ end
76
+
77
+ # Whether session.max_wakes holds wake turns now.
78
+ def spent? = @in_a_row >= max
79
+
80
+ # Whether a peer's answer may start a wake turn by the peer budget
81
+ # (#context_open? asked first). +name+: the source, for the log line.
82
+ def peer_open?(name:)
83
+ return true if @peer_in_a_row < peer_turns
84
+
85
+ Log.info(:worker, "context_wake_held", reason: "peer_turns", names: name)
86
+ false
87
+ end
88
+
47
89
  # For delegate reports: :due when a wake turn may run now (the block
48
90
  # says reports wait; asked only when nothing else holds), :budget when
49
91
  # only the budget stops it, nil otherwise. The start grace is the
@@ -68,8 +110,12 @@ module Samagotchi
68
110
  true
69
111
  end
70
112
 
71
- # A wake turn starts. @return [Integer] the wake turns in a row now
72
- def count! = @in_a_row += 1
113
+ # A wake turn starts; +peer+: for a peer's answer, which counts toward
114
+ # both budgets. @return [Integer] the wake turns in a row now
115
+ def count!(peer: false)
116
+ @peer_in_a_row += 1 if peer
117
+ @in_a_row += 1
118
+ end
73
119
 
74
120
  # A wake turn failed (or was stopped before it got anywhere): none
75
121
  # starts again until a human's input.
@@ -77,11 +123,17 @@ module Samagotchi
77
123
  @paused = true
78
124
  end
79
125
 
80
- # A human's input resets the budget, the pause and the budget notice.
81
- def human_input!
126
+ # A human's input resets the budget, the pause and the budget notice;
127
+ # an +interactive+ one (ClientId.interactive?: the web, a TUI) the peer
128
+ # budget and its notice too. chi send isn't: a peer can run it.
129
+ def human_input!(interactive: true)
82
130
  @in_a_row = 0
83
131
  @paused = false
84
132
  @budget_noticed = false
133
+ return unless interactive
134
+
135
+ @peer_in_a_row = 0
136
+ @peer_noticed = false
85
137
  end
86
138
 
87
139
  # @return [Boolean] true the first time the budget is spent since the
@@ -92,6 +144,14 @@ module Samagotchi
92
144
  @budget_noticed = true
93
145
  end
94
146
 
147
+ # @return [Boolean] true the first time a peer's answer is held since
148
+ # the last interactive input: the UIs hear it once
149
+ def notice_peer_budget!
150
+ return false if @peer_noticed
151
+
152
+ @peer_noticed = true
153
+ end
154
+
95
155
  # The idle loop's sleep: +poll+, or less while a wake (the block says
96
156
  # one is due) waits out the start grace.
97
157
  def idle_wait(poll)
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.66.0
4
+ version: 0.67.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Dedov
@@ -130,6 +130,7 @@ files:
130
130
  - docs/desktop.md
131
131
  - docs/guardrails.md
132
132
  - docs/hooks.md
133
+ - docs/internals/anthropic.md
133
134
  - docs/internals/background-tasks.md
134
135
  - docs/internals/bundles.md
135
136
  - docs/internals/context-telemetry.md
@@ -260,6 +261,7 @@ files:
260
261
  - lib/samagotchi/delivery.rb
261
262
  - lib/samagotchi/desktop.rb
262
263
  - lib/samagotchi/desktop/macos.rb
264
+ - lib/samagotchi/desktop/macos/AgentTerminal.swift
263
265
  - lib/samagotchi/desktop/macos/App.swift
264
266
  - lib/samagotchi/desktop/macos/Broadcast.swift
265
267
  - lib/samagotchi/desktop/macos/ChiRunner.swift
@@ -270,6 +272,7 @@ files:
270
272
  - lib/samagotchi/desktop/macos/Models.swift
271
273
  - lib/samagotchi/desktop/macos/Panel.swift
272
274
  - lib/samagotchi/desktop/macos/ProcessRunner.swift
275
+ - lib/samagotchi/desktop/macos/Tmux.swift
273
276
  - lib/samagotchi/desktop_command.rb
274
277
  - lib/samagotchi/edit_preview.rb
275
278
  - lib/samagotchi/empty_answer_retry.rb
@@ -304,12 +307,14 @@ files:
304
307
  - lib/samagotchi/guardrails/shell_paths.rb
305
308
  - lib/samagotchi/guardrails/targets.rb
306
309
  - lib/samagotchi/guardrails/verdict.rb
310
+ - lib/samagotchi/hook_routes.rb
307
311
  - lib/samagotchi/hooks.rb
308
312
  - lib/samagotchi/hooks/bundle_loader.rb
309
313
  - lib/samagotchi/hooks/loader.rb
310
314
  - lib/samagotchi/hooks/registry.rb
311
315
  - lib/samagotchi/hooks/stream_watch.rb
312
316
  - lib/samagotchi/host_config.rb
317
+ - lib/samagotchi/host_keys.rb
313
318
  - lib/samagotchi/host_model.rb
314
319
  - lib/samagotchi/host_registry.rb
315
320
  - lib/samagotchi/idle_client.rb
@@ -326,6 +331,7 @@ files:
326
331
  - lib/samagotchi/last_turn.rb
327
332
  - lib/samagotchi/launch_mode.rb
328
333
  - lib/samagotchi/live_versions.rb
334
+ - lib/samagotchi/llm/adapter_common.rb
329
335
  - lib/samagotchi/llm/adapters.rb
330
336
  - lib/samagotchi/llm/anthropic_assembly.rb
331
337
  - lib/samagotchi/llm/anthropic_messages.rb
@@ -342,6 +348,7 @@ files:
342
348
  - lib/samagotchi/llm/native_tool_normalizer.rb
343
349
  - lib/samagotchi/llm/openai_chat.rb
344
350
  - lib/samagotchi/llm/prompt_cache.rb
351
+ - lib/samagotchi/llm/refusal_memo.rb
345
352
  - lib/samagotchi/llm/stream_drops.rb
346
353
  - lib/samagotchi/llm/turn_settings.rb
347
354
  - lib/samagotchi/llm/usage.rb
@@ -399,15 +406,18 @@ files:
399
406
  - lib/samagotchi/owner_lock.rb
400
407
  - lib/samagotchi/parent_report.rb
401
408
  - lib/samagotchi/paths.rb
409
+ - lib/samagotchi/peer_sources.rb
402
410
  - lib/samagotchi/pending_input_queue.rb
403
411
  - lib/samagotchi/plugin/api.rb
404
412
  - lib/samagotchi/plugin/attached_context.rb
405
413
  - lib/samagotchi/plugin/context.rb
406
414
  - lib/samagotchi/plugin/loader.rb
415
+ - lib/samagotchi/plugin/peer.rb
407
416
  - lib/samagotchi/plugin/service.rb
408
417
  - lib/samagotchi/plugin/sessions.rb
409
418
  - lib/samagotchi/plugin/side_question.rb
410
419
  - lib/samagotchi/plugin/tool_result.rb
420
+ - lib/samagotchi/plugin/tool_spec.rb
411
421
  - lib/samagotchi/plugin_session_state.rb
412
422
  - lib/samagotchi/plugin_tasks.rb
413
423
  - lib/samagotchi/process_group.rb
@@ -495,6 +505,7 @@ files:
495
505
  - lib/samagotchi/tool_runner.rb
496
506
  - lib/samagotchi/tool_view.rb
497
507
  - lib/samagotchi/toolkit.rb
508
+ - lib/samagotchi/toolkit_binding.rb
498
509
  - lib/samagotchi/toolkit_command.rb
499
510
  - lib/samagotchi/tools/args.rb
500
511
  - lib/samagotchi/tools/ask_user_question.rb
@@ -523,9 +534,11 @@ files:
523
534
  - lib/samagotchi/tools/task_create.rb
524
535
  - lib/samagotchi/tools/task_get.rb
525
536
  - lib/samagotchi/tools/task_list.rb
537
+ - lib/samagotchi/tools/task_record.rb
526
538
  - lib/samagotchi/tools/task_runtime.rb
527
539
  - lib/samagotchi/tools/task_stop.rb
528
540
  - lib/samagotchi/tools/task_wait.rb
541
+ - lib/samagotchi/tools/tool_index.rb
529
542
  - lib/samagotchi/tools/tool_path.rb
530
543
  - lib/samagotchi/tools/web_fetch.rb
531
544
  - lib/samagotchi/tools/write.rb