samagotchi 0.65.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 (155) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +107 -1
  3. data/README.md +2 -1
  4. data/bin/chi +51 -2
  5. data/docs/architecture.md +50 -28
  6. data/docs/cli.md +14 -2
  7. data/docs/configuration.md +101 -16
  8. data/docs/context.md +39 -2
  9. data/docs/desktop.md +90 -22
  10. data/docs/guardrails.md +8 -5
  11. data/docs/hooks.md +2 -2
  12. data/docs/internals/anthropic.md +156 -0
  13. data/docs/internals/background-tasks.md +1 -1
  14. data/docs/internals/bundles.md +2 -0
  15. data/docs/internals/engine.md +75 -30
  16. data/docs/internals/gemma4-contract.md +1 -1
  17. data/docs/internals/llm-context-bench.md +5 -4
  18. data/docs/internals/prompt-caching.md +36 -13
  19. data/docs/memory.md +1 -1
  20. data/docs/plugins.md +289 -25
  21. data/docs/releasing.md +1 -1
  22. data/docs/sessions.md +16 -6
  23. data/docs/sub-agent.md +6 -1
  24. data/docs/testing.md +17 -3
  25. data/lib/samagotchi/bootstrap/probe.rb +4 -3
  26. data/lib/samagotchi/bootstrap_command.rb +13 -3
  27. data/lib/samagotchi/bridge/ring_buffer.rb +0 -5
  28. data/lib/samagotchi/bridge.rb +6 -3
  29. data/lib/samagotchi/bundles/claude-peer/manifest.yml +7 -6
  30. data/lib/samagotchi/bundles/claude-peer/plugin.rb +40 -302
  31. data/lib/samagotchi/bundles/claude-peer/scripts/chi-peer-SKILL.md +8 -3
  32. data/lib/samagotchi/bundles/claude-peer/skill_claude_peer.md +14 -6
  33. data/lib/samagotchi/bundles/codex-peer/manifest.yml +22 -0
  34. data/lib/samagotchi/bundles/codex-peer/plugin.rb +189 -0
  35. data/lib/samagotchi/bundles/codex-peer/scripts/chi-peer-SKILL.md +136 -0
  36. data/lib/samagotchi/bundles/codex-peer/scripts/pair +92 -0
  37. data/lib/samagotchi/bundles/codex-peer/skill_codex_peer.md +76 -0
  38. data/lib/samagotchi/bundles/coordinator/manifest.yml +5 -5
  39. data/lib/samagotchi/bundles/coordinator/plugin.rb +24 -2
  40. data/lib/samagotchi/bundles/dev/manifest.yml +2 -1
  41. data/lib/samagotchi/bundles/mcp/manifest.yml +5 -5
  42. data/lib/samagotchi/bundles/mcp/plugin.rb +82 -294
  43. data/lib/samagotchi/bundles/system/config_modification_protocol.md +7 -3
  44. data/lib/samagotchi/bundles/system/delegated.md +2 -1
  45. data/lib/samagotchi/bundles/system/manifest.yml +5 -5
  46. data/lib/samagotchi/bundles/system/memory_guide.md +1 -1
  47. data/lib/samagotchi/bundles/system/self_map.md +1 -1
  48. data/lib/samagotchi/cache_confirm.rb +9 -6
  49. data/lib/samagotchi/commands/registry.rb +25 -8
  50. data/lib/samagotchi/config.rb +23 -8
  51. data/lib/samagotchi/context_absorber.rb +66 -13
  52. data/lib/samagotchi/desktop/macos/AgentTerminal.swift +260 -0
  53. data/lib/samagotchi/desktop/macos/App.swift +3 -3
  54. data/lib/samagotchi/desktop/macos/ChiRunner.swift +5 -2
  55. data/lib/samagotchi/desktop/macos/Images.swift +2 -2
  56. data/lib/samagotchi/desktop/macos/Kitty.swift +33 -197
  57. data/lib/samagotchi/desktop/macos/Panel.swift +118 -82
  58. data/lib/samagotchi/desktop/macos/ProcessRunner.swift +1 -1
  59. data/lib/samagotchi/desktop/macos/Tmux.swift +239 -0
  60. data/lib/samagotchi/desktop/macos.rb +84 -13
  61. data/lib/samagotchi/desktop_command.rb +14 -3
  62. data/lib/samagotchi/engine.rb +120 -107
  63. data/lib/samagotchi/engine_peers.rb +3 -0
  64. data/lib/samagotchi/guardrail_wiring.rb +1 -1
  65. data/lib/samagotchi/guardrails/approval.rb +1 -1
  66. data/lib/samagotchi/guardrails/approvals.rb +1 -1
  67. data/lib/samagotchi/guardrails/rules.rb +1 -1
  68. data/lib/samagotchi/guardrails/targets.rb +1 -1
  69. data/lib/samagotchi/hook_routes.rb +151 -0
  70. data/lib/samagotchi/hooks/registry.rb +2 -2
  71. data/lib/samagotchi/host_keys.rb +147 -0
  72. data/lib/samagotchi/kernel_loop.rb +9 -1
  73. data/lib/samagotchi/llm/adapter_common.rb +138 -0
  74. data/lib/samagotchi/llm/anthropic_assembly.rb +4 -2
  75. data/lib/samagotchi/llm/anthropic_messages.rb +28 -105
  76. data/lib/samagotchi/llm/api_key.rb +23 -7
  77. data/lib/samagotchi/llm/chat_loop.rb +10 -6
  78. data/lib/samagotchi/llm/openai_chat.rb +9 -92
  79. data/lib/samagotchi/llm/refusal_memo.rb +29 -0
  80. data/lib/samagotchi/llm_context_override.rb +1 -0
  81. data/lib/samagotchi/peer_sources.rb +58 -0
  82. data/lib/samagotchi/plugin/api.rb +138 -156
  83. data/lib/samagotchi/plugin/context.rb +22 -1
  84. data/lib/samagotchi/plugin/loader.rb +5 -2
  85. data/lib/samagotchi/plugin/peer.rb +394 -0
  86. data/lib/samagotchi/plugin/tool_spec.rb +166 -0
  87. data/lib/samagotchi/plugin_tasks.rb +2 -2
  88. data/lib/samagotchi/row_refs.rb +1 -1
  89. data/lib/samagotchi/self_report.rb +5 -3
  90. data/lib/samagotchi/send_command.rb +41 -15
  91. data/lib/samagotchi/session.rb +18 -1
  92. data/lib/samagotchi/session_commands.rb +16 -1
  93. data/lib/samagotchi/session_continue.rb +58 -15
  94. data/lib/samagotchi/session_inbox.rb +0 -13
  95. data/lib/samagotchi/session_manager.rb +4 -1
  96. data/lib/samagotchi/session_setup.rb +14 -7
  97. data/lib/samagotchi/system_prompt.rb +16 -1
  98. data/lib/samagotchi/terminal_ui/attach_launcher.rb +19 -9
  99. data/lib/samagotchi/terminal_ui.rb +18 -2
  100. data/lib/samagotchi/tool_call_parser.rb +1 -1
  101. data/lib/samagotchi/tool_runner.rb +13 -1
  102. data/lib/samagotchi/toolkit.rb +246 -0
  103. data/lib/samagotchi/toolkit_binding.rb +138 -0
  104. data/lib/samagotchi/toolkit_command.rb +117 -0
  105. data/lib/samagotchi/tools/context_read.rb +14 -0
  106. data/lib/samagotchi/tools/execute.rb +12 -12
  107. data/lib/samagotchi/tools/registry.rb +43 -6
  108. data/lib/samagotchi/tools/task_create.rb +6 -6
  109. data/lib/samagotchi/tools/task_get.rb +13 -13
  110. data/lib/samagotchi/tools/task_list.rb +6 -6
  111. data/lib/samagotchi/tools/task_record.rb +52 -0
  112. data/lib/samagotchi/tools/task_runtime.rb +55 -91
  113. data/lib/samagotchi/tools/task_stop.rb +6 -6
  114. data/lib/samagotchi/tools/task_wait.rb +12 -13
  115. data/lib/samagotchi/tools/tool_index.rb +454 -0
  116. data/lib/samagotchi/update_command.rb +9 -6
  117. data/lib/samagotchi/version.rb +1 -1
  118. data/lib/samagotchi/web/app.rb +28 -9
  119. data/lib/samagotchi/web/capabilities.rb +1 -1
  120. data/lib/samagotchi/web/public/activity.js +2 -2
  121. data/lib/samagotchi/web/public/annotate_actions.js +109 -0
  122. data/lib/samagotchi/web/public/annotate_bar.js +84 -2
  123. data/lib/samagotchi/web/public/app.js +52 -43
  124. data/lib/samagotchi/web/public/chains.js +1 -1
  125. data/lib/samagotchi/web/public/commands.js +6 -4
  126. data/lib/samagotchi/web/public/composer_size.js +2 -2
  127. data/lib/samagotchi/web/public/copy.js +1 -1
  128. data/lib/samagotchi/web/public/ctx.js +1 -1
  129. data/lib/samagotchi/web/public/delivery_line.js +4 -4
  130. data/lib/samagotchi/web/public/families_view.js +1 -1
  131. data/lib/samagotchi/web/public/format.js +11 -7
  132. data/lib/samagotchi/web/public/images.js +25 -2
  133. data/lib/samagotchi/web/public/index.html +9 -0
  134. data/lib/samagotchi/web/public/info_bar.js +5 -3
  135. data/lib/samagotchi/web/public/llm_context_chip.js +2 -2
  136. data/lib/samagotchi/web/public/notify.js +6 -4
  137. data/lib/samagotchi/web/public/question_card.js +1 -1
  138. data/lib/samagotchi/web/public/ref_scan.js +1 -1
  139. data/lib/samagotchi/web/public/session_state.js +17 -0
  140. data/lib/samagotchi/web/public/session_title.js +2 -3
  141. data/lib/samagotchi/web/public/sessions_list.js +0 -8
  142. data/lib/samagotchi/web/public/stage_model.js +2 -2
  143. data/lib/samagotchi/web/public/stream_handlers.js +13 -0
  144. data/lib/samagotchi/web/public/strip.js +3 -3
  145. data/lib/samagotchi/web/public/task_stop.js +3 -2
  146. data/lib/samagotchi/web/public/toolkit_chip.js +29 -0
  147. data/lib/samagotchi/web/public/turn_events.js +1 -1
  148. data/lib/samagotchi/web/public/turn_html.js +2 -2
  149. data/lib/samagotchi/web/public/turn_model.js +2 -2
  150. data/lib/samagotchi/web/public/turn_view.js +1 -1
  151. data/lib/samagotchi/web/server.rb +0 -4
  152. data/lib/samagotchi/worker.rb +13 -8
  153. data/lib/samagotchi/worker_inbound.rb +36 -4
  154. data/lib/samagotchi/worker_wakes.rb +67 -7
  155. metadata +23 -1
@@ -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.65.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
@@ -190,6 +191,11 @@ files:
190
191
  - lib/samagotchi/bundles/claude-peer/scripts/chi-peer-SKILL.md
191
192
  - lib/samagotchi/bundles/claude-peer/scripts/pair
192
193
  - lib/samagotchi/bundles/claude-peer/skill_claude_peer.md
194
+ - lib/samagotchi/bundles/codex-peer/manifest.yml
195
+ - lib/samagotchi/bundles/codex-peer/plugin.rb
196
+ - lib/samagotchi/bundles/codex-peer/scripts/chi-peer-SKILL.md
197
+ - lib/samagotchi/bundles/codex-peer/scripts/pair
198
+ - lib/samagotchi/bundles/codex-peer/skill_codex_peer.md
193
199
  - lib/samagotchi/bundles/coordinator/manifest.yml
194
200
  - lib/samagotchi/bundles/coordinator/plugin.rb
195
201
  - lib/samagotchi/bundles/coordinator/skill_coordinator.md
@@ -255,6 +261,7 @@ files:
255
261
  - lib/samagotchi/delivery.rb
256
262
  - lib/samagotchi/desktop.rb
257
263
  - lib/samagotchi/desktop/macos.rb
264
+ - lib/samagotchi/desktop/macos/AgentTerminal.swift
258
265
  - lib/samagotchi/desktop/macos/App.swift
259
266
  - lib/samagotchi/desktop/macos/Broadcast.swift
260
267
  - lib/samagotchi/desktop/macos/ChiRunner.swift
@@ -265,6 +272,7 @@ files:
265
272
  - lib/samagotchi/desktop/macos/Models.swift
266
273
  - lib/samagotchi/desktop/macos/Panel.swift
267
274
  - lib/samagotchi/desktop/macos/ProcessRunner.swift
275
+ - lib/samagotchi/desktop/macos/Tmux.swift
268
276
  - lib/samagotchi/desktop_command.rb
269
277
  - lib/samagotchi/edit_preview.rb
270
278
  - lib/samagotchi/empty_answer_retry.rb
@@ -299,12 +307,14 @@ files:
299
307
  - lib/samagotchi/guardrails/shell_paths.rb
300
308
  - lib/samagotchi/guardrails/targets.rb
301
309
  - lib/samagotchi/guardrails/verdict.rb
310
+ - lib/samagotchi/hook_routes.rb
302
311
  - lib/samagotchi/hooks.rb
303
312
  - lib/samagotchi/hooks/bundle_loader.rb
304
313
  - lib/samagotchi/hooks/loader.rb
305
314
  - lib/samagotchi/hooks/registry.rb
306
315
  - lib/samagotchi/hooks/stream_watch.rb
307
316
  - lib/samagotchi/host_config.rb
317
+ - lib/samagotchi/host_keys.rb
308
318
  - lib/samagotchi/host_model.rb
309
319
  - lib/samagotchi/host_registry.rb
310
320
  - lib/samagotchi/idle_client.rb
@@ -321,6 +331,7 @@ files:
321
331
  - lib/samagotchi/last_turn.rb
322
332
  - lib/samagotchi/launch_mode.rb
323
333
  - lib/samagotchi/live_versions.rb
334
+ - lib/samagotchi/llm/adapter_common.rb
324
335
  - lib/samagotchi/llm/adapters.rb
325
336
  - lib/samagotchi/llm/anthropic_assembly.rb
326
337
  - lib/samagotchi/llm/anthropic_messages.rb
@@ -337,6 +348,7 @@ files:
337
348
  - lib/samagotchi/llm/native_tool_normalizer.rb
338
349
  - lib/samagotchi/llm/openai_chat.rb
339
350
  - lib/samagotchi/llm/prompt_cache.rb
351
+ - lib/samagotchi/llm/refusal_memo.rb
340
352
  - lib/samagotchi/llm/stream_drops.rb
341
353
  - lib/samagotchi/llm/turn_settings.rb
342
354
  - lib/samagotchi/llm/usage.rb
@@ -394,15 +406,18 @@ files:
394
406
  - lib/samagotchi/owner_lock.rb
395
407
  - lib/samagotchi/parent_report.rb
396
408
  - lib/samagotchi/paths.rb
409
+ - lib/samagotchi/peer_sources.rb
397
410
  - lib/samagotchi/pending_input_queue.rb
398
411
  - lib/samagotchi/plugin/api.rb
399
412
  - lib/samagotchi/plugin/attached_context.rb
400
413
  - lib/samagotchi/plugin/context.rb
401
414
  - lib/samagotchi/plugin/loader.rb
415
+ - lib/samagotchi/plugin/peer.rb
402
416
  - lib/samagotchi/plugin/service.rb
403
417
  - lib/samagotchi/plugin/sessions.rb
404
418
  - lib/samagotchi/plugin/side_question.rb
405
419
  - lib/samagotchi/plugin/tool_result.rb
420
+ - lib/samagotchi/plugin/tool_spec.rb
406
421
  - lib/samagotchi/plugin_session_state.rb
407
422
  - lib/samagotchi/plugin_tasks.rb
408
423
  - lib/samagotchi/process_group.rb
@@ -489,6 +504,9 @@ files:
489
504
  - lib/samagotchi/tool_row_fields.rb
490
505
  - lib/samagotchi/tool_runner.rb
491
506
  - lib/samagotchi/tool_view.rb
507
+ - lib/samagotchi/toolkit.rb
508
+ - lib/samagotchi/toolkit_binding.rb
509
+ - lib/samagotchi/toolkit_command.rb
492
510
  - lib/samagotchi/tools/args.rb
493
511
  - lib/samagotchi/tools/ask_user_question.rb
494
512
  - lib/samagotchi/tools/builtin_calls.rb
@@ -516,9 +534,11 @@ files:
516
534
  - lib/samagotchi/tools/task_create.rb
517
535
  - lib/samagotchi/tools/task_get.rb
518
536
  - lib/samagotchi/tools/task_list.rb
537
+ - lib/samagotchi/tools/task_record.rb
519
538
  - lib/samagotchi/tools/task_runtime.rb
520
539
  - lib/samagotchi/tools/task_stop.rb
521
540
  - lib/samagotchi/tools/task_wait.rb
541
+ - lib/samagotchi/tools/tool_index.rb
522
542
  - lib/samagotchi/tools/tool_path.rb
523
543
  - lib/samagotchi/tools/web_fetch.rb
524
544
  - lib/samagotchi/tools/write.rb
@@ -543,6 +563,7 @@ files:
543
563
  - lib/samagotchi/web/markdown_renderer.rb
544
564
  - lib/samagotchi/web/message_parts.rb
545
565
  - lib/samagotchi/web/public/activity.js
566
+ - lib/samagotchi/web/public/annotate_actions.js
546
567
  - lib/samagotchi/web/public/annotate_bar.js
547
568
  - lib/samagotchi/web/public/annotate_presets.js
548
569
  - lib/samagotchi/web/public/annotations.js
@@ -608,6 +629,7 @@ files:
608
629
  - lib/samagotchi/web/public/thinking_chip.js
609
630
  - lib/samagotchi/web/public/thinking_ticker.js
610
631
  - lib/samagotchi/web/public/timing.js
632
+ - lib/samagotchi/web/public/toolkit_chip.js
611
633
  - lib/samagotchi/web/public/turn_events.js
612
634
  - lib/samagotchi/web/public/turn_html.js
613
635
  - lib/samagotchi/web/public/turn_model.js