samagotchi 0.64.0 → 0.65.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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -1
  3. data/docs/architecture.md +20 -3
  4. data/docs/cli.md +25 -1
  5. data/docs/configuration.md +128 -3
  6. data/docs/internals/engine.md +15 -3
  7. data/docs/sessions.md +3 -2
  8. data/lib/samagotchi/bridge.rb +11 -1
  9. data/lib/samagotchi/bundles/system/config_modification_protocol.md +2 -2
  10. data/lib/samagotchi/bundles/system/manifest.yml +2 -2
  11. data/lib/samagotchi/client.rb +4 -2
  12. data/lib/samagotchi/config.rb +5 -4
  13. data/lib/samagotchi/engine.rb +39 -7
  14. data/lib/samagotchi/generation_phase.rb +17 -0
  15. data/lib/samagotchi/host_config.rb +27 -6
  16. data/lib/samagotchi/host_registry.rb +34 -11
  17. data/lib/samagotchi/idle_client.rb +62 -25
  18. data/lib/samagotchi/idle_recap.rb +5 -2
  19. data/lib/samagotchi/idle_target.rb +30 -7
  20. data/lib/samagotchi/llm/adapters.rb +41 -0
  21. data/lib/samagotchi/llm/anthropic_assembly.rb +210 -0
  22. data/lib/samagotchi/llm/anthropic_messages.rb +416 -0
  23. data/lib/samagotchi/llm/anthropic_wire.rb +238 -0
  24. data/lib/samagotchi/llm/api_key.rb +26 -9
  25. data/lib/samagotchi/llm/chat_loop.rb +113 -14
  26. data/lib/samagotchi/llm/dialect.rb +57 -0
  27. data/lib/samagotchi/llm/errors.rb +81 -12
  28. data/lib/samagotchi/llm/model_listing.rb +111 -0
  29. data/lib/samagotchi/llm/model_result.rb +9 -2
  30. data/lib/samagotchi/llm/openai_chat.rb +46 -93
  31. data/lib/samagotchi/model_profile.rb +1 -1
  32. data/lib/samagotchi/reasoning_history.rb +14 -4
  33. data/lib/samagotchi/recap_setup.rb +2 -1
  34. data/lib/samagotchi/self_report.rb +18 -28
  35. data/lib/samagotchi/session.rb +3 -2
  36. data/lib/samagotchi/session_metrics.rb +6 -11
  37. data/lib/samagotchi/steer_cut.rb +4 -0
  38. data/lib/samagotchi/terminal_ui/attached_loop.rb +8 -2
  39. data/lib/samagotchi/terminal_ui/event_renderer.rb +2 -1
  40. data/lib/samagotchi/terminal_ui/formatting.rb +4 -3
  41. data/lib/samagotchi/terminal_ui/status_row.rb +24 -3
  42. data/lib/samagotchi/turn_note.rb +22 -5
  43. data/lib/samagotchi/version.rb +1 -1
  44. data/lib/samagotchi/web/app.rb +2 -1
  45. data/lib/samagotchi/web/public/activity.js +3 -0
  46. data/lib/samagotchi/web/public/app.js +90 -13
  47. data/lib/samagotchi/web/public/delivery_line.js +228 -0
  48. data/lib/samagotchi/web/public/index.html +29 -0
  49. data/lib/samagotchi/web/public/live_turn.js +8 -0
  50. data/lib/samagotchi/web/public/stage_model.js +27 -7
  51. data/lib/samagotchi/web/public/stage_view.js +32 -10
  52. data/lib/samagotchi/web/public/stream_handlers.js +8 -2
  53. data/lib/samagotchi/web/public/turn_events.js +22 -8
  54. data/lib/samagotchi/web/public/turn_html.js +20 -4
  55. data/lib/samagotchi/web/public/turn_model.js +16 -9
  56. data/lib/samagotchi/web/public/turn_view.js +6 -4
  57. metadata +8 -1
@@ -7,7 +7,8 @@
7
7
  // Rules:
8
8
  // - turn_started opens the first gen (no iteration yet).
9
9
  // - generation_started(n) opens a new gen unless the current one is still
10
- // empty (then it takes n).
10
+ // empty (then it takes n); either way the gen's startedAt is the page's
11
+ // clock at it (null for a replay).
11
12
  // - a chunk goes to the gen of its iteration (opening one when none has it);
12
13
  // a chunk with no iteration goes to the current gen, unless that one is
13
14
  // textDone or already has tool rows (an older server's replay), which
@@ -45,7 +46,7 @@ function isEmpty(gen) {
45
46
 
46
47
  function openGen(turn, iteration) {
47
48
  const closed = closeCurrent(turn);
48
- const gen = { iteration: iteration ?? null, thinking: "", text: "", activity: newActivity(), textDone: false, closed: false, notices: [] };
49
+ const gen = { iteration: iteration ?? null, thinking: "", text: "", activity: newActivity(), textDone: false, closed: false, notices: [], startedAt: null, thinkingAt: null };
49
50
  gen.tools = gen.activity.rows;
50
51
  turn.gens.push(gen);
51
52
  return { gen, opened: true, closed };
@@ -81,16 +82,21 @@ export function turnStarted(turn) {
81
82
  return openGen(turn, null);
82
83
  }
83
84
 
84
- export function generationStarted(turn, iteration = null) {
85
+ // +now+ (ms): when the page saw the generation start, its startedAt (the
86
+ // composer's delivery line clocks the step from it); null for a replayed
87
+ // start (a join: the snapshot's generation age stands in).
88
+ export function generationStarted(turn, iteration = null, now = null) {
85
89
  const current = currentGen(turn);
86
- if (current && isEmpty(current)) {
87
- current.iteration = iteration ?? current.iteration;
88
- return { gen: current, opened: false, closed: null };
89
- }
90
- return openGen(turn, iteration);
90
+ const r = current && isEmpty(current) ? { gen: current, opened: false, closed: null } : openGen(turn, iteration);
91
+ if (!r.opened) r.gen.iteration = iteration ?? r.gen.iteration;
92
+ r.gen.startedAt = now;
93
+ return r;
91
94
  }
92
95
 
93
- export function chunk(turn, { text = "", thinking = "", iteration = null } = {}) {
96
+ // +now+ (ms): when the page got the chunk (null for a replay): a gen's
97
+ // first thinking delta stamps its thinkingAt, the clock the worker's cut
98
+ // counts from too (GenerationPhase).
99
+ export function chunk(turn, { text = "", thinking = "", iteration = null, now = null } = {}) {
94
100
  let r;
95
101
  if (iteration == null) {
96
102
  const current = currentGen(turn);
@@ -102,6 +108,7 @@ export function chunk(turn, { text = "", thinking = "", iteration = null } = {})
102
108
  // Leading whitespace (the "\n" after <think>, or after a closed
103
109
  // think/tool_call block) would render as an empty first line; trim it at
104
110
  // the start of a gen's thinking and text only.
111
+ if (thinking && !gen.thinking && now != null) gen.thinkingAt = now;
105
112
  if (thinking) gen.thinking += leadTrimmed(gen.thinking, thinking);
106
113
  if (text) gen.text += leadTrimmed(gen.text, text);
107
114
  return r;
@@ -700,14 +700,16 @@ export function createTurnView({
700
700
  draw(entry);
701
701
  }
702
702
  },
703
- generationStarted(data) {
703
+ // +now+: the page's clock at a live start (stream_handlers.js), null
704
+ // for a replayed one.
705
+ generationStarted(data, now = null) {
704
706
  if (!turn) this.turnStarted({});
705
- apply(model.generationStarted(turn, data.iteration ?? null));
707
+ apply(model.generationStarted(turn, data.iteration ?? null, now));
706
708
  },
707
- chunk({ text, thinking, iteration }) {
709
+ chunk({ text, thinking, iteration, now = null }) {
708
710
  if (!text && !thinking) return;
709
711
  if (!turn) this.turnStarted({});
710
- const r = model.chunk(turn, { text, thinking, iteration });
712
+ const r = model.chunk(turn, { text, thinking, iteration, now });
711
713
  apply(r);
712
714
  scheduleFlush(r.gen);
713
715
  },
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.64.0
4
+ version: 0.65.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Dedov
@@ -321,11 +321,17 @@ files:
321
321
  - lib/samagotchi/last_turn.rb
322
322
  - lib/samagotchi/launch_mode.rb
323
323
  - lib/samagotchi/live_versions.rb
324
+ - lib/samagotchi/llm/adapters.rb
325
+ - lib/samagotchi/llm/anthropic_assembly.rb
326
+ - lib/samagotchi/llm/anthropic_messages.rb
327
+ - lib/samagotchi/llm/anthropic_wire.rb
324
328
  - lib/samagotchi/llm/api_key.rb
325
329
  - lib/samagotchi/llm/backend.rb
326
330
  - lib/samagotchi/llm/chat_loop.rb
331
+ - lib/samagotchi/llm/dialect.rb
327
332
  - lib/samagotchi/llm/errors.rb
328
333
  - lib/samagotchi/llm/http.rb
334
+ - lib/samagotchi/llm/model_listing.rb
329
335
  - lib/samagotchi/llm/model_result.rb
330
336
  - lib/samagotchi/llm/native_backend.rb
331
337
  - lib/samagotchi/llm/native_tool_normalizer.rb
@@ -555,6 +561,7 @@ files:
555
561
  - lib/samagotchi/web/public/copy.js
556
562
  - lib/samagotchi/web/public/ctx.js
557
563
  - lib/samagotchi/web/public/data.js
564
+ - lib/samagotchi/web/public/delivery_line.js
558
565
  - lib/samagotchi/web/public/diff_view.js
559
566
  - lib/samagotchi/web/public/families_view.js
560
567
  - lib/samagotchi/web/public/favicon.svg