samagotchi 0.154.1 → 0.156.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 +29 -1
- data/bin/chi +1 -1
- data/docs/architecture.md +12 -7
- data/docs/bundles.md +21 -0
- data/docs/cli.md +1 -1
- data/docs/guardrails.md +2 -2
- data/docs/hooks.md +1 -1
- data/docs/internals/anthropic.md +5 -5
- data/docs/internals/attached-context.md +9 -6
- data/docs/internals/background-tasks.md +1 -1
- data/docs/internals/block-renderers.md +8 -1
- data/docs/internals/engine.md +642 -831
- data/docs/internals/inline-widgets.md +136 -0
- data/docs/internals/llm-context-forget.md +8 -3
- data/docs/internals/objectives.md +8 -6
- data/docs/internals/participants.md +5 -5
- data/docs/internals/prompt-caching.md +13 -6
- data/docs/internals/remote-sessions.md +3 -1
- data/docs/internals/web-frontend.md +1 -1
- data/docs/internals/working-set.md +2 -1
- data/docs/plugins.md +2 -0
- data/docs/releasing.md +1 -1
- data/docs/sessions.md +4 -4
- data/docs/system-one.md +3 -2
- data/docs/testing.md +1 -1
- data/lib/samagotchi/block_renderers.rb +5 -0
- data/lib/samagotchi/bootstrap/config_writer.rb +1 -1
- data/lib/samagotchi/broadcast_command.rb +3 -3
- data/lib/samagotchi/bundle_command/check.rb +1 -1
- data/lib/samagotchi/bundle_command/try/sandbox.rb +1 -1
- data/lib/samagotchi/bundles/dev/manifest.yml +3 -2
- data/lib/samagotchi/bundles/inline-widgets/manifest.yml +11 -0
- data/lib/samagotchi/bundles/inline-widgets/plugin.rb +76 -0
- data/lib/samagotchi/bundles/system/config_modification_protocol.md +2 -2
- data/lib/samagotchi/bundles/system/manifest.yml +2 -2
- data/lib/samagotchi/child_move.rb +7 -51
- data/lib/samagotchi/children_status.rb +1 -1
- data/lib/samagotchi/cli/parent_wait.rb +1 -1
- data/lib/samagotchi/config.rb +17 -112
- data/lib/samagotchi/context_command.rb +1 -2
- data/lib/samagotchi/context_window.rb +3 -3
- data/lib/samagotchi/desktop/macos.rb +1 -1
- data/lib/samagotchi/engine/context_judge.rb +21 -119
- data/lib/samagotchi/engine/guardrails.rb +4 -2
- data/lib/samagotchi/engine/messages.rb +9 -6
- data/lib/samagotchi/engine/models.rb +5 -2
- data/lib/samagotchi/engine/objectives.rb +30 -80
- data/lib/samagotchi/engine/participants.rb +15 -10
- data/lib/samagotchi/engine/plugins.rb +3 -1
- data/lib/samagotchi/engine/questions.rb +1 -1
- data/lib/samagotchi/engine/side_requests.rb +26 -13
- data/lib/samagotchi/engine/toolkit.rb +35 -191
- data/lib/samagotchi/engine/turn_end.rb +1 -1
- data/lib/samagotchi/engine/turn_helpers.rb +16 -39
- data/lib/samagotchi/engine/verify.rb +7 -143
- data/lib/samagotchi/engine.rb +166 -98
- data/lib/samagotchi/engine_peers.rb +1 -1
- data/lib/samagotchi/event_fanout.rb +18 -12
- data/lib/samagotchi/guardrail_wiring.rb +83 -82
- data/lib/samagotchi/guardrails/gate.rb +41 -40
- data/lib/samagotchi/guardrails/pair_boundary.rb +2 -1
- data/lib/samagotchi/guardrails/review_boundary.rb +2 -1
- data/lib/samagotchi/guardrails/targets.rb +28 -11
- data/lib/samagotchi/guardrails_command.rb +1 -1
- data/lib/samagotchi/host_config.rb +72 -1
- data/lib/samagotchi/host_model.rb +2 -6
- data/lib/samagotchi/host_registry.rb +1 -1
- data/lib/samagotchi/inline_widgets.rb +325 -0
- data/lib/samagotchi/kernel_loop.rb +215 -313
- data/lib/samagotchi/llm/anthropic_wire.rb +2 -2
- data/lib/samagotchi/llm/backend.rb +3 -1
- data/lib/samagotchi/llm/chat_loop.rb +87 -49
- data/lib/samagotchi/llm/native_backend.rb +3 -2
- data/lib/samagotchi/llm_context_apply.rb +54 -1
- data/lib/samagotchi/llm_context_forget.rb +5 -3
- data/lib/samagotchi/llm_context_notice.rb +1 -1
- data/lib/samagotchi/llm_context_strategy.rb +7 -9
- data/lib/samagotchi/llm_context_view.rb +9 -0
- data/lib/samagotchi/model_binding.rb +3 -3
- data/lib/samagotchi/model_price.rb +4 -10
- data/lib/samagotchi/model_profile.rb +6 -6
- data/lib/samagotchi/model_settings.rb +37 -2
- data/lib/samagotchi/note_command.rb +1 -2
- data/lib/samagotchi/objectives_audit.rb +4 -3
- data/lib/samagotchi/participants.rb +2 -2
- data/lib/samagotchi/plugin/context.rb +1 -1
- data/lib/samagotchi/plugin/prompt_sections.rb +7 -0
- data/lib/samagotchi/plugin/sessions.rb +2 -5
- data/lib/samagotchi/plugin/tool_spec.rb +5 -3
- data/lib/samagotchi/project_env.rb +1 -1
- data/lib/samagotchi/question_desk.rb +1 -1
- data/lib/samagotchi/reasoning_history.rb +3 -3
- data/lib/samagotchi/reminder_carry.rb +1 -1
- data/lib/samagotchi/reprefill_meter.rb +45 -0
- data/lib/samagotchi/review_command.rb +1 -1
- data/lib/samagotchi/revise_anchor.rb +1 -1
- data/lib/samagotchi/sampling_settings.rb +3 -3
- data/lib/samagotchi/self_report.rb +7 -7
- data/lib/samagotchi/session.rb +50 -7
- data/lib/samagotchi/session_access/local.rb +7 -5
- data/lib/samagotchi/session_access/remote.rb +17 -3
- data/lib/samagotchi/session_archive_command.rb +2 -2
- data/lib/samagotchi/session_chain.rb +7 -6
- data/lib/samagotchi/session_continue.rb +6 -5
- data/lib/samagotchi/session_delete_command.rb +1 -1
- data/lib/samagotchi/session_manager/delivery.rb +254 -0
- data/lib/samagotchi/session_manager/emptiness.rb +138 -0
- data/lib/samagotchi/session_manager/lifecycle.rb +274 -0
- data/lib/samagotchi/session_manager/listing.rb +189 -0
- data/lib/samagotchi/session_manager/removal.rb +190 -0
- data/lib/samagotchi/session_manager/spawn.rb +242 -0
- data/lib/samagotchi/session_manager/worker_command.rb +157 -0
- data/lib/samagotchi/session_manager.rb +26 -1540
- data/lib/samagotchi/session_metrics.rb +1 -1
- data/lib/samagotchi/sessions_command.rb +1 -1
- data/lib/samagotchi/share_command.rb +1 -1
- data/lib/samagotchi/starting_marker.rb +65 -0
- data/lib/samagotchi/steer_cut_after.rb +3 -3
- data/lib/samagotchi/system_one/recorder.rb +49 -0
- data/lib/samagotchi/system_prompt.rb +37 -30
- data/lib/samagotchi/terminal_ui/exit_lines.rb +1 -1
- data/lib/samagotchi/terminal_ui.rb +2 -6
- data/lib/samagotchi/testing/boundary.rb +7 -0
- data/lib/samagotchi/testing/bundle.rb +7 -5
- data/lib/samagotchi/testing/install.rb +3 -2
- data/lib/samagotchi/testing/sessions.rb +1 -1
- data/lib/samagotchi/thinking.rb +3 -3
- data/lib/samagotchi/token_usage.rb +1 -1
- data/lib/samagotchi/tool_activity.rb +15 -7
- data/lib/samagotchi/tool_declarations.rb +6 -6
- data/lib/samagotchi/tool_output_cut.rb +17 -0
- data/lib/samagotchi/tool_response.rb +4 -3
- data/lib/samagotchi/tool_runner.rb +96 -102
- data/lib/samagotchi/toolkit_binding.rb +40 -14
- data/lib/samagotchi/toolkit_command.rb +1 -1
- data/lib/samagotchi/tools/deferred_tools.rb +17 -21
- data/lib/samagotchi/tools/delegate.rb +10 -5
- data/lib/samagotchi/tools/delegate_result.rb +4 -4
- data/lib/samagotchi/tools/index_hint.rb +14 -0
- data/lib/samagotchi/tools/registry.rb +64 -44
- data/lib/samagotchi/tools/send_note.rb +4 -6
- data/lib/samagotchi/tools/tool_index.rb +150 -102
- data/lib/samagotchi/tools/tool_surface.rb +187 -0
- data/lib/samagotchi/turn_context.rb +68 -0
- data/lib/samagotchi/turn_stages/context_judge.rb +172 -0
- data/lib/samagotchi/turn_stages/objectives.rb +150 -0
- data/lib/samagotchi/turn_stages/toolkit_suggestion.rb +257 -0
- data/lib/samagotchi/turn_stages/verify_anchors.rb +168 -0
- data/lib/samagotchi/turn_stages/warmup.rb +82 -0
- data/lib/samagotchi/turn_state.rb +46 -4
- data/lib/samagotchi/version.rb +1 -1
- data/lib/samagotchi/vision_support.rb +3 -3
- data/lib/samagotchi/web/app.rb +15 -8
- data/lib/samagotchi/web/markdown_renderer.rb +39 -14
- data/lib/samagotchi/web/message_display.rb +1 -1
- data/lib/samagotchi/web/participant_access.rb +2 -2
- data/lib/samagotchi/web/public/app.js +5 -1
- data/lib/samagotchi/web/public/block_host.js +74 -199
- data/lib/samagotchi/web/public/block_renderers.css +2 -0
- data/lib/samagotchi/web/public/block_source.js +7 -4
- data/lib/samagotchi/web/public/block_watch.js +256 -0
- data/lib/samagotchi/web/public/composer_fold.js +3 -0
- data/lib/samagotchi/web/public/index.html +28 -9
- data/lib/samagotchi/web/public/inline_widgets.js +146 -0
- data/lib/samagotchi/web/public/owner_verify.js +1 -1
- data/lib/samagotchi/web/public/participant.js +1 -1
- data/lib/samagotchi/web/public/revise_stack.js +1 -1
- data/lib/samagotchi/web/public/stage_watch.js +6 -2
- data/lib/samagotchi/web/public/text_roots.js +1 -1
- data/lib/samagotchi/web/public/verify_target.js +1 -1
- data/lib/samagotchi/web/public/widget_picks.js +130 -0
- data/lib/samagotchi/web/public/widget_walk.js +230 -0
- data/lib/samagotchi/web/public/widgets.css +70 -0
- data/lib/samagotchi/web/session_access_routes.rb +3 -3
- data/lib/samagotchi/web/session_control.rb +3 -3
- data/lib/samagotchi/web/session_create.rb +3 -3
- data/lib/samagotchi/web/session_hub.rb +1 -1
- data/lib/samagotchi/web/session_show.rb +3 -3
- data/lib/samagotchi/web/session_summary.rb +3 -4
- data/lib/samagotchi/worker.rb +55 -27
- data/lib/samagotchi/worker_boot.rb +184 -0
- data/lib/samagotchi/worker_signals.rb +1 -1
- data/lib/samagotchi/worker_task_wakes.rb +2 -2
- metadata +29 -1
|
@@ -314,11 +314,13 @@ module Samagotchi
|
|
|
314
314
|
|
|
315
315
|
# @return [String] the child's id, or an Error: line
|
|
316
316
|
def self.follow_up(task, session:, parent:, state_dir:)
|
|
317
|
-
id = Session.
|
|
317
|
+
id = Session.resolve!(session, state_dir: state_dir)
|
|
318
318
|
child = begin
|
|
319
319
|
Session.load(id, state_dir: state_dir)
|
|
320
|
-
rescue
|
|
321
|
-
|
|
320
|
+
rescue Session::NotFound
|
|
321
|
+
raise # gone since resolve!: the outer rescue adds the list_sessions hint
|
|
322
|
+
rescue ArgumentError => e # a file that won't load
|
|
323
|
+
return "Error: #{e.message}"
|
|
322
324
|
end
|
|
323
325
|
unless child.parent_id == parent.id
|
|
324
326
|
return "Error: #{id[0, 8]} is not a delegate of this session; send_note reaches any session"
|
|
@@ -340,6 +342,8 @@ module Samagotchi
|
|
|
340
342
|
"Error: session #{id[0, 8]}: #{e.message}"
|
|
341
343
|
rescue SessionManager::OwnedByTUI
|
|
342
344
|
"Error: session #{id[0, 8]} is #{OwnerLock::TUI_BUSY}, which can't take a delegated message"
|
|
345
|
+
rescue Session::NotFound => e
|
|
346
|
+
"Error: #{e.message} (list_sessions shows them)"
|
|
343
347
|
rescue Session::AmbiguousId => e
|
|
344
348
|
"Error: #{e.message}"
|
|
345
349
|
end
|
|
@@ -392,10 +396,11 @@ module Samagotchi
|
|
|
392
396
|
# busy (a worker runs its turn), or running with a worker on its way
|
|
393
397
|
# (ChildrenStatus asks it too).
|
|
394
398
|
# @param summary [Hash] a children_of row, or the same keys: busy,
|
|
395
|
-
# status
|
|
399
|
+
# saved_status (the file's: the displayed status shows a worker on
|
|
400
|
+
# its way as idle), live, updated_at
|
|
396
401
|
def self.running?(summary)
|
|
397
402
|
return true if summary[:busy]
|
|
398
|
-
return false unless summary[:
|
|
403
|
+
return false unless summary[:saved_status] == Session::STATUS_RUNNING && !summary[:live]
|
|
399
404
|
|
|
400
405
|
Time.now - Time.iso8601(summary[:updated_at].to_s) < STARTING_GRACE_SECONDS
|
|
401
406
|
rescue ArgumentError
|
|
@@ -29,7 +29,7 @@ module Samagotchi
|
|
|
29
29
|
newest_running_child(peers.session_id, state_dir: sd) ||
|
|
30
30
|
(return "No running delegate; list_sessions shows finished ones.")
|
|
31
31
|
else
|
|
32
|
-
id = Session.
|
|
32
|
+
id = Session.resolve!(session.to_s.strip, state_dir: sd)
|
|
33
33
|
child = Session.load(id, state_dir: sd)
|
|
34
34
|
unless child.parent_id == peers.session_id
|
|
35
35
|
return "Error: #{id[0, 8]} is not a delegate of this session (list_sessions marks them child)"
|
|
@@ -38,10 +38,10 @@ module Samagotchi
|
|
|
38
38
|
id
|
|
39
39
|
end
|
|
40
40
|
DelegateWait.call(child_id, peers: peers, timeout: Delegate.parse_timeout(timeout))
|
|
41
|
-
rescue Session::
|
|
41
|
+
rescue Session::NotFound => e
|
|
42
|
+
"Error: #{e.message} (list_sessions shows them)"
|
|
43
|
+
rescue ArgumentError => e
|
|
42
44
|
"Error: #{e.message}"
|
|
43
|
-
rescue ArgumentError
|
|
44
|
-
"Error: no session #{session.to_s.strip} (list_sessions shows them)"
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def self.newest_running_child(parent_id, state_dir:)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Samagotchi
|
|
4
|
+
module Tools
|
|
5
|
+
# find_tools' answer text that the wire reads too, kept a leaf (no
|
|
6
|
+
# requires): ToolIndex writes CALL_HINT as a keyword answer's first
|
|
7
|
+
# line, and LLM::AnthropicWire strips it from a result whose tools it
|
|
8
|
+
# loads (they are called directly then).
|
|
9
|
+
module IndexHint
|
|
10
|
+
# A keyword answer's first line; call_tool is BuiltinCalls::VIA.
|
|
11
|
+
CALL_HINT = "Call one with call_tool(tool: \"<group>/<tool>\", args: {…})."
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -2,14 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
module Samagotchi
|
|
4
4
|
module Tools
|
|
5
|
+
# A reader of the turn's tools (Tools::ToolSurface) given none: a
|
|
6
|
+
# context or call that should carry the turn's carries nothing. Never
|
|
7
|
+
# taken as a failing preview's or targets' (ToolActivity, Guardrails::
|
|
8
|
+
# Targets re-raise it): a rule's acts_as must not silently go missing.
|
|
9
|
+
class MissingSurface < StandardError
|
|
10
|
+
def initialize(msg = "no ToolSurface: the turn's tools are missing (TurnContext#surface)") = super
|
|
11
|
+
end
|
|
12
|
+
|
|
5
13
|
# The tools a session offers the model, in declaration order: the
|
|
6
14
|
# built-ins (Tools::Builtins) as registered, then the ones bundles add,
|
|
7
15
|
# by bundle and name. That order doesn't depend on which plugin
|
|
8
16
|
# finished its init first or re-registered a changed tool, so the
|
|
9
17
|
# tool list (part of the prompt's cached prefix) is the same in every
|
|
10
|
-
# session with the same tools.
|
|
11
|
-
#
|
|
12
|
-
#
|
|
18
|
+
# session with the same tools. Its readers (the prompt, a turn's
|
|
19
|
+
# loops, the tool index, /toolkit) read the Tools::ToolSurface built
|
|
20
|
+
# from its lists (#entries, #reachable_names, #left_out_names,
|
|
21
|
+
# #removed_names, #stranded_names) under a toolkit and layers.
|
|
13
22
|
class Registry
|
|
14
23
|
# @!attribute name [String]
|
|
15
24
|
# @!attribute schema [Hash] {name:, description:, parameters:}, as in
|
|
@@ -18,22 +27,45 @@ module Samagotchi
|
|
|
18
27
|
# "Error: …" marks a failure); kctx is the KernelLoop's ToolContext
|
|
19
28
|
# @!attribute label [String, nil] the activity line's action ("calling
|
|
20
29
|
# tool" when nil); ToolActivity knows the built-ins' own
|
|
21
|
-
# @!attribute preview [#call, nil] call → the activity line's
|
|
22
|
-
#
|
|
30
|
+
# @!attribute preview [#call, nil] (call, surface) → the activity line's
|
|
31
|
+
# params; +surface+ the turn's Tools::ToolSurface (nil: none)
|
|
32
|
+
# @!attribute targets [#call, nil] (call, surface) → what guardrail
|
|
33
|
+
# rules match. #register takes a one-argument preview or targets
|
|
34
|
+
# (call only, a plugin's) and gives it this form (.per_call)
|
|
23
35
|
# @!attribute refs [#call, nil] call → the row's refs (a plugin's
|
|
24
36
|
# refs:, RowRefs checks what it gives)
|
|
25
37
|
# @!attribute source [String] "core", or the bundle that added it
|
|
26
38
|
# @!attribute layer [Symbol, nil] the LLM context layer the tool
|
|
27
39
|
# belongs to (LLMContextStrategy): offered only in a turn running
|
|
28
40
|
# under it (forget_outputs, :forget); nil: always
|
|
29
|
-
# @!attribute unwrap [#call, nil] (call,
|
|
30
|
-
# for, run in its place before
|
|
31
|
-
# of chi's own tools:
|
|
32
|
-
# it is; nil on every
|
|
41
|
+
# @!attribute unwrap [#call, nil] (call, surface) → the call it stands
|
|
42
|
+
# for under the turn's Tools::ToolSurface, run in its place before
|
|
43
|
+
# the guardrail gate (call_tool on one of chi's own tools:
|
|
44
|
+
# Tools::ToolIndex#unwrap), or nil to run it as it is; nil on every
|
|
45
|
+
# other tool
|
|
33
46
|
Entry = Struct.new(:name, :schema, :handler, :label, :preview, :targets, :refs, :source, :layer, :unwrap,
|
|
34
47
|
keyword_init: true) do
|
|
35
48
|
def core? = source == "core"
|
|
36
49
|
|
|
50
|
+
# Its preview on +call+ (the row's params), nil without one.
|
|
51
|
+
# +surface+, the turn's Tools::ToolSurface (nil: none), is what
|
|
52
|
+
# call_tool's reads (what the turn reaches: it raises MissingSurface
|
|
53
|
+
# without one); a plugin's ignores it.
|
|
54
|
+
def preview_of(call, surface = nil) = preview&.call(call, surface)
|
|
55
|
+
|
|
56
|
+
# Its targets on +call+ (what guardrail rules match), nil without
|
|
57
|
+
# any; +surface+ as #preview_of.
|
|
58
|
+
def targets_of(call, surface = nil) = targets&.call(call, surface)
|
|
59
|
+
|
|
60
|
+
# +callable+ as (call, surface) → value, the one form an entry's
|
|
61
|
+
# preview and targets take: a one-argument one (call only) is given
|
|
62
|
+
# the call alone. The arity is read here, once, at registration.
|
|
63
|
+
def self.per_call(callable)
|
|
64
|
+
return callable if callable.nil? || callable.arity != 1
|
|
65
|
+
|
|
66
|
+
->(call, _surface = nil) { callable.call(call) }
|
|
67
|
+
end
|
|
68
|
+
|
|
37
69
|
# Offered in a turn under +layers+ (the turn's LLM context layers).
|
|
38
70
|
def offered?(layers) = layer.nil? || Array(layers).include?(layer)
|
|
39
71
|
end
|
|
@@ -43,17 +75,19 @@ module Samagotchi
|
|
|
43
75
|
# name, and +groups+ the source groups registered when the plugins
|
|
44
76
|
# loaded; +loaded+ the entries registered then (nil: whatever is
|
|
45
77
|
# registered now), which alone decide whether the index's tools are
|
|
46
|
-
# needed (Registry#index_needed?). +deferrable+ (→ the
|
|
47
|
-
# tools a host that loads tools may declare deferred)
|
|
48
|
-
# (call → the call_tool call a direct call of one
|
|
49
|
-
# nil)
|
|
78
|
+
# needed (Registry#index_needed?). +deferrable+ (surface → the
|
|
79
|
+
# sources' tools a host that loads tools may declare deferred),
|
|
80
|
+
# +wrap+ ((call, surface) → the call_tool call a direct call of one
|
|
81
|
+
# of them runs as, or nil) and +unreached+ ((name, surface) → a
|
|
82
|
+
# source tool the toolkit doesn't reach) are nil when nothing reaches
|
|
83
|
+
# them; each is given the turn's Tools::ToolSurface.
|
|
50
84
|
Index = Data.define(:source, :call_name, :groups, :deferrable, :wrap, :unreached, :loaded) do
|
|
51
85
|
def initialize(source:, call_name:, groups:, deferrable: nil, wrap: nil, unreached: nil, loaded: nil)
|
|
52
86
|
super(source: source, call_name: call_name, groups: Array(groups).map(&:to_s).uniq.freeze,
|
|
53
87
|
deferrable: deferrable, wrap: wrap, unreached: unreached, loaded: loaded&.dup&.freeze)
|
|
54
88
|
end
|
|
55
89
|
|
|
56
|
-
def unreached_tool(name) = unreached&.call(name)
|
|
90
|
+
def unreached_tool(name, surface) = unreached&.call(name, surface)
|
|
57
91
|
end
|
|
58
92
|
|
|
59
93
|
def initialize
|
|
@@ -66,7 +100,7 @@ module Samagotchi
|
|
|
66
100
|
attr_accessor :index
|
|
67
101
|
|
|
68
102
|
# The session's resolved toolkit (Toolkit::Resolved), which the lists
|
|
69
|
-
# below
|
|
103
|
+
# below filter by; nil declares every tool (full). The
|
|
70
104
|
# Engine sets it at a turn's start, before the prompt is built, and
|
|
71
105
|
# only there: a request's declared tools never change mid-turn.
|
|
72
106
|
attr_accessor :toolkit
|
|
@@ -81,8 +115,9 @@ module Samagotchi
|
|
|
81
115
|
unwrap: nil)
|
|
82
116
|
raise ArgumentError, "tool #{name} is already registered" if @entries.key?(name)
|
|
83
117
|
|
|
84
|
-
@entries[name] = Entry.new(name: name, schema: schema, handler: handler, label: label,
|
|
85
|
-
targets: targets, refs: refs,
|
|
118
|
+
@entries[name] = Entry.new(name: name, schema: schema, handler: handler, label: label,
|
|
119
|
+
preview: Entry.per_call(preview), targets: Entry.per_call(targets), refs: refs,
|
|
120
|
+
source: source, layer: layer, unwrap: unwrap)
|
|
86
121
|
end
|
|
87
122
|
|
|
88
123
|
# Remove a tool (a plugin's tool set changed after load).
|
|
@@ -94,22 +129,6 @@ module Samagotchi
|
|
|
94
129
|
|
|
95
130
|
def key?(name) = @entries.key?(name.to_s)
|
|
96
131
|
|
|
97
|
-
# The entry +name+ names when a turn under +layers+ offers it (the
|
|
98
|
-
# one a call dispatches to).
|
|
99
|
-
# @return [Entry, nil]
|
|
100
|
-
def offered(name, layers: [])
|
|
101
|
-
entry = self[name]
|
|
102
|
-
entry if entry&.offered?(layers) && declared?(entry)
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# The entry +name+ names when the session's toolkit leaves it out (a
|
|
106
|
-
# real tool the model can't call here, by its name), nil otherwise.
|
|
107
|
-
# @return [Entry, nil]
|
|
108
|
-
def left_out(name, layers: [])
|
|
109
|
-
entry = self[name]
|
|
110
|
-
entry if entry && left_out?(entry, layers, @toolkit)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
132
|
# The tools +toolkit+ (the session's by default) leaves out of a turn
|
|
114
133
|
# under +layers+. The tool index's own aren't, unless it removes them:
|
|
115
134
|
# they are declared when there is something to reach.
|
|
@@ -118,14 +137,6 @@ module Samagotchi
|
|
|
118
137
|
ordered(@entries.values.select { |entry| left_out?(entry, layers, toolkit) }).map(&:name)
|
|
119
138
|
end
|
|
120
139
|
|
|
121
|
-
# The tool +name+ names (a built-in or a plugin's) when the session's
|
|
122
|
-
# toolkit leaves it out but the tool index reaches it (#reachable_names).
|
|
123
|
-
# @return [Entry, nil]
|
|
124
|
-
def indexed(name, layers: [], toolkit: @toolkit)
|
|
125
|
-
entry = self[name]
|
|
126
|
-
entry if entry && call_offered?(toolkit) && soft?(entry, layers, toolkit)
|
|
127
|
-
end
|
|
128
|
-
|
|
129
140
|
# The tools +toolkit+ leaves out of a turn under +layers+ that the tool
|
|
130
141
|
# index reaches (call_tool), built-ins and plugin tools alike: not in
|
|
131
142
|
# its kit's list, but not removed either (remove:, --no-tool, /toolkit
|
|
@@ -184,14 +195,23 @@ module Samagotchi
|
|
|
184
195
|
ordered(@entries.values.select { |entry| entry.offered?(layers) && declared?(entry, toolkit) })
|
|
185
196
|
end
|
|
186
197
|
|
|
187
|
-
# @return [Array<Hash>] the schemas, in declaration order
|
|
188
|
-
def schemas(layers: []) = entries(layers: layers).map(&:schema)
|
|
189
|
-
|
|
190
198
|
def freeze
|
|
191
199
|
@entries.freeze
|
|
192
200
|
super
|
|
193
201
|
end
|
|
194
202
|
|
|
203
|
+
# A frozen copy of its entry set, with its toolkit, reaching_kit and
|
|
204
|
+
# index as they are now (ToolkitBinding#publish!, on the turn thread):
|
|
205
|
+
# registering or unregistering here leaves it as it was. Shallow: the
|
|
206
|
+
# Entry Structs are this Registry's own, their fields set in place on
|
|
207
|
+
# the turn thread (Plugin::ToolSpec.apply, ToolIndex#refresh!).
|
|
208
|
+
# @return [Registry]
|
|
209
|
+
def snapshot
|
|
210
|
+
copy = dup
|
|
211
|
+
copy.instance_variable_set(:@entries, @entries.dup)
|
|
212
|
+
copy.freeze
|
|
213
|
+
end
|
|
214
|
+
|
|
195
215
|
private
|
|
196
216
|
|
|
197
217
|
# Declared by +toolkit+ (nil: every tool, full). The tool index's
|
|
@@ -22,7 +22,7 @@ module Samagotchi
|
|
|
22
22
|
return "Error: this session's id is not known here" unless peers&.session_id
|
|
23
23
|
return "Error: give the target session's id (list_sessions shows them)" if session.to_s.strip.empty?
|
|
24
24
|
|
|
25
|
-
id = Session.
|
|
25
|
+
id = Session.resolve!(session.to_s.strip, state_dir: peers.state_dir)
|
|
26
26
|
Session.load(id, state_dir: peers.state_dir)
|
|
27
27
|
return "Error: #{id[0, 8]} is this session; send_note is for other sessions" if id == peers.session_id
|
|
28
28
|
|
|
@@ -33,12 +33,10 @@ module Samagotchi
|
|
|
33
33
|
|
|
34
34
|
where = result.status == :queued ? "its worker adds it before its next turn" : "it has no worker now, so it waits for its next start"
|
|
35
35
|
"Queued a note for session #{id[0, 8]}: #{where}. It does not start a turn there."
|
|
36
|
-
rescue Session::
|
|
36
|
+
rescue Session::NotFound => e
|
|
37
|
+
"Error: #{e.message} (list_sessions shows them)"
|
|
38
|
+
rescue ArgumentError => e # AmbiguousId, SessionInbox::NoteRejected, a file that won't load
|
|
37
39
|
"Error: #{e.message}"
|
|
38
|
-
rescue SessionInbox::NoteRejected => e
|
|
39
|
-
"Error: #{e.message}"
|
|
40
|
-
rescue ArgumentError
|
|
41
|
-
"Error: no session #{session.to_s.strip} (list_sessions shows them)"
|
|
42
40
|
end
|
|
43
41
|
end
|
|
44
42
|
end
|