samagotchi 0.79.0 → 0.80.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 +30 -1
- data/README.md +7 -5
- data/docs/cli.md +24 -7
- data/docs/configuration.md +7 -4
- data/docs/internals/anthropic.md +3 -1
- data/docs/internals/bundles.md +4 -0
- data/docs/internals/engine.md +13 -3
- data/docs/plugins.md +144 -3
- data/docs/releasing.md +2 -2
- data/docs/sessions.md +1 -1
- data/docs/testing.md +32 -2
- data/lib/samagotchi/bootstrap/config_writer.rb +13 -3
- data/lib/samagotchi/bootstrap/probe.rb +153 -31
- data/lib/samagotchi/bootstrap_command.rb +92 -15
- data/lib/samagotchi/bridge.rb +1 -1
- data/lib/samagotchi/bundles/system/manifest.yml +2 -2
- data/lib/samagotchi/bundles/system/self_map.md +1 -1
- data/lib/samagotchi/continue_offer.rb +5 -5
- data/lib/samagotchi/engine.rb +40 -37
- data/lib/samagotchi/guardrails/approval.rb +6 -4
- data/lib/samagotchi/guardrails/gate.rb +7 -3
- data/lib/samagotchi/hooks/bundle_loader.rb +31 -16
- data/lib/samagotchi/hooks/registry.rb +44 -3
- data/lib/samagotchi/host_registry.rb +12 -4
- data/lib/samagotchi/llm/adapter_common.rb +4 -2
- data/lib/samagotchi/llm/anthropic_binding_recovery.rb +3 -0
- data/lib/samagotchi/llm/anthropic_messages.rb +2 -1
- data/lib/samagotchi/llm/http.rb +12 -7
- data/lib/samagotchi/plugin/card.rb +44 -0
- data/lib/samagotchi/plugin/context.rb +53 -8
- data/lib/samagotchi/plugin/http.rb +154 -0
- data/lib/samagotchi/plugin/http_transport.rb +77 -0
- data/lib/samagotchi/plugin/loader.rb +29 -10
- data/lib/samagotchi/question_answer.rb +29 -0
- data/lib/samagotchi/question_desk.rb +20 -19
- data/lib/samagotchi/relay_verifier.rb +1 -1
- data/lib/samagotchi/testing/boundary.rb +156 -0
- data/lib/samagotchi/testing/bundle.rb +349 -0
- data/lib/samagotchi/testing/fake_executable.rb +42 -0
- data/lib/samagotchi/testing/fake_http.rb +137 -0
- data/lib/samagotchi/testing/helpers.rb +56 -0
- data/lib/samagotchi/testing/host.rb +76 -0
- data/lib/samagotchi/testing/minitest.rb +31 -0
- data/lib/samagotchi/testing/recorder.rb +138 -0
- data/lib/samagotchi/testing/recording_api.rb +27 -0
- data/lib/samagotchi/testing/rspec.rb +31 -0
- data/lib/samagotchi/testing/sandbox.rb +163 -0
- data/lib/samagotchi/testing/sessions.rb +77 -0
- data/lib/samagotchi/testing/verdict.rb +28 -0
- data/lib/samagotchi/testing/waiting.rb +36 -0
- data/lib/samagotchi/testing.rb +26 -0
- data/lib/samagotchi/tools/delegate_relay.rb +7 -6
- data/lib/samagotchi/tools/tool_index.rb +3 -0
- data/lib/samagotchi/turn_state.rb +28 -1
- data/lib/samagotchi/version.rb +1 -1
- data/lib/samagotchi/web/public/app.js +47 -23
- data/lib/samagotchi/web/public/images.js +33 -0
- data/lib/samagotchi/web/public/index.html +71 -38
- data/lib/samagotchi/web/public/level_chip.js +11 -11
- data/lib/samagotchi/web/public/lists_view.js +19 -14
- data/lib/samagotchi/web/public/llm_context_chip.js +15 -15
- data/lib/samagotchi/web/public/model_picker.js +1 -1
- data/lib/samagotchi/web/public/scope.js +3 -3
- data/lib/samagotchi/web/public/strip.js +35 -9
- data/lib/samagotchi/web/public/strip_grip.js +76 -0
- data/lib/samagotchi/web/public/thinking_chip.js +5 -5
- metadata +21 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { GRIP_OPEN_PX } from "./composer_size.js";
|
|
2
|
+
import { stripGripAction, stripGripTitle } from "./strip.js";
|
|
3
|
+
|
|
4
|
+
// The latest-sessions strip's grip (used by app.js): the handle on the edge
|
|
5
|
+
// between the strip and the chat, the composer's grip's twin, mirrored. A
|
|
6
|
+
// drag up (or a tap) hides the strip, a drag down (or a tap) shows it, and
|
|
7
|
+
// Enter or Space toggles too. The strip snaps: unlike the composer's box it
|
|
8
|
+
// does not follow the pointer, so nothing is measured while dragging — only
|
|
9
|
+
// whether the release would act (.will-toggle, the pill in the accent).
|
|
10
|
+
// The grip owns its title and aria-expanded (composer_grip.js's
|
|
11
|
+
// drawFoldControls does the same for the composer's): app.js calls the
|
|
12
|
+
// returned refresh() from applyStripHidden, and nothing else writes them.
|
|
13
|
+
// No click listener: a click still fires after pointerdown's preventDefault
|
|
14
|
+
// and would toggle twice. No document listener either: the composer's grip
|
|
15
|
+
// needs one for typing on the page, this one acts only on itself.
|
|
16
|
+
// +setHidden(true)+ hides the strip, +isHidden()+ says whether it is hidden.
|
|
17
|
+
export function createStripGrip({ gripEl, isHidden, setHidden }) {
|
|
18
|
+
let willToggle = false;
|
|
19
|
+
|
|
20
|
+
function refresh() {
|
|
21
|
+
const hidden = isHidden();
|
|
22
|
+
gripEl.setAttribute("aria-expanded", hidden ? "false" : "true");
|
|
23
|
+
gripEl.title = stripGripTitle({ hidden, willToggle });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function setWillToggle(will) {
|
|
27
|
+
if (will === willToggle) return;
|
|
28
|
+
willToggle = will;
|
|
29
|
+
gripEl.classList.toggle("will-toggle", will);
|
|
30
|
+
refresh();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
gripEl.addEventListener("pointerdown", (e) => {
|
|
34
|
+
e.preventDefault();
|
|
35
|
+
gripEl.setPointerCapture(e.pointerId);
|
|
36
|
+
gripEl.classList.add("dragging");
|
|
37
|
+
const startY = e.clientY;
|
|
38
|
+
// Past a tap's size, and the release would act: the pill promises. A
|
|
39
|
+
// tap-sized move never flickers it (that stays a tap).
|
|
40
|
+
const willAfter = (dy) => Math.abs(dy) >= GRIP_OPEN_PX && stripGripAction({ hidden: isHidden(), dy }) !== null;
|
|
41
|
+
const move = (ev) => setWillToggle(willAfter(ev.clientY - startY));
|
|
42
|
+
const end = () => {
|
|
43
|
+
gripEl.classList.remove("dragging");
|
|
44
|
+
gripEl.removeEventListener("pointermove", move);
|
|
45
|
+
gripEl.removeEventListener("pointerup", up);
|
|
46
|
+
gripEl.removeEventListener("pointercancel", cancel);
|
|
47
|
+
};
|
|
48
|
+
const up = (ev) => {
|
|
49
|
+
const action = stripGripAction({ hidden: isHidden(), dy: ev.clientY - startY });
|
|
50
|
+
end();
|
|
51
|
+
setWillToggle(false);
|
|
52
|
+
if (action) setHidden(action === "hide");
|
|
53
|
+
refresh();
|
|
54
|
+
};
|
|
55
|
+
const cancel = () => {
|
|
56
|
+
end();
|
|
57
|
+
setWillToggle(false);
|
|
58
|
+
refresh();
|
|
59
|
+
};
|
|
60
|
+
gripEl.addEventListener("pointermove", move);
|
|
61
|
+
gripEl.addEventListener("pointerup", up);
|
|
62
|
+
gripEl.addEventListener("pointercancel", cancel);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Enter or Space on the focused handle toggles (preventDefault: Space
|
|
66
|
+
// would scroll the page).
|
|
67
|
+
gripEl.addEventListener("keydown", (e) => {
|
|
68
|
+
if (e.key !== "Enter" && e.key !== " ") return;
|
|
69
|
+
e.preventDefault();
|
|
70
|
+
setHidden(!isHidden());
|
|
71
|
+
refresh();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
refresh();
|
|
75
|
+
return refresh;
|
|
76
|
+
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// {level, source, own}; the worker's snapshot, a command_ran, or the
|
|
7
7
|
// server's own reading of the session file). A config on level_chip.js.
|
|
8
8
|
//
|
|
9
|
-
// The start page has one too (kind "new
|
|
9
|
+
// The start page has one too (kind "new session"): it shows the picked
|
|
10
10
|
// model's level (GET /api/models' thinking) and keeps a choice for the
|
|
11
11
|
// next create only (POST /api/sessions' thinking), never remembered:
|
|
12
12
|
// nothing is sent unless the user sets one.
|
|
@@ -26,20 +26,20 @@ export const CONFIG = Object.freeze({
|
|
|
26
26
|
formClass: "think-form",
|
|
27
27
|
popoverClass: "think-popover",
|
|
28
28
|
nowClass: "think-now",
|
|
29
|
-
when: (fresh) => (fresh ? "For the new
|
|
29
|
+
when: (fresh) => (fresh ? "For the new session's first turn on; not remembered for the next one."
|
|
30
30
|
: "From the next turn's start. On Gemma the whole prompt is read again; a hosted API reads the whole conversation again."),
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
export const { nowText } = level;
|
|
34
34
|
|
|
35
|
-
// The new
|
|
35
|
+
// The new session's choice (a level, or null) laid over the model's summary:
|
|
36
36
|
// what the chip shows. The model's own summary without a choice.
|
|
37
37
|
export function withChoice(summary, choice) {
|
|
38
38
|
if (!summary || !choice) return summary;
|
|
39
39
|
return { ...summary, level: choice, source: SESSION, own: choice };
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
// The chip: its text, tooltip and whether the session (or the new
|
|
42
|
+
// The chip: its text, tooltip and whether the session (or the new session)
|
|
43
43
|
// set its own; null without a summary (an older worker). The default with
|
|
44
44
|
// nothing set anywhere shows too ("think default"): the chip is where the
|
|
45
45
|
// level is set.
|
|
@@ -67,7 +67,7 @@ export function formTemplate(summary, opts) {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
// The chip's popover (level_chip.js createLevelControl); the start page's
|
|
70
|
-
// passes kind
|
|
70
|
+
// passes kind NEW_SESSION, choice and choose.
|
|
71
71
|
export function createThinkingControl({ id = "thinkingPopover", ...opts }) {
|
|
72
72
|
return level.createLevelControl({ cfg: CONFIG, id, ...opts });
|
|
73
73
|
}
|
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.80.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dmitry Dedov
|
|
@@ -417,7 +417,10 @@ files:
|
|
|
417
417
|
- lib/samagotchi/pending_question.rb
|
|
418
418
|
- lib/samagotchi/plugin/api.rb
|
|
419
419
|
- lib/samagotchi/plugin/attached_context.rb
|
|
420
|
+
- lib/samagotchi/plugin/card.rb
|
|
420
421
|
- lib/samagotchi/plugin/context.rb
|
|
422
|
+
- lib/samagotchi/plugin/http.rb
|
|
423
|
+
- lib/samagotchi/plugin/http_transport.rb
|
|
421
424
|
- lib/samagotchi/plugin/loader.rb
|
|
422
425
|
- lib/samagotchi/plugin/peer.rb
|
|
423
426
|
- lib/samagotchi/plugin/service.rb
|
|
@@ -435,6 +438,7 @@ files:
|
|
|
435
438
|
- lib/samagotchi/prompt_literal_guard.rb
|
|
436
439
|
- lib/samagotchi/prompt_note.rb
|
|
437
440
|
- lib/samagotchi/prompt_warmup.rb
|
|
441
|
+
- lib/samagotchi/question_answer.rb
|
|
438
442
|
- lib/samagotchi/question_desk.rb
|
|
439
443
|
- lib/samagotchi/queued_command.rb
|
|
440
444
|
- lib/samagotchi/reasoning_history.rb
|
|
@@ -501,6 +505,21 @@ files:
|
|
|
501
505
|
- lib/samagotchi/terminal_ui/surface.rb
|
|
502
506
|
- lib/samagotchi/terminal_ui/thinking_line.rb
|
|
503
507
|
- lib/samagotchi/terminal_ui/version_lines.rb
|
|
508
|
+
- lib/samagotchi/testing.rb
|
|
509
|
+
- lib/samagotchi/testing/boundary.rb
|
|
510
|
+
- lib/samagotchi/testing/bundle.rb
|
|
511
|
+
- lib/samagotchi/testing/fake_executable.rb
|
|
512
|
+
- lib/samagotchi/testing/fake_http.rb
|
|
513
|
+
- lib/samagotchi/testing/helpers.rb
|
|
514
|
+
- lib/samagotchi/testing/host.rb
|
|
515
|
+
- lib/samagotchi/testing/minitest.rb
|
|
516
|
+
- lib/samagotchi/testing/recorder.rb
|
|
517
|
+
- lib/samagotchi/testing/recording_api.rb
|
|
518
|
+
- lib/samagotchi/testing/rspec.rb
|
|
519
|
+
- lib/samagotchi/testing/sandbox.rb
|
|
520
|
+
- lib/samagotchi/testing/sessions.rb
|
|
521
|
+
- lib/samagotchi/testing/verdict.rb
|
|
522
|
+
- lib/samagotchi/testing/waiting.rb
|
|
504
523
|
- lib/samagotchi/text_diff.rb
|
|
505
524
|
- lib/samagotchi/thinking.rb
|
|
506
525
|
- lib/samagotchi/thinking_command.rb
|
|
@@ -652,6 +671,7 @@ files:
|
|
|
652
671
|
- lib/samagotchi/web/public/storage.js
|
|
653
672
|
- lib/samagotchi/web/public/stream_handlers.js
|
|
654
673
|
- lib/samagotchi/web/public/strip.js
|
|
674
|
+
- lib/samagotchi/web/public/strip_grip.js
|
|
655
675
|
- lib/samagotchi/web/public/tally.js
|
|
656
676
|
- lib/samagotchi/web/public/task_stop.js
|
|
657
677
|
- lib/samagotchi/web/public/thinking_chip.js
|