@mono-agent/web 0.20.14 → 0.21.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.
- package/README.md +388 -70
- package/dist/contracts.d.ts +364 -8
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +2 -0
- package/dist/contracts.js.map +1 -1
- package/dist/cron-reply-context.d.ts +27 -0
- package/dist/cron-reply-context.d.ts.map +1 -0
- package/dist/cron-reply-context.js +241 -0
- package/dist/cron-reply-context.js.map +1 -0
- package/dist/discovery.d.ts +1 -0
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +8 -6
- package/dist/discovery.js.map +1 -1
- package/dist/effort-ladder.d.ts +14 -0
- package/dist/effort-ladder.d.ts.map +1 -1
- package/dist/effort-ladder.js +41 -0
- package/dist/effort-ladder.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/long-lived-fetch.d.ts +5 -0
- package/dist/long-lived-fetch.d.ts.map +1 -0
- package/dist/long-lived-fetch.js +22 -0
- package/dist/long-lived-fetch.js.map +1 -0
- package/dist/monitor-reply.d.ts +10 -0
- package/dist/monitor-reply.d.ts.map +1 -0
- package/dist/monitor-reply.js +67 -0
- package/dist/monitor-reply.js.map +1 -0
- package/dist/notification-client.d.ts.map +1 -1
- package/dist/notification-client.js +5 -4
- package/dist/notification-client.js.map +1 -1
- package/dist/operator-client.d.ts +25 -1
- package/dist/operator-client.d.ts.map +1 -1
- package/dist/operator-client.js +167 -8
- package/dist/operator-client.js.map +1 -1
- package/dist/server.d.ts +42 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +627 -49
- package/dist/server.js.map +1 -1
- package/dist/service.d.ts +201 -8
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +1425 -136
- package/dist/service.js.map +1 -1
- package/dist/store-migrations.d.ts +23 -0
- package/dist/store-migrations.d.ts.map +1 -0
- package/dist/store-migrations.js +212 -0
- package/dist/store-migrations.js.map +1 -0
- package/dist/store.d.ts +294 -17
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +1637 -263
- package/dist/store.js.map +1 -1
- package/package.json +8 -5
- package/webapp/dist/assets/{assistant-ui-BzN2E6n6.js → assistant-ui-pZmGxIp2.js} +16 -16
- package/webapp/dist/assets/index-6uQ7TVQe.css +1 -0
- package/webapp/dist/assets/index-CsSMjSgW.js +156 -0
- package/webapp/dist/assets/{markdown-Vq23xgh7.js → markdown-Du5t10ja.js} +1 -1
- package/webapp/dist/badge-96.png +0 -0
- package/webapp/dist/index.html +26 -6
- package/webapp/dist/manifest.webmanifest +1 -1
- package/webapp/dist/notification-sw.js +3 -1
- package/webapp/dist/sw.js +1 -1
- package/webapp/dist/{workbox-9c191d2f.js → workbox-2fbc6a65.js} +1 -1
- package/webapp/dist/assets/index-C4a2Dv1W.js +0 -155
- package/webapp/dist/assets/index-mhMBLGB0.css +0 -1
package/README.md
CHANGED
|
@@ -24,6 +24,15 @@ Catalog responsibility: Serves the always-on browser operator console for persis
|
|
|
24
24
|
- Persist agents, threads, messages, structured reasoning/tool/telemetry parts,
|
|
25
25
|
revisions, turns, attachments, and agent pin preferences under
|
|
26
26
|
`~/.mono-agent/web`.
|
|
27
|
+
- Persist optional per-agent model/effort defaults for new interactive web
|
|
28
|
+
threads, copied at creation and clearable back to resolved config.
|
|
29
|
+
- Preserve each turn's requested, attempted, and answering route plus the Pi
|
|
30
|
+
wrapper's effective thinking level, and project bounded fallback/retry
|
|
31
|
+
attribution without exposing raw provider diagnostics.
|
|
32
|
+
- Proxy ephemeral, exact-origin provider-auth status and login sessions to the
|
|
33
|
+
currently connected capability-advertising agent without storing credentials,
|
|
34
|
+
prompt input, or session projections. The client omits authorization for an
|
|
35
|
+
agent with no operator API key and sends the discovered bearer when one exists.
|
|
27
36
|
- Let an MCP-capable agent replace the interim first-message title with a short
|
|
28
37
|
semantic title and evolve it after a material topic shift, while treating any
|
|
29
38
|
user rename as a permanent lock.
|
|
@@ -31,7 +40,20 @@ Catalog responsibility: Serves the always-on browser operator console for persis
|
|
|
31
40
|
opaque-artifact metadata carried by structured agent stream events; web
|
|
32
41
|
SQLite remains a client cache, not the canonical lifecycle store.
|
|
33
42
|
- Keep an upstream turn running when a browser reloads or disconnects, and expose
|
|
34
|
-
|
|
43
|
+
content deltas plus rate-limited change hints over SSE so any connected browser
|
|
44
|
+
can catch up without reloading what it already holds.
|
|
45
|
+
- Project foreground outcomes and retained background-job activity into conversation
|
|
46
|
+
rows. Current work and failures take priority over reply previews, including for
|
|
47
|
+
closed conversations and job cards outside the loaded message page.
|
|
48
|
+
Silent assistant-only host wakes retain the previous meaningful outcome for
|
|
49
|
+
this priority, without changing their actual run status or completion time.
|
|
50
|
+
The optional `runState.lastOutcome` is derived from retained user-message
|
|
51
|
+
provenance and visible reply content; `null` means no prior outcome, while
|
|
52
|
+
absent metadata preserves compatibility with older cached summaries.
|
|
53
|
+
- Shape projected transcripts at the service boundary — drop non-allowlisted
|
|
54
|
+
telemetry payloads, and preview oversized tool arguments/results with their
|
|
55
|
+
byte count and a digest — while serving the whole part from message-bound
|
|
56
|
+
routes and honoring `?full=1` as the unshaped escape hatch.
|
|
35
57
|
- Offer plain-text follow-ups to a capable active provider run, persist their
|
|
36
58
|
pending/applied/queued state, and promote safe fallbacks into normal turns.
|
|
37
59
|
- Render a running agent's structured `AskUser` interaction by exact
|
|
@@ -52,17 +74,43 @@ Catalog responsibility: Serves the always-on browser operator console for persis
|
|
|
52
74
|
channel per `(sourceId, jobId)` and reconcile all run states from the agent.
|
|
53
75
|
- Accept exact-source/thread process-job notifications through the same private
|
|
54
76
|
ingress, update one durable job card in place without a verbatim-history
|
|
55
|
-
append, and
|
|
56
|
-
operator capability.
|
|
77
|
+
append, and poll its bounded redacted live output tail through the agent's
|
|
78
|
+
independent owner operator capability without persisting each output chunk.
|
|
79
|
+
The browser collects cards from the loaded message window in one
|
|
80
|
+
conversation-level stack after the transcript. Queued, starting, and running
|
|
81
|
+
cards stay visible by default; terminal cards remain mounted behind
|
|
82
|
+
expandable history so status counts and live transitions stay current.
|
|
83
|
+
When a loaded launching `Exec`/`Bash` call has its exact persisted machine
|
|
84
|
+
receipt, that response's Activity also shows its actual start row. The
|
|
85
|
+
terminal row appears where the exact wake was consumed: at the steered point
|
|
86
|
+
in an active response or first in a follow-up response. If no retained wake
|
|
87
|
+
marker exists, the terminal row falls back beside the launch. These rows
|
|
88
|
+
never poll or duplicate card output; legacy or paginated-out launch receipts
|
|
89
|
+
remain stack-only.
|
|
57
90
|
- Accept exact-source/thread Monitor wakes through that private ingress, steer
|
|
58
91
|
them into the active run or serialize one assistant-only follow-up, retain
|
|
59
92
|
delivery identity plus a payload hash for fail-closed duplicate handling, and
|
|
60
|
-
group their secret-free projections into
|
|
61
|
-
|
|
62
|
-
|
|
93
|
+
group their secret-free projections into compact Monitor activity. The
|
|
94
|
+
browser presents adjacent activity-only follow-ups for the same watch as one
|
|
95
|
+
continuous Activity block; a visible reply or unrelated message ends that
|
|
96
|
+
block. Raw event text and delivery keys never reach the rendered row; Monitor
|
|
97
|
+
wakes have no browser-side stop control. For a verified Monitor wake, a
|
|
98
|
+
terminal no-op assistant message is suppressed while an earlier meaningful
|
|
99
|
+
answer and rich content remain visible. Push delivery waits for an outstanding
|
|
100
|
+
steering receipt and uses the normalized reply. Monitor callbacks use the
|
|
101
|
+
independent owner credential derived from the advertised private state directory.
|
|
63
102
|
|
|
64
103
|
## Install / Usage
|
|
65
104
|
|
|
105
|
+
Process-job completion replies suppress only an exact sentinel-only terminal
|
|
106
|
+
message with a verified wake association; narration and rich replies remain
|
|
107
|
+
visible. Silent replies create no response push. A web wake receipt confirms
|
|
108
|
+
that steering was applied or that the agent accepted the exact follow-up turn
|
|
109
|
+
request, which is also when the wake's host-owned chain depth and background
|
|
110
|
+
starts bind to it; the turn's later model outcome remains separate. Job cards
|
|
111
|
+
distinguish an unknown pre-confirmation receipt from failure and explain that
|
|
112
|
+
replay was suppressed.
|
|
113
|
+
|
|
66
114
|
`@mono-agent/agent-app` provides the normal managed-service lifecycle:
|
|
67
115
|
|
|
68
116
|
```bash
|
|
@@ -71,12 +119,21 @@ mono-agent web status
|
|
|
71
119
|
mono-agent web
|
|
72
120
|
```
|
|
73
121
|
|
|
122
|
+
The server and the webapp ship as one artifact — this package serves the bundle
|
|
123
|
+
built beside it — so `mono-agent web restart` re-stages both and they always
|
|
124
|
+
upgrade together. A console build older than the bootstrap and delta protocol
|
|
125
|
+
below cannot read this server, and an installed PWA picks up a new build only
|
|
126
|
+
when its staged service worker is applied.
|
|
127
|
+
|
|
74
128
|
Bare `mono-agent web` reports status and usable URLs; it does not implicitly
|
|
75
129
|
start or mutate the service. Use `mono-agent web run` for a foreground process
|
|
76
130
|
or `--loopback` to bind only `127.0.0.1`. The curated `--theme` values are
|
|
77
|
-
`evergreen` (default), `ocean`, `plum`, and `terracotta`.
|
|
78
|
-
the
|
|
79
|
-
|
|
131
|
+
`evergreen` (default), `ocean`, `plum`, and `terracotta`. `--name <label>` sets
|
|
132
|
+
the console label used for the installed PWA name/short name, browser title, and
|
|
133
|
+
rail brand, defaulting to the machine hostname. Managed starts persist both
|
|
134
|
+
selections, restarts retain them unless explicitly replaced, `--name -` clears
|
|
135
|
+
the stored label back to the hostname default, and `web status` reports the
|
|
136
|
+
effective values.
|
|
80
137
|
|
|
81
138
|
Install this package directly only when embedding the server in another host:
|
|
82
139
|
|
|
@@ -97,13 +154,14 @@ who can reach port 5050 can inspect conversations and operate discovered agents;
|
|
|
97
154
|
use host firewall/LAN policy and Tailscale ACLs as the access boundary. The
|
|
98
155
|
server emits no CORS permission and rejects cross-origin mutations.
|
|
99
156
|
|
|
100
|
-
The service
|
|
101
|
-
|
|
102
|
-
header,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
157
|
+
The service uses the operating-system hostname as its machine identity and as
|
|
158
|
+
the default display name. An operator-selected `name` replaces that default in
|
|
159
|
+
the desktop/mobile header, browser title, and installed PWA name while the
|
|
160
|
+
hostname continues to key browser cache ownership. The selected theme changes
|
|
161
|
+
shell and accent colors while keeping content, status, warning, and danger
|
|
162
|
+
semantics consistent across hosts. The generated PWA manifest remains
|
|
163
|
+
network-fetched rather than service-worker-cached so its console identity cannot
|
|
164
|
+
be masked by a generic build-time manifest.
|
|
107
165
|
|
|
108
166
|
Private IP literals, localhost, the machine hostname, and its exact `.local`
|
|
109
167
|
name are accepted as browser hosts. Set `MONO_AGENT_WEB_ALLOWED_HOSTS` to a
|
|
@@ -114,18 +172,47 @@ managed agent protects its loopback operator endpoint, discovery reads only
|
|
|
114
172
|
|
|
115
173
|
On desktop, the agent rail has fixed compact and expanded layouts selected by
|
|
116
174
|
an explicit expand/collapse control. That choice is remembered by the browser.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
the
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
175
|
+
On narrow touch screens, a deliberate right swipe across the unoccupied chat
|
|
176
|
+
surface or ordinary unselected transcript text opens the conversation drawer.
|
|
177
|
+
A left swipe across either open navigation drawer closes it. Controls, active
|
|
178
|
+
text selections, inputs, and any native horizontal scroller keep their normal
|
|
179
|
+
touch behavior; short drags and vertically dominant scrolling do not trigger
|
|
180
|
+
navigation. The two header navigation controls remain available as 44-pixel
|
|
181
|
+
touch targets.
|
|
182
|
+
Offline agents that remain in the current discovery result are hidden behind a
|
|
183
|
+
subtle count by default; pinned agents and the currently selected agent remain
|
|
184
|
+
visible even while offline. An agent omitted by a successful discovery refresh
|
|
185
|
+
is removed from every picker and from that count regardless of its prior pin or
|
|
186
|
+
selection. Its rows, conversations, and pin stay retained in SQLite and return
|
|
187
|
+
if the same source id is discovered again. The same filter applies to the
|
|
188
|
+
desktop rail, mobile picker, and command palette. Pin or unpin with the star
|
|
189
|
+
control; pins live in the web service so favorites stay consistent over
|
|
190
|
+
localhost, LAN, and Tailscale.
|
|
191
|
+
|
|
192
|
+
The single-row mobile header keeps navigation, title, notifications, and a
|
|
193
|
+
conversation actions menu together. Run settings sit beside **Send** in the
|
|
194
|
+
composer, where the compact trigger shows only the resolved model and effort.
|
|
195
|
+
Its popover combines searchable model selection with the selected model's
|
|
196
|
+
supported reasoning-effort choices and becomes a viewport-safe bottom sheet on
|
|
197
|
+
narrow screens. Model rows use the configured
|
|
198
|
+
display name when present and otherwise use the running agent's catalog name.
|
|
199
|
+
Choosing a model applies it immediately while keeping the popover open for an
|
|
200
|
+
effort choice; the explicit **Close** action finishes the interaction.
|
|
201
|
+
Pointer/touch opening and model or effort changes do not focus the search input;
|
|
202
|
+
keyboard opening retains search navigation. Local LM Studio and Ollama models
|
|
203
|
+
confirmed as embedding-only by native metadata are omitted from chat choices.
|
|
204
|
+
Unknown metadata preserves compatibility; model names are not used as a heuristic.
|
|
205
|
+
A persisted catalog-only selection stays visible by its canonical reference when
|
|
206
|
+
lazy provider metadata is absent, fails, or omits that model. While no metadata
|
|
207
|
+
describes that model at all, its current effort and the shared compatibility
|
|
208
|
+
ladder the agent accepts remain controllable, without reverting to the agent
|
|
209
|
+
default; once exact metadata loads it supplies the catalog display name and the
|
|
210
|
+
advertised ladder, which may narrow, keep, or remove those choices. Exact choices
|
|
211
|
+
come from the running agent's startup capability snapshot. Silence about a model
|
|
212
|
+
is not a claim and keeps the compatibility ladder, but metadata that marks a
|
|
213
|
+
model as reasoning-capable without enumerating its levels hides the effort
|
|
214
|
+
control entirely, default row included, rather than guessing cloud grades.
|
|
215
|
+
Usage telemetry remains internal
|
|
129
216
|
and is summarized through a context display that keeps exact Pi, Codex,
|
|
130
217
|
OpenCode, and ACP provider-request snapshots separate from last-turn processed
|
|
131
218
|
tokens and conversation cost. Running turns are labeled `Updating`; failed
|
|
@@ -133,9 +220,68 @@ turns and model changes are `Last measured`. A running or successful compaction
|
|
|
133
220
|
suppresses the older number until the next exact snapshot, while legacy and
|
|
134
221
|
unsupported-runtime threads show `Context —` instead of deriving a percentage
|
|
135
222
|
from aggregate work.
|
|
136
|
-
Structured reasoning, routine tools,
|
|
137
|
-
share the stream-aware Activity disclosure,
|
|
138
|
-
message state without reordering answer
|
|
223
|
+
Structured reasoning, routine tools, process-job lifecycle evidence, and one
|
|
224
|
+
update-in-place row per compaction share the stream-aware Activity disclosure,
|
|
225
|
+
which collapses at every terminal message state without reordering answer
|
|
226
|
+
parts. Receipt-bearing job launches keep their start row beside the exact
|
|
227
|
+
launch call. Their terminal row follows the consumed wake chronologically, with
|
|
228
|
+
launch-adjacent placement only as a fallback when no wake marker was retained;
|
|
229
|
+
ordinary adjacent same-tool calls retain their existing clustering.
|
|
230
|
+
|
|
231
|
+
The picker is labelled **Next turn**. The conversation header carries no run
|
|
232
|
+
attribution. Below an assistant message, a normal route marker appears only when
|
|
233
|
+
the model that ran differs from the conversation's current selection. A fallback
|
|
234
|
+
warning always appears there, even when its answering model matches the current
|
|
235
|
+
selection, and names requested and answering models plus the classified reason
|
|
236
|
+
when the runtime supplied one. Expanding the marker shows the bounded route
|
|
237
|
+
chain, same-model retries, route-level effort, and Pi's actual effective thinking
|
|
238
|
+
level. Configured subagents keep independent attribution in their own Activity
|
|
239
|
+
row. The browser never infers a fallback from selector state, and the
|
|
240
|
+
route-attribution payload never carries raw provider errors or request identifiers.
|
|
241
|
+
|
|
242
|
+
The agent rail's settings action opens a separate **Agent settings** dialog.
|
|
243
|
+
Its model and effort choices become the defaults for subsequently created web
|
|
244
|
+
console conversations for that agent. Either field may inherit resolved config,
|
|
245
|
+
and **Revert to config** clears both overrides in one action. These settings live
|
|
246
|
+
in the web service's SQLite database, survive restart, and do not edit
|
|
247
|
+
`mono-agent.config.json`; existing conversations and Telegram, Slack, cron,
|
|
248
|
+
webhook, API, and TUI requests remain unchanged.
|
|
249
|
+
|
|
250
|
+
The same dialog shows **Provider authentication** when the current agent
|
|
251
|
+
advertises provider-auth v1. It renders only the host-returned providers used by
|
|
252
|
+
effective routes, distinguishing detected credentials from live-request
|
|
253
|
+
verification: **OK** requires a retained real success, while static presence is
|
|
254
|
+
**Not verified**. A normal-size neutral Authenticate/Re-authenticate button stays
|
|
255
|
+
available for every supported login method regardless of the row state. Agents
|
|
256
|
+
advertising the additive checks capability also show one section-level **Run
|
|
257
|
+
check** button; it checks only the displayed providers, reports partial fixed
|
|
258
|
+
outcomes inline, and never runs on settings reads or polling. GitHub Copilot and
|
|
259
|
+
OpenAI Codex expose Pi device-code flows;
|
|
260
|
+
Anthropic accepts the final redirect URL/code; API-key providers use masked
|
|
261
|
+
provider-owned prompts. Re-authentication remains available during an active
|
|
262
|
+
login: a valid choice replaces it, while the compact flow stays visible until
|
|
263
|
+
the fresh session arrives. Stale start, poll, input, and cancel responses cannot
|
|
264
|
+
restore the old session. Polling continues through identical active snapshots;
|
|
265
|
+
an expired retained session releases the local running control, while transient
|
|
266
|
+
read failures remain retryable. A replacement whose prior credential transaction
|
|
267
|
+
cannot drain safely within two seconds reports `replacement_timeout`. Secret
|
|
268
|
+
input is cleared before submission. The web
|
|
269
|
+
server requires exact origin, proxies through the agent's ordinary operator
|
|
270
|
+
connection, marks responses no-store, and never reads the Pi auth path. The
|
|
271
|
+
operator request is keyless when that agent has no API key and uses its bearer
|
|
272
|
+
when it does. Auth state is component/agent memory only—not SQLite, thread
|
|
273
|
+
history, browser storage, or run artifacts. The console remains a
|
|
274
|
+
trusted-network single-user surface, not a per-human authenticated application.
|
|
275
|
+
|
|
276
|
+
Live checks are explicit side effects: each selected provider receives one tiny
|
|
277
|
+
no-fallback request, which may consume quota, trigger minimum billing, or refresh
|
|
278
|
+
OAuth. Check sessions and observations are process-local, expire from memory,
|
|
279
|
+
and are not persisted by the web service. They must be cancelled explicitly
|
|
280
|
+
before starting authentication.
|
|
281
|
+
|
|
282
|
+
Standalone process-job and Monitor revival turns in an existing web conversation
|
|
283
|
+
read that conversation's model/effort snapshot immediately before admission. A
|
|
284
|
+
wake steered into an active run stays on that run's already selected route.
|
|
139
285
|
|
|
140
286
|
New interactive threads initially use the first user message as their fallback
|
|
141
287
|
title. On compatible routes, an allowlisted app-owned `SetConversationTitle`
|
|
@@ -161,6 +307,8 @@ unavailable entries disabled with their status. Keyboard, pointer, and touch
|
|
|
161
307
|
selection only inserts the canonical `$skill-name` token at the caret; it never
|
|
162
308
|
sends the draft. Loading, stale, empty, unsupported, offline, and registry-error
|
|
163
309
|
states leave normal composition available.
|
|
310
|
+
The browse control uses a library icon, and touch opening leaves the search
|
|
311
|
+
unfocused so the software keyboard does not cover the viewport-safe sheet.
|
|
164
312
|
|
|
165
313
|
Select rendered message text to quote it into the composer. One quote is kept
|
|
166
314
|
with the authored user message and supplied to the operator as Markdown
|
|
@@ -168,18 +316,30 @@ blockquote context; it does not rewrite the visible message text. The public
|
|
|
168
316
|
turn DTO exposes this as `quote: { text, messageId }`, and the source message
|
|
169
317
|
must belong to the same thread.
|
|
170
318
|
|
|
171
|
-
The composer
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
319
|
+
The composer has one **Send** action whether the thread looks idle or running.
|
|
320
|
+
Button Send, desktop Enter, and **Control/Command + Shift + Enter** all submit
|
|
321
|
+
one immutable UUID-bearing payload; Shift+Enter and touch Enter remain newline.
|
|
322
|
+
The server, not browser run state, admits it as either a normal turn or targeted
|
|
323
|
+
live guidance for the exact active Web operation. There is no secondary Steer
|
|
324
|
+
button. With no active turn, the service starts exactly one normal turn using
|
|
325
|
+
the conversation route captured at admission.
|
|
326
|
+
|
|
327
|
+
The message shows `pending`, `applied`, `queued`, `cancelled`, or `uncertain`.
|
|
328
|
+
`applied` means exact owned-operation transcript consumption, not provider
|
|
329
|
+
receipt or answer adherence. Unsupported targeting or proved-safe removal
|
|
330
|
+
visibly queues one normal turn; a post-dispatch failure, end-of-turn race,
|
|
331
|
+
cancellation, or restart is permanently uncertain and is not retried
|
|
332
|
+
automatically. Active-turn attachments are rejected with
|
|
333
|
+
`active_attachments_unsupported` before upload ownership changes; the browser
|
|
334
|
+
restores the full text, structured quote, and staged files. The same payload may
|
|
335
|
+
be deliberately sent after the response finishes with a new submission id.
|
|
336
|
+
Cancelling the active turn also cancels its pending or queued live follow-ups.
|
|
337
|
+
Live follow-ups are capped at 8,000 characters and 100 unsettled messages per
|
|
338
|
+
thread.
|
|
339
|
+
|
|
340
|
+
Once exact consumption is host-confirmed, the assistant's Activity disclosure also
|
|
181
341
|
receives one completed `↪️ Steered: “<safe preview>”` tool row with result
|
|
182
|
-
`
|
|
342
|
+
`Consumed by current run`. The original follow-up remains the full human message;
|
|
183
343
|
the synthetic activity carries only a one-line, redacted, 40-code-point preview.
|
|
184
344
|
|
|
185
345
|
The header bell explicitly enables standards-based Web Push. Permission and
|
|
@@ -227,12 +387,40 @@ late or replayed delivery cannot recreate the channel. Bootstrap and paging are
|
|
|
227
387
|
bounded per source and archive state, with redirect-resolving thread fetches for selections
|
|
228
388
|
or mutations outside the current window.
|
|
229
389
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
390
|
+
The cron header is read-only: a quiet line shows human-language cadence and the
|
|
391
|
+
agent-authored next run in the viewer's local date/time, with the viewer timezone
|
|
392
|
+
available on the time label. Wall-clock cadence includes the scheduler timezone
|
|
393
|
+
(UTC by default); unsupported expressions retain normalized cron text and timezone.
|
|
394
|
+
Disabled or removed jobs say so. Missing, invalid, past, or offline/stale next-run
|
|
395
|
+
state says **Next run unavailable**. Configuration stays in files/config JSON;
|
|
396
|
+
the browser neither edits it nor computes a schedule.
|
|
397
|
+
|
|
398
|
+
Each visible terminal run keeps **Reply**, status, and local time in its compact
|
|
399
|
+
footer; secondary artifact, originating-session, activity, and truncation
|
|
400
|
+
diagnostics live under an accessible **Details** disclosure. Reply snapshots the
|
|
401
|
+
exact persisted result at activation—compact summary unless activity detail is
|
|
402
|
+
already loaded—and imports at most 32 KiB of explicitly marked untrusted
|
|
403
|
+
provenance/result into a separate normal conversation for the same agent. It
|
|
404
|
+
does not fetch hidden detail, rerun cron, invoke a provider, submit the empty
|
|
405
|
+
composer, include tools/files/config/neighbouring history, or continue the cron
|
|
406
|
+
session. The agent must positively advertise context-import v1 with a sufficient
|
|
407
|
+
byte limit. Unknown transport outcomes keep one operation for explicit Retry;
|
|
408
|
+
they are never replayed on startup. The page keeps unresolved identity in
|
|
409
|
+
memory even when bounded session persistence is unavailable, and temporary
|
|
410
|
+
offline/unsupported retry preflight does not discard it. A later deliberate
|
|
411
|
+
Reply after a definitive failure creates another operation and conversation.
|
|
412
|
+
The imported conversation renders that immutable snapshot as a compact card:
|
|
413
|
+
run provenance and status, Markdown result, optional failure/truncation notices,
|
|
414
|
+
and an accessible **Details** disclosure with exact raw JSON. This is read-time
|
|
415
|
+
presentation only. The two host-seeded rows, snapshot text and digest remain
|
|
416
|
+
unchanged in SQLite and in the agent's canonical history; unparseable or
|
|
417
|
+
non-v1 text remains ordinary text.
|
|
418
|
+
|
|
419
|
+
The web HTTP config-view, run-now, and effective-enabled proxies remain available
|
|
420
|
+
for operator clients. Mutations still require same-origin requests, source-qualified
|
|
421
|
+
routing, an operator API key, explicit agent-side opt-in, an idempotency key, and
|
|
422
|
+
agent-issued confirmation. Runtime enable state, run history, action audit, and
|
|
423
|
+
idempotency are agent-owned; web SQLite is a reconnect/refresh projection.
|
|
236
424
|
|
|
237
425
|
When the selected agent advertises `capabilities.askUser`, a running `AskUser`
|
|
238
426
|
tool call appears as one form containing all remaining questions. Each question
|
|
@@ -258,7 +446,21 @@ artifact availability, and explicit persistence failure. The browser never
|
|
|
258
446
|
reconstructs those outcomes from display text, run JSONL, or its own SQLite.
|
|
259
447
|
Historical content and artifact references remain untrusted; references expose
|
|
260
448
|
no host path and may later become unavailable when their independently retained
|
|
261
|
-
artifact is removed.
|
|
449
|
+
artifact is removed. An oversized argument or result reaches the card as a
|
|
450
|
+
preview carrying its full byte count and a digest of the body it was cut from;
|
|
451
|
+
expanding fetches the whole part from the message-bound tool-call route, and a
|
|
452
|
+
device-restored repair is accepted only when that digest still matches.
|
|
453
|
+
|
|
454
|
+
The console runs in a browser-local data mode — Auto, Lean, or Full — cycled
|
|
455
|
+
from the sidebar-footer indicator or the command palette, alongside a session
|
|
456
|
+
byte total and per-minute rate marked estimated whenever any component is not a
|
|
457
|
+
browser measurement. `Auto` reads the Network Information API and resolves to
|
|
458
|
+
Full where there is none (Safari, and so iOS), which is why an installed PWA is
|
|
459
|
+
offered Lean once. Lean loads pictures and MCP App documents on request, batches
|
|
460
|
+
delta paint to one second, halves page sizes and poll rates, and retains fewer
|
|
461
|
+
image blobs; polling pauses while the document is hidden. The preference keys
|
|
462
|
+
`mono-agent.web.data-mode` and `mono-agent.web.data-mode-suggested` are browser
|
|
463
|
+
storage, not configuration.
|
|
262
464
|
### Reply files and MCP Apps
|
|
263
465
|
|
|
264
466
|
Agents that advertise reply attachments expose message-bound downloads in the
|
|
@@ -276,7 +478,11 @@ message write and rejected if found in durable rich-part records.
|
|
|
276
478
|
|
|
277
479
|
The service mints exact-thread/message/part capabilities only while projecting
|
|
278
480
|
a browser DTO, with the existing ten-minute access TTL bounded by the part's
|
|
279
|
-
retention deadline
|
|
481
|
+
retention deadline and quantised down to a five-minute bucket, so a repeated
|
|
482
|
+
projection of the same message yields the same URL and its transcript stays
|
|
483
|
+
conditionally revalidatable. Content is served
|
|
484
|
+
`private, max-age=<remaining key life>, no-transform`; those bytes may therefore
|
|
485
|
+
survive in the browser's own private disk cache after the key expires. An authentic expired capability returns
|
|
280
486
|
`reply_access_expired`; forged, cross-thread, and unknown references keep the
|
|
281
487
|
generic not-found response. The PWA then asks the exact-origin access route to
|
|
282
488
|
re-project the authoritative retained part and retries an attachment, app
|
|
@@ -307,6 +513,33 @@ cross-resource requests fail. See
|
|
|
307
513
|
|
|
308
514
|
## Architecture
|
|
309
515
|
|
|
516
|
+
### Silent cron history
|
|
517
|
+
|
|
518
|
+
Successful empty answers and answers suppressed by `NOTHING_TO_REPORT` add no
|
|
519
|
+
visible conversation row. Failures, real output and completed notification
|
|
520
|
+
content remain visible. The console retains compact silent run history separately
|
|
521
|
+
from visible messages; each job keeps up to 500 visible and 500 suppressed run
|
|
522
|
+
projections. Paging, search, previews and message counts exclude suppressed rows.
|
|
523
|
+
|
|
524
|
+
Schema 19 marks existing definitely-silent projections without deleting their
|
|
525
|
+
messages, turns or delivery receipts. Ambiguous text truncated by an older agent
|
|
526
|
+
stays visible until authoritative evidence arrives. Cron transcript caches reset
|
|
527
|
+
when their authoritative revision advances, so previously loaded older pages may
|
|
528
|
+
need to be loaded again. Offline hydration also hides old synthetic-only silent
|
|
529
|
+
rows while preserving delivered text and rich replies.
|
|
530
|
+
|
|
531
|
+
### Storage migrations
|
|
532
|
+
|
|
533
|
+
`src/store-migrations.ts` owns the ordered, named migration registry; its last
|
|
534
|
+
step determines the supported SQLite schema version. Append a guarded step and
|
|
535
|
+
historical-layout preservation tests when changing storage. Never relabel a
|
|
536
|
+
shipped step: rebase before choosing a version, and append a repair if released
|
|
537
|
+
layouts collided. Bootstrap DDL and the upgrade transaction stay in `store.ts`.
|
|
538
|
+
Registry validation runs before bootstrap writes, and schema postconditions run
|
|
539
|
+
before the upgrade commits and on current-version opens. Step failures report
|
|
540
|
+
only the version/name, not stored content. A version stamp is not an execution
|
|
541
|
+
ledger; postconditions check the required effects.
|
|
542
|
+
|
|
310
543
|
### Data flow
|
|
311
544
|
|
|
312
545
|
1. `server.ts` accepts the versioned browser API, staged uploads, and SSE
|
|
@@ -316,35 +549,53 @@ cross-resource requests fail. See
|
|
|
316
549
|
Web Push subscription/event/delivery, notification, and cron projection
|
|
317
550
|
records through the SQLite store, and
|
|
318
551
|
drives each agent over its loopback operator endpoint.
|
|
319
|
-
3. Service mutations publish
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
552
|
+
3. Service mutations publish content deltas and change hints. A browser names
|
|
553
|
+
one conversation on `/api/v1/events` and receives that conversation's
|
|
554
|
+
`message.delta` frames in full; every other change arrives as a hint,
|
|
555
|
+
rate-limited to one per conversation per second, that it answers with an
|
|
556
|
+
`If-None-Match` read of exactly the projection it names — including the
|
|
557
|
+
selected agent's memory-only live skill registry. Responses are compressed
|
|
558
|
+
and carry per-route cache policy: immutable hashed assets, revalidated shell
|
|
559
|
+
and worker scripts, `private, no-cache` API reads, and immutable
|
|
560
|
+
content-addressed upload bytes. Reloads and concurrent tabs still do not own
|
|
561
|
+
or interrupt upstream turns.
|
|
323
562
|
4. The bundled assistant-ui webapp maps those DTOs—including canonical
|
|
324
563
|
lifecycle metadata—into its external store, thread list, messages, compact
|
|
325
564
|
Monitor activity, tool cards, composer, attachments, and push-subscription
|
|
326
|
-
UI
|
|
565
|
+
UI, keeping a per-conversation cache that is also written to the device
|
|
566
|
+
(IndexedDB `mono-agent-web`, version 2, swept per writer on hydration) so a
|
|
567
|
+
cold start draws before the first response. Its service worker precaches the
|
|
568
|
+
shell, handles background push delivery and same-origin clicks, and is
|
|
569
|
+
registered in `prompt` mode: a new build is staged and applied on the next
|
|
570
|
+
idle foreground moment or an explicit reload, never over a running turn or an
|
|
571
|
+
unsent draft.
|
|
327
572
|
5. `deliverWebNotification` reads the owner-private live ingress record and
|
|
328
573
|
performs one bearer-authenticated loopback delivery. Cron/webhook delivery
|
|
329
574
|
first appends the result to agent history, then atomically exposes an
|
|
330
575
|
idempotent assistant-only thread. A process-job delivery instead updates one
|
|
331
576
|
source/thread-bound durable card; its normal wake turn owns the single agent
|
|
332
|
-
history entry.
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
577
|
+
history entry. Its receipt returns once that exact follow-up is durably
|
|
578
|
+
admitted rather than waiting for model completion. A Monitor delivery is
|
|
579
|
+
steered into an active run or becomes an assistant-only follow-up in the exact
|
|
580
|
+
existing web thread; exact host-owned receipts update one compact, secret-free
|
|
581
|
+
activity row rather than creating repeated steering cards. The browser may be
|
|
582
|
+
closed, but the web service must remain running.
|
|
583
|
+
|
|
584
|
+
Monitor activity shows suppressed lines/batches and follow-up, steered, or
|
|
585
|
+
unknown wake dispositions. These are host delivery counts, not model-turn or
|
|
586
|
+
cost estimates. Historical v1 Monitor projections in SQLite and browser caches
|
|
587
|
+
remain readable alongside v2 projections.
|
|
337
588
|
|
|
338
589
|
### Package structure
|
|
339
590
|
|
|
340
591
|
| Source area | Responsibility |
|
|
341
592
|
| --- | --- |
|
|
342
|
-
| [`server.ts`](https://github.com/robertsreberski/mono-agent/blob/main/packages/web/src/server.ts) | HTTP service, `/api/v1` routes,
|
|
343
|
-
| [`service.ts`](https://github.com/robertsreberski/mono-agent/blob/main/packages/web/src/service.ts) | Application lifecycle for discovery, threads, turns, agent-authored automatic titles, live-input delivery/fallback, attachments, `AskUser` snapshots/submission, cancellation, notifications, and invalidation. |
|
|
593
|
+
| [`server.ts`](https://github.com/robertsreberski/mono-agent/blob/main/packages/web/src/server.ts) | HTTP service, `/api/v1` routes, hostname/display-name/theme bootstrap identity, per-console PWA manifest, uploads, SSE invalidations, host/origin checks, provider-auth no-store proxy routes, and static webapp serving. |
|
|
594
|
+
| [`service.ts`](https://github.com/robertsreberski/mono-agent/blob/main/packages/web/src/service.ts) | Application lifecycle for discovery, threads, turns, agent-authored automatic titles, live-input delivery/fallback, attachments, `AskUser` snapshots/submission, provider-auth connection-generation guarding, cancellation, notifications, and invalidation. |
|
|
344
595
|
| [`store.ts`](https://github.com/robertsreberski/mono-agent/blob/main/packages/web/src/store.ts) | Owner-private SQLite schema and transactional persistence, including race-safe automatic-title updates that never overwrite a user rename. |
|
|
345
|
-
| [`operator-client.ts`](https://github.com/robertsreberski/mono-agent/blob/main/packages/web/src/operator-client.ts) | Structured turn streaming, info/capabilities, live-input settlement, pending/submitted `AskUser`, cancellation, durable history append, and owner-authenticated process-job
|
|
596
|
+
| [`operator-client.ts`](https://github.com/robertsreberski/mono-agent/blob/main/packages/web/src/operator-client.ts) | Structured turn streaming, info/capabilities, live-input settlement, pending/submitted `AskUser`, cancellation, durable history append, conditionally bearer-authenticated provider-auth, and owner-authenticated process-job requests over the operator protocol. |
|
|
346
597
|
| [`notification-client.ts`](https://github.com/robertsreberski/mono-agent/blob/main/packages/web/src/notification-client.ts) and [`notification-ingress.ts`](https://github.com/robertsreberski/mono-agent/blob/main/packages/web/src/notification-ingress.ts) | Bounded, authenticated cron/webhook delivery, source/thread-bound process-job cards, and Monitor wake turns. |
|
|
347
|
-
| [`webapp/`](https://github.com/robertsreberski/mono-agent/tree/main/packages/web/webapp) | Isolated assistant-ui PWA, including compact Monitor activity, atomic `AskUser` forms, tests, and its own dependency lockfile. |
|
|
598
|
+
| [`webapp/`](https://github.com/robertsreberski/mono-agent/tree/main/packages/web/webapp) | Isolated assistant-ui PWA, including compact Monitor activity, the loaded conversation-level process-job stack and live tails, atomic `AskUser` forms, tests, and its own dependency lockfile. |
|
|
348
599
|
|
|
349
600
|
## Public API
|
|
350
601
|
|
|
@@ -359,7 +610,7 @@ cross-resource requests fail. See
|
|
|
359
610
|
| `discoverAcpBridgeAgents` | Discover Worklab-importable ACP sources through a credential-free, versioned ownership contract. |
|
|
360
611
|
| `discoverOperatorAgents` | Read trusted operator endpoints from trace-source manifests. |
|
|
361
612
|
| `WebBootstrap`, `WebThreadDetail`, `WebEvent`, and related `Web*` DTOs | Build another client against the versioned browser API. |
|
|
362
|
-
| `WEB_THEMES`, `DEFAULT_WEB_THEME`, `WebTheme`, and `WebConsoleIdentity` | Select a curated theme and consume the hostname/theme identity returned to browsers. |
|
|
613
|
+
| `WEB_THEMES`, `DEFAULT_WEB_THEME`, `WEB_CONSOLE_NAME_MAX_CHARACTERS`, `WebTheme`, and `WebConsoleIdentity` | Select a curated theme/name and consume the hostname/display-name/theme identity returned to browsers. |
|
|
363
614
|
|
|
364
615
|
<!-- public-api-inventory:start -->
|
|
365
616
|
<!-- Generated by scripts/generate-public-api-docs.mjs. Do not edit by hand. -->
|
|
@@ -376,6 +627,7 @@ ACP_PROTOCOL_VERSION
|
|
|
376
627
|
AcpBridgeDiscovery
|
|
377
628
|
AcpBridgeSourceDescriptor
|
|
378
629
|
AcpBridgeSourceHealth
|
|
630
|
+
CreateWebCronReplyInput
|
|
379
631
|
CreateWebThreadInput
|
|
380
632
|
CreateWebUploadInput
|
|
381
633
|
DEFAULT_WEB_HOST
|
|
@@ -398,11 +650,14 @@ OperatorTurnInput
|
|
|
398
650
|
OperatorTurnResult
|
|
399
651
|
PatchWebAgentInput
|
|
400
652
|
PatchWebThreadInput
|
|
653
|
+
PutWebAgentRunSettingsInput
|
|
401
654
|
SearchWebThreadsInput
|
|
402
655
|
StartWebLiveInputInput
|
|
403
656
|
StartWebServerOptions
|
|
657
|
+
StartWebSubmissionInput
|
|
404
658
|
StartWebTurnInput
|
|
405
659
|
WEB_API_VERSION
|
|
660
|
+
WEB_CONSOLE_NAME_MAX_CHARACTERS
|
|
406
661
|
WEB_MAX_ACTIVE_ATTACHMENT_TURN_BYTES
|
|
407
662
|
WEB_MAX_CONCURRENT_UPLOADS
|
|
408
663
|
WEB_MAX_FILES_PER_TURN
|
|
@@ -417,16 +672,25 @@ WEB_STAGED_UPLOAD_TTL_MS
|
|
|
417
672
|
WEB_THEMES
|
|
418
673
|
WEB_THREAD_SEARCH_MAX
|
|
419
674
|
WEB_THREAD_SEARCH_MIN_QUERY
|
|
675
|
+
WebAgentRunSettings
|
|
420
676
|
WebAgentStatus
|
|
421
677
|
WebAgentSummary
|
|
678
|
+
WebAgentsChangedPayload
|
|
422
679
|
WebAttachment
|
|
423
680
|
WebBootstrap
|
|
681
|
+
WebBootstrapScope
|
|
424
682
|
WebConsoleError
|
|
425
683
|
WebConsoleIdentity
|
|
684
|
+
WebCronReplyContextPart
|
|
685
|
+
WebCronReplyReceipt
|
|
686
|
+
WebCronReplySnapshotKind
|
|
426
687
|
WebEvent
|
|
427
688
|
WebEventType
|
|
689
|
+
WebJobActivity
|
|
428
690
|
WebLiveInputReceipt
|
|
429
691
|
WebMessage
|
|
692
|
+
WebMessageDelta
|
|
693
|
+
WebMessageDeltaOp
|
|
430
694
|
WebMessagePart
|
|
431
695
|
WebMessageStatus
|
|
432
696
|
WebModelOption
|
|
@@ -435,8 +699,14 @@ WebPushBootstrap
|
|
|
435
699
|
WebPushSubscriptionState
|
|
436
700
|
WebPushSubscriptionStatus
|
|
437
701
|
WebQuote
|
|
702
|
+
WebRunAttribution
|
|
703
|
+
WebRunExecution
|
|
704
|
+
WebRunRetry
|
|
705
|
+
WebRunSelection
|
|
706
|
+
WebRunSettingSource
|
|
438
707
|
WebRunState
|
|
439
708
|
WebRunStatus
|
|
709
|
+
WebRunTransition
|
|
440
710
|
WebServerHandle
|
|
441
711
|
WebSkillAvailability
|
|
442
712
|
WebSkillInfo
|
|
@@ -444,8 +714,10 @@ WebSkillRegistry
|
|
|
444
714
|
WebSkillUnavailableReason
|
|
445
715
|
WebStatePathOptions
|
|
446
716
|
WebStatePaths
|
|
717
|
+
WebSubmissionReceipt
|
|
447
718
|
WebTheme
|
|
448
719
|
WebThread
|
|
720
|
+
WebThreadChangedPayload
|
|
449
721
|
WebThreadDetail
|
|
450
722
|
WebThreadNotificationTriggerKind
|
|
451
723
|
WebThreadSearchHit
|
|
@@ -476,9 +748,16 @@ the actual bound address/port plus idempotent `stop()` and `close()` methods.
|
|
|
476
748
|
|
|
477
749
|
The browser API is rooted at `/api/v1`:
|
|
478
750
|
|
|
479
|
-
- `GET /bootstrap
|
|
751
|
+
- `GET /bootstrap` (one `?sourceId`/`?archived` thread bucket, `?limit` capped),
|
|
752
|
+
`PATCH /agents/:id`, and `GET/PATCH/DELETE /threads/:id`
|
|
480
753
|
- `POST /threads`, `/threads/:id/turns`, `/threads/:id/live-input`, and
|
|
481
|
-
`/threads/:id/cancel
|
|
754
|
+
`/threads/:id/cancel`; the browser composer uses
|
|
755
|
+
`POST /threads/:id/submissions` plus recovery reads at
|
|
756
|
+
`GET /threads/:id/submissions/:submissionId`
|
|
757
|
+
- `GET /threads/:id/messages/:messageId` for one message (delta gap recovery)
|
|
758
|
+
and `GET /threads/:id/messages/:messageId/tool-calls/:toolCallId` for the
|
|
759
|
+
unshaped body behind a truncated tool-call preview; `?full=1` on a transcript
|
|
760
|
+
read returns it unshaped
|
|
482
761
|
- `GET /threads/:id/ask` and `POST /threads/:id/ask` for the current structured
|
|
483
762
|
`AskUser` snapshot and atomic answer submission
|
|
484
763
|
- `POST /uploads`, `PUT/GET /uploads/:id/content`, and `DELETE /uploads/:id`
|
|
@@ -491,7 +770,13 @@ The browser API is rooted at `/api/v1`:
|
|
|
491
770
|
and `POST /push/events/:eventId/ack`; the status read carries the exact
|
|
492
771
|
`X-Mono-Agent-Web-Origin` browser-origin claim and returns no endpoint or key
|
|
493
772
|
material
|
|
494
|
-
- `GET /events` (SSE)
|
|
773
|
+
- `GET /events` (SSE); the optional `?thread=<id>` subscribes that connection to
|
|
774
|
+
one conversation's `message.delta` frames, resolving a redirected id to the
|
|
775
|
+
canonical one. `Last-Event-ID` is ignored — `ready` means resync
|
|
776
|
+
- `POST /agents/:sourceId/cron/jobs/:jobId/runs/:runId/reply-threads` snapshots
|
|
777
|
+
one visible terminal run and imports it into one normal same-agent thread;
|
|
778
|
+
the exact-origin request carries a browser-owned operation UUID and summary
|
|
779
|
+
or already-loaded-detail selection
|
|
495
780
|
|
|
496
781
|
`GET /healthz` is intentionally outside the versioned API for service probes.
|
|
497
782
|
Its compatibility-stable `status` remains `ok` while the additive `push` field
|
|
@@ -503,16 +788,49 @@ The additive `WebBootstrap.console` object carries the server-derived
|
|
|
503
788
|
`POST /threads/:id/live-input` accepts `{ text }` and returns a persisted message
|
|
504
789
|
with `disposition: "pending" | "queued"`; SSE invalidation exposes its later
|
|
505
790
|
`liveInputStatus` settlement.
|
|
791
|
+
|
|
792
|
+
`POST /threads/:id/submissions` accepts a canonical UUID plus the ordinary turn
|
|
793
|
+
payload. The thread-scoped immutable payload is recorded in `web_submissions`
|
|
794
|
+
with its turn/live-input/rejection associations. Same-id same-payload replay
|
|
795
|
+
returns the existing current receipt without dispatch; conflicting reuse is
|
|
796
|
+
`409`. `GET /threads/:id/submissions/:submissionId` is side-effect-free and both
|
|
797
|
+
receipt routes are `private, no-store`. Browser recovery persists only thread
|
|
798
|
+
and submission ids in session storage—never draft text or file bytes—and checks
|
|
799
|
+
the receipt without automatically posting again.
|
|
800
|
+
|
|
801
|
+
Schema 22 adds a nullable `live_inputs.dispatch_started_at` marker committed
|
|
802
|
+
before the operator request. On restart, an unmarked offered row is safe to
|
|
803
|
+
queue once; a marked row becomes `uncertain` and non-promotable. Existing
|
|
804
|
+
schema-21 rows migrate with a null marker, so their earlier dispatch history is
|
|
805
|
+
not reconstructible. Schema 23 adds the durable `web_submissions` ledger and
|
|
806
|
+
keeps it for the lifetime of its thread, including archive; permanent deletion
|
|
807
|
+
cascades it. Schema 24 adds the read indexes used by conversation run-state
|
|
808
|
+
lookups. Schema 25 adds `cron_reply_operations`, which owns the immutable
|
|
809
|
+
snapshot, canonical-import identity, pending/terminal settlement, and deletion
|
|
810
|
+
tombstone. Pending rows survive restart for explicit same-operation retry;
|
|
811
|
+
failed or deleted rows cannot expose or resurrect a conversation. Stop the Web
|
|
812
|
+
service and make a compatible database backup before migration. A schema-24
|
|
813
|
+
binary refuses a schema-25 database; rollback requires
|
|
814
|
+
restoring that compatible pre-upgrade backup and loses writes made afterward.
|
|
815
|
+
Upgrade the operator-adapter before the Web producer so `liveInputTargeting`
|
|
816
|
+
is available; an older operator is not guessed through and the receipt visibly
|
|
817
|
+
queues `unsupported_targeting`. Deployment remains a separate operation.
|
|
506
818
|
Permanent deletion is limited to archived, inactive conversations. It removes
|
|
507
819
|
database descendants transactionally and deletes committed attachment files;
|
|
508
820
|
startup and scheduled cleanup remove any file orphaned by a crash or transient
|
|
509
|
-
filesystem failure after the database commit.
|
|
821
|
+
filesystem failure after the database commit. Archiving a truly empty manual
|
|
822
|
+
conversation conditionally removes it instead; any authoritative trigger,
|
|
823
|
+
message, turn, attachment, live input, submission receipt, or delivery evidence makes the server
|
|
824
|
+
preserve it in Archived, including activity that arrives during the archive
|
|
825
|
+
race.
|
|
510
826
|
|
|
511
827
|
## Dependency Boundary
|
|
512
828
|
|
|
513
829
|
The server depends only on the `core` `@mono-agent/agent-contracts` and
|
|
514
830
|
`@mono-agent/config` packages, the `observability` trace-source registry, and
|
|
515
|
-
Express. Its
|
|
831
|
+
Express. Its Node-side operator clients use Undici to keep deliberately
|
|
832
|
+
long-lived turn and host-wake streams under their explicit lifecycle owners.
|
|
833
|
+
Its compiled browser bundle additionally contains the production graph
|
|
516
834
|
from the isolated `webapp` lockfile: assistant-ui, Base UI, cmdk, React, and
|
|
517
835
|
Workbox plus their transitive dependencies. The repository advisory and license
|
|
518
836
|
gates audit that nested production graph separately because it ships inside this
|