samagotchi 0.112.0 → 0.114.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 +48 -1
- data/bin/chi +8 -0
- data/docs/cli.md +24 -6
- data/docs/configuration.md +22 -10
- data/docs/internals/prompt-caching.md +2 -1
- data/docs/internals/web-push.md +28 -4
- data/docs/sessions.md +3 -3
- data/lib/samagotchi/bootstrap_command.rb +70 -5
- data/lib/samagotchi/bundles/system/manifest.yml +1 -1
- data/lib/samagotchi/config.rb +24 -0
- data/lib/samagotchi/config_text_edit.rb +10 -3
- data/lib/samagotchi/gem_update.rb +5 -1
- data/lib/samagotchi/idle_recap.rb +38 -10
- data/lib/samagotchi/push_command.rb +188 -0
- data/lib/samagotchi/recap_store.rb +20 -3
- data/lib/samagotchi/recap_title.rb +78 -0
- data/lib/samagotchi/run_options.rb +1 -0
- data/lib/samagotchi/session_manager.rb +10 -3
- data/lib/samagotchi/sessions_command.rb +14 -11
- data/lib/samagotchi/title_command.rb +6 -1
- data/lib/samagotchi/version.rb +1 -1
- data/lib/samagotchi/web/app.rb +46 -3
- data/lib/samagotchi/web/markdown_renderer.rb +20 -0
- data/lib/samagotchi/web/public/app.js +6 -0
- data/lib/samagotchi/web/public/index.html +43 -4
- data/lib/samagotchi/web/public/markdown_tip.js +33 -0
- data/lib/samagotchi/web/public/notifications.js +22 -8
- data/lib/samagotchi/web/public/push_devices.js +187 -0
- data/lib/samagotchi/web/push/attention.rb +2 -1
- data/lib/samagotchi/web/push/store.rb +14 -0
- data/lib/samagotchi/web/push.rb +5 -0
- data/lib/samagotchi/web/push_routes.rb +17 -3
- data/lib/samagotchi/web/server.rb +46 -14
- data/lib/samagotchi/web/session_show.rb +2 -0
- data/lib/samagotchi/web/session_summary.rb +7 -2
- metadata +5 -1
|
@@ -130,7 +130,9 @@ module Samagotchi
|
|
|
130
130
|
annotate_presets: annotate_presets, editor: editor, lan: lan, working_set: working_set,
|
|
131
131
|
public_url: public_url }
|
|
132
132
|
started = if plan
|
|
133
|
-
with_tunnel(provider, plan)
|
|
133
|
+
with_tunnel(provider, plan) do |up|
|
|
134
|
+
start(**options, public_notes: provider.start_lines(plan), on_bound: up)
|
|
135
|
+
end
|
|
134
136
|
else
|
|
135
137
|
start(**options)
|
|
136
138
|
end
|
|
@@ -147,25 +149,43 @@ module Samagotchi
|
|
|
147
149
|
end
|
|
148
150
|
|
|
149
151
|
# The tunnel on while the block runs (the server), off after it
|
|
150
|
-
# whatever ends it (Ctrl-C, SIGTERM, SIGHUP,
|
|
151
|
-
#
|
|
152
|
-
#
|
|
152
|
+
# whatever ends it (Ctrl-C, SIGTERM, SIGHUP), once #up may have taken
|
|
153
|
+
# effect: a refusal before it turns off nothing (a live tunnel of
|
|
154
|
+
# another chi web stays). The block gets #up to call once the port is
|
|
155
|
+
# bound (start's on_bound), so Serve never forwards the tailnet to a
|
|
156
|
+
# listener that took the port first. A signal during #up waits for it
|
|
157
|
+
# (its command runs in its own process group, and Serve keeps what it
|
|
158
|
+
# set even if chi stopped waiting), so it can't land between the serve
|
|
159
|
+
# going on and the teardown being due; #up is bounded by its timeout.
|
|
153
160
|
def self.with_tunnel(provider, plan)
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
161
|
+
attempted = false
|
|
162
|
+
yield(lambda do
|
|
163
|
+
Thread.handle_interrupt(SignalException => :never) do
|
|
164
|
+
attempted = true
|
|
165
|
+
provider.up(plan)
|
|
166
|
+
end
|
|
167
|
+
end)
|
|
157
168
|
ensure
|
|
158
|
-
tunnel_down(provider, plan) if
|
|
169
|
+
tunnel_down(provider, plan) if attempted
|
|
159
170
|
end
|
|
160
171
|
|
|
161
172
|
# The tunnel's teardown, before any line (a hung-up terminal can't
|
|
162
173
|
# write): a failure is one warning line, never a crash or another exit
|
|
163
|
-
# status
|
|
174
|
+
# status. A second Ctrl-C (SIGTERM, SIGHUP) during it waits for it
|
|
175
|
+
# (bounded by its commands' timeouts) and is then dropped: the run
|
|
176
|
+
# already ends the way the first signal ends it.
|
|
164
177
|
def self.tunnel_down(provider, plan)
|
|
165
|
-
line =
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
178
|
+
line = nil
|
|
179
|
+
begin
|
|
180
|
+
Thread.handle_interrupt(SignalException => :never) do
|
|
181
|
+
line = begin
|
|
182
|
+
provider.down_line(plan, provider.down(plan))
|
|
183
|
+
rescue Tunnel::Refused => e
|
|
184
|
+
provider.down_warning(plan, e)
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
rescue SignalException
|
|
188
|
+
nil
|
|
169
189
|
end
|
|
170
190
|
say(line) if line
|
|
171
191
|
end
|
|
@@ -187,11 +207,14 @@ module Samagotchi
|
|
|
187
207
|
# (web.public_url, or --tunnel's): every request needs the access token
|
|
188
208
|
# @param public_notes [Array<String>] lines after the proxied link's
|
|
189
209
|
# (the tunnel's)
|
|
210
|
+
# @param on_bound [#call, nil] run once the port is bound, before any
|
|
211
|
+
# line (the tunnel's #up); what it raises ends the run
|
|
190
212
|
# @return [Boolean] false when the port was taken (said so on stderr)
|
|
191
213
|
def self.start(port: nil, host: nil, url: nil, open_browser: false, state_dir: nil, manager: nil, markdown: false,
|
|
192
214
|
view: Config::BY_KEY["web.view"].default, annotate_presets: Config::BY_KEY["web.annotate_presets"].default, hub: nil, lan: nil,
|
|
193
215
|
editor: Config::BY_KEY["web.editor"].default, token_path: Token.path,
|
|
194
|
-
working_set: Config::BY_KEY["web.working_set"].default, public_url: nil, public_notes: []
|
|
216
|
+
working_set: Config::BY_KEY["web.working_set"].default, public_url: nil, public_notes: [],
|
|
217
|
+
on_bound: nil)
|
|
195
218
|
config_restart_unsubscribe = ConfigFile.watch_restart_settings!(process: :web) do |message|
|
|
196
219
|
Samagotchi::Log.warn(:config, "restart_required", echo: "Warning: config: #{message}")
|
|
197
220
|
end
|
|
@@ -227,7 +250,11 @@ module Samagotchi
|
|
|
227
250
|
# Said once the port is bound: a second chi web racing for it gets
|
|
228
251
|
# the in-use line instead.
|
|
229
252
|
running_path = Running.path(state_dir: state_dir)
|
|
253
|
+
webrick = nil
|
|
254
|
+
callback_unfinished = false
|
|
230
255
|
started = lambda do
|
|
256
|
+
callback_unfinished = true
|
|
257
|
+
on_bound&.call
|
|
231
258
|
record_running(running_path, port, public_url)
|
|
232
259
|
puts "Chi Web on #{url} (public: #{File.expand_path("public", __dir__)})"
|
|
233
260
|
puts lan_lines(ip: lan.ip, port: port, token: Token.read(token_path), others: lan.others, public: lan.public) if lan
|
|
@@ -244,12 +271,14 @@ module Samagotchi
|
|
|
244
271
|
open_url(open_target)
|
|
245
272
|
end
|
|
246
273
|
end
|
|
274
|
+
callback_unfinished = false
|
|
247
275
|
end
|
|
248
276
|
|
|
249
277
|
# The event loops (GET /api/events) end once WEBrick leaves
|
|
250
278
|
# :Running: it joins every request thread before run returns.
|
|
251
279
|
Rackup::Handler::WEBrick.run(app, Host: host, Port: port, AccessLog: [], Logger: Log.new($stderr, WEBrick::Log::WARN),
|
|
252
280
|
StartCallback: started) do |server|
|
|
281
|
+
webrick = server
|
|
253
282
|
app.server_running = -> { server.status == :Running }
|
|
254
283
|
listen_lan(server, lan, port) if lan
|
|
255
284
|
end
|
|
@@ -261,6 +290,9 @@ module Samagotchi
|
|
|
261
290
|
warn "Error: can't listen on #{lan.ip}:#{port} (#{e.message}); did the address change? Run chi web again"
|
|
262
291
|
false
|
|
263
292
|
ensure
|
|
293
|
+
# A start callback that raised (on_bound's refusal, a Ctrl-C) leaves
|
|
294
|
+
# WEBrick :Running with its sockets open.
|
|
295
|
+
webrick&.listeners&.each { |socket| socket.close unless socket.closed? } if callback_unfinished
|
|
264
296
|
Running.clear(path: running_path) if running_path
|
|
265
297
|
config_restart_unsubscribe&.call
|
|
266
298
|
notifier&.stop
|
|
@@ -81,6 +81,7 @@ module Samagotchi
|
|
|
81
81
|
# names its plugins' too.
|
|
82
82
|
commands: turn_snapshot&.fetch("commands", nil) || SessionCommands.builtin_registry.listing,
|
|
83
83
|
markdown_warning: @markdown_renderer.warning,
|
|
84
|
+
markdown_tip: @markdown_renderer.tip,
|
|
84
85
|
**viewer_capabilities(req),
|
|
85
86
|
pending_question: pending,
|
|
86
87
|
last_event_seq: last_event_seq,
|
|
@@ -208,6 +209,7 @@ module Samagotchi
|
|
|
208
209
|
session: session_json,
|
|
209
210
|
messages: messages,
|
|
210
211
|
markdown_warning: @markdown_renderer.warning,
|
|
212
|
+
markdown_tip: @markdown_renderer.tip,
|
|
211
213
|
**viewer_capabilities(req),
|
|
212
214
|
timing: timing
|
|
213
215
|
})
|
|
@@ -40,6 +40,7 @@ module Samagotchi
|
|
|
40
40
|
up = bridge_up?(session_dir, owner)
|
|
41
41
|
sidecar = up ? WorkerSidecar.read(session_dir) : nil
|
|
42
42
|
saved = SessionMetrics.saved_summary(session_dir, budget_tokens: budget_resolver(session, registry))
|
|
43
|
+
recap_card = RecapStore.card(session_dir)
|
|
43
44
|
{
|
|
44
45
|
id: session.id,
|
|
45
46
|
status: status,
|
|
@@ -74,8 +75,12 @@ module Samagotchi
|
|
|
74
75
|
# place of the first message.
|
|
75
76
|
title: session.title,
|
|
76
77
|
owner: owner&.kind,
|
|
77
|
-
# The saved recap's first sentence, for the session card
|
|
78
|
-
|
|
78
|
+
# The saved recap's first sentence, for the session card, and the
|
|
79
|
+
# auto title its reply led with (RecapTitle), else nil: an untitled
|
|
80
|
+
# session's name on the pages and its pushes (never in a model
|
|
81
|
+
# request).
|
|
82
|
+
recap: recap_card.preview,
|
|
83
|
+
auto_title: recap_card.title,
|
|
79
84
|
# How full the context was after the last turn (%), or nil, and
|
|
80
85
|
# the session's token sums and cost (the card's ctx tooltip), from
|
|
81
86
|
# one read of analytics.json.
|
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.114.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dmitry Dedov
|
|
@@ -503,6 +503,7 @@ files:
|
|
|
503
503
|
- lib/samagotchi/prompt_note.rb
|
|
504
504
|
- lib/samagotchi/prompt_warmup.rb
|
|
505
505
|
- lib/samagotchi/proxy_trace.rb
|
|
506
|
+
- lib/samagotchi/push_command.rb
|
|
506
507
|
- lib/samagotchi/question_answer.rb
|
|
507
508
|
- lib/samagotchi/question_asked.rb
|
|
508
509
|
- lib/samagotchi/question_desk.rb
|
|
@@ -512,6 +513,7 @@ files:
|
|
|
512
513
|
- lib/samagotchi/recap_command.rb
|
|
513
514
|
- lib/samagotchi/recap_setup.rb
|
|
514
515
|
- lib/samagotchi/recap_store.rb
|
|
516
|
+
- lib/samagotchi/recap_title.rb
|
|
515
517
|
- lib/samagotchi/redacted_inspect.rb
|
|
516
518
|
- lib/samagotchi/ref.rb
|
|
517
519
|
- lib/samagotchi/relay.rb
|
|
@@ -767,6 +769,7 @@ files:
|
|
|
767
769
|
- lib/samagotchi/web/public/llm_context_chip.js
|
|
768
770
|
- lib/samagotchi/web/public/manifest.webmanifest
|
|
769
771
|
- lib/samagotchi/web/public/markdown_place.js
|
|
772
|
+
- lib/samagotchi/web/public/markdown_tip.js
|
|
770
773
|
- lib/samagotchi/web/public/model_pick.js
|
|
771
774
|
- lib/samagotchi/web/public/model_picker.js
|
|
772
775
|
- lib/samagotchi/web/public/notice_links.js
|
|
@@ -780,6 +783,7 @@ files:
|
|
|
780
783
|
- lib/samagotchi/web/public/plain_line.js
|
|
781
784
|
- lib/samagotchi/web/public/prompt_history.js
|
|
782
785
|
- lib/samagotchi/web/public/push.js
|
|
786
|
+
- lib/samagotchi/web/public/push_devices.js
|
|
783
787
|
- lib/samagotchi/web/public/question_card.js
|
|
784
788
|
- lib/samagotchi/web/public/question_cards.js
|
|
785
789
|
- lib/samagotchi/web/public/read_view.js
|