omo-ai 5.1.13 → 5.1.15

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "_comment": "Derived from @code-yeongyu/senpi 2026.10.3 builtinProviders(). builtinProviderIds and oauthProviderIds are the engine registry verbatim; providers maps a source harness id onto the omo provider that serves the same endpoint; oauthLogins maps a source OAuth id onto the omo provider to run /login for. Re-derive all four whenever the senpi pin changes.",
2
+ "_comment": "Derived from @code-yeongyu/senpi 2026.10.6 builtinProviders(). builtinProviderIds and oauthProviderIds are the engine registry verbatim; providers maps a source harness id onto the omo provider that serves the same endpoint; oauthLogins maps a source OAuth id onto the omo provider to run /login for. Re-derive all four whenever the senpi pin changes.",
3
3
  "builtinProviderIds": [
4
4
  "alibaba-token-plan",
5
5
  "amazon-bedrock",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omo-ai",
3
- "version": "5.1.13",
3
+ "version": "5.1.15",
4
4
  "type": "module",
5
5
  "description": "OmO Native - the standalone omo command with the OMO extension built in: bun add -g omo-ai",
6
6
  "bin": {
@@ -17,7 +17,7 @@
17
17
  "postinstall": "node bin/senpi-patch.mjs"
18
18
  },
19
19
  "dependencies": {
20
- "@code-yeongyu/senpi": "2026.10.3"
20
+ "@code-yeongyu/senpi": "2026.10.6"
21
21
  },
22
22
  "repository": {
23
23
  "type": "git",
@@ -7,6 +7,65 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [5.1.15] - 2026-10-04
11
+
12
+ **A new `auto` permission preset approves only what it can prove stays inside your project.** 5.1.15 runs on senpi 2026.10.6, whose `auto` preset approves an action without asking only when it can show the action stays inside the project, judged on the exact file each tool will open; anything it can't pin down still asks, and your own deny and ask rules still win. ([senpi#2614](https://github.com/code-yeongyu/senpi/pull/2614), [senpi#2688](https://github.com/code-yeongyu/senpi/pull/2688))
13
+
14
+ ### Fixed
15
+
16
+ **A question a session relayed to a chat thread closes when you answer it in the terminal.** Before, a relayed ask_user question answered (or timed out, or dismissed) in the session's own client stayed pending in the gateway store, so a chat connector kept that thread's later replies waiting until someone answered in chat. Outbox rows now also say whether a relayed answer is still being handed to the session (`answer_state`), so a connector waits for a delivered answer instead of treating a claim as settled. Thanks to @effortprogrammer. ([#9506](https://github.com/code-yeongyu/oh-my-openagent/pull/9506))
17
+
18
+ **Editing your config no longer gets a hot reload rejected over a deprecated-key notice.** Renamed keys such as `deep` -> `deep-low` still load, but any edit that touched one produced a new notice, and the reload was refused. Thanks to @davhdavh for the report and @cynkai for the fix. ([#8555](https://github.com/code-yeongyu/oh-my-openagent/issues/8555), [#8878](https://github.com/code-yeongyu/oh-my-openagent/pull/8878))
19
+
20
+ **`thread_read` pages forward when given `next_cursor`.** A truncated read returned a cursor, but retrying with it returned the same first window again. Thanks to @cynkai. ([#9435](https://github.com/code-yeongyu/oh-my-openagent/pull/9435))
21
+
22
+ **A memory usage write that fails after shutdown is logged instead of surfacing as an unhandled rejection.** Thanks to @Dante-dan. ([#9524](https://github.com/code-yeongyu/oh-my-openagent/pull/9524))
23
+
24
+ ### Changed
25
+
26
+ **omo runs on senpi 2026.10.6.** Besides the `auto` preset above, in that release the startup banner folds into one summary line; a 429 or 5xx from the provider shows as one retry banner instead of raw JSON, while a failed compaction still shows as an error; tool-card diffs read at 7:1 contrast and each edit card shows its change count; the `apply_patch` streaming preview stays bounded; `/files` and `/diff` open on Windows again; a first run with no provider gets the `/login` guidance; Linux x64 gets the native PTY backend. Full list: [senpi 2026.10.6](https://github.com/code-yeongyu/senpi/releases/tag/v2026.10.6).
27
+
28
+ **A finished subagent's card reads as a summary**, for example `ran 2m 14s · 5 tools · $0.4213 (CH: 87%)`, instead of a line of debug tokens. ([senpi#2654](https://github.com/code-yeongyu/senpi/issues/2654), [#9513](https://github.com/code-yeongyu/oh-my-openagent/pull/9513))
29
+
30
+ **Memory's `/doctor` checks load on first use** instead of with the extension, so startup loads less; the command behaves the same. Thanks to @Dante-dan. ([#9520](https://github.com/code-yeongyu/oh-my-openagent/pull/9520))
31
+
32
+
33
+ ## [5.1.14] - 2026-10-03
34
+
35
+ **Permission checks can no longer switch themselves off.** Up to 5.1.13, a failure while the permission system started (a misspelled `permissionPreset` in settings or on the command line, a `null` permission rule, or an unreadable approvals file) left every tool call running with no permission check, and nothing said so. 5.1.14 runs on senpi 2026.10.5, which refuses tool calls with `Permission setup failed: <reason>` until the setting is fixed. If you can't update yet, check that `permissionPreset` names a preset that exists and that no permission rule is `null`. ([senpi#2617](https://github.com/code-yeongyu/senpi/issues/2617), [senpi#2618](https://github.com/code-yeongyu/senpi/pull/2618))
36
+
37
+ ### Fixed
38
+
39
+ **A first-turn forced tool call that a strict-schema gateway refuses no longer ends the turn.** When a gateway answers 400 and names the forced tool (its `tools.N` position or its quoted name), the request is retried once without forcing; a generic 400, or one naming another tool, still fails as before. Thanks to @rhyme227 for the report. ([#9507](https://github.com/code-yeongyu/oh-my-openagent/issues/9507), [senpi#2648](https://github.com/code-yeongyu/senpi/issues/2648))
40
+
41
+ **`apply_patch` keeps each file's line endings and no longer drops an indented file section.** CRLF and mixed-ending files are no longer rewritten to LF, and a file header indented in the patch applies instead of being skipped while the tool reported success. ([senpi#2638](https://github.com/code-yeongyu/senpi/issues/2638), [senpi#2636](https://github.com/code-yeongyu/senpi/issues/2636))
42
+
43
+ **An NVIDIA-only setup starts on a model its catalog still lists.** The previous NVIDIA default was retired upstream; the default is now `nvidia/nemotron-3-ultra-550b-a55b`. ([senpi#2645](https://github.com/code-yeongyu/senpi/issues/2645))
44
+
45
+ **Codex edition (LazyCodex): a language server that isn't installed no longer blocks every edit.** LazyCodex's post-edit language-server check answered `block` with the install guidance on each edit, even after you declined the install; it now follows your install decision, as the Native edition does. ([#9509](https://github.com/code-yeongyu/oh-my-openagent/issues/9509), [#9510](https://github.com/code-yeongyu/oh-my-openagent/pull/9510))
46
+
47
+ **A computer-use permission denial is an error in code mode too.** Through a JS or Python eval, a denied computer call came back without the error flag, so a model could miss the denial and keep acting; it now fails the call there as it does on a direct call. ([#9475](https://github.com/code-yeongyu/oh-my-openagent/issues/9475), [#9482](https://github.com/code-yeongyu/oh-my-openagent/pull/9482))
48
+
49
+ **Windows: a delegated task you kill is reported as killed, not as a crash, and memory no longer loses a state write to a briefly held file.** A kill is now recognised from the runner's own request instead of from the child's stderr, and memory's atomic state rename retries the few-millisecond hold Windows places on an open target. ([#9471](https://github.com/code-yeongyu/oh-my-openagent/issues/9471), [#9501](https://github.com/code-yeongyu/oh-my-openagent/pull/9501), [#9491](https://github.com/code-yeongyu/oh-my-openagent/pull/9491))
50
+
51
+ **The computer-use doctor check on macOS reports an engine that never replied as a timeout instead of failing with `EPERM`.** Cleaning up the timed-out probe now treats a process group that is already exiting as gone. Thanks to @MoerAI. ([#9422](https://github.com/code-yeongyu/oh-my-openagent/issues/9422), [#9464](https://github.com/code-yeongyu/oh-my-openagent/pull/9464))
52
+
53
+ Thanks to @MoerAI for moving the task engine's child event channel into `senpi-task`, where the computer-use component now imports it from. ([#9454](https://github.com/code-yeongyu/oh-my-openagent/issues/9454), [#9467](https://github.com/code-yeongyu/oh-my-openagent/pull/9467))
54
+
55
+ ### Changed
56
+
57
+ **omo runs on senpi 2026.10.5** (through 2026.10.4): the permission fix above; an eval kernel (Python, Ruby or Julia) whose interpreter dies is replaced once instead of failing every later cell; idle shared hosts give their cost back; the Claude Agent SDK moves to 0.3.288; and pasting in terminals without bracketed-paste markers works. Full lists: [senpi 2026.10.4](https://github.com/code-yeongyu/senpi/releases/tag/v2026.10.4), [senpi 2026.10.5](https://github.com/code-yeongyu/senpi/releases/tag/v2026.10.5).
58
+
59
+ **The task tool no longer suggests delegating a few reads or small foreground checks.** Its description and the ultrawork routing named those as delegation targets, and GPT-6 Astra followed them literally, waiting on children for work it could do in a few calls. ([#9499](https://github.com/code-yeongyu/oh-my-openagent/issues/9499), [#9500](https://github.com/code-yeongyu/oh-my-openagent/pull/9500))
60
+
61
+ ### Added
62
+
63
+ **The browser skill follows the browser the OmO desktop app picks for the session.** With a connected browser it uses only that browser and says "Connect your browser" when it's missing; with the in-app browser or none chosen it refuses to drive your own browser. It reports what the browser is doing, and asks before an irreversible action in your own browser. In a terminal nothing changes. ([#9486](https://github.com/code-yeongyu/oh-my-openagent/issues/9486), [#9502](https://github.com/code-yeongyu/oh-my-openagent/pull/9502))
64
+
65
+ **Chat connectors and other integrations can keep their own state in the session-gateway database** and update it in the same transaction as sending, binding or acknowledging a message. The session-gateway store supports namespaced extensions: compiled operations can update their registered objects and enqueue messages through bindings, bind conversations, or acknowledge outbox rows in one transaction. A persistent ownership registry protects core and other extensions' objects; matching a name prefix never grants access. Core-colliding names, triggers and views are refused. Migrations are coordinated across processes, forbidden schema changes roll back, and a joined enqueue creates its wake marker inside the transaction, so a rollback removes it. Failures return typed refusals without stopping the worker. Core schema v6 adds the extension registry, preserves existing rows and records `author.user_id` as nullable `deliveries.actor_user_id`. ([#9331](https://github.com/code-yeongyu/oh-my-openagent/pull/9331), Refs [#9143](https://github.com/code-yeongyu/oh-my-openagent/issues/9143))
66
+
67
+ A session-gateway store or store extension whose schema is newer than the running omo is refused with `gateway_schema_too_new` and left untouched: an older binary neither migrates nor lowers the core `user_version`, and an extension that registers fewer migrations than its stored version keeps its stored version, data and existing registration. ([#9331](https://github.com/code-yeongyu/oh-my-openagent/pull/9331))
68
+
10
69
  ## [5.1.13] - 2026-10-03
11
70
 
12
71
  **MCP tools work again when memory is on.** Since 5.1.10, a finished memory child or delegated task shut the shared MCP servers down for the whole process, so every MCP call failed with `MCP server <name> is disabled`. This release runs on senpi 2026.10.3, which gives each session its own binding to the shared servers; it was verified with the shipped bundle. If you can't update yet, turn memory off until you do: set `"memory": { "enabled": false }` in `~/.omo/omo.json`, or start omo with `--omo-senpi-memory-disabled=true`.
package/plugin/README.md CHANGED
@@ -65,4 +65,4 @@ Disable individual OMO Senpi components through the adapter's per-component disa
65
65
 
66
66
  The Senpi LSP tools are always registered so the harness can show the same six tools in every project: `lsp_diagnostics`, `lsp_goto_definition`, `lsp_find_references`, `lsp_symbols`, `lsp_prepare_rename`, and `lsp_rename`. Runtime execution is handled by the packaged OMO LSP daemon, not by a vendored Senpi client.
67
67
 
68
- Project-local `.pi/lsp-client.json` command or env entries are ignored for safety. Move custom LSP command definitions to your user `.pi/lsp-client.json`; project configs may keep safe fields such as extensions, language IDs, and priorities. `lsp_rename` still runs sequentially, and post-edit diagnostics keep using the daemon after edits without stopping it.
68
+ Project-local `lsp-client.json` command or env entries (in `.omo/` or `.pi/`) are ignored for safety. Move custom LSP command definitions to your user `~/.omo/lsp-client.json` (`~/.pi/lsp-client.json` is still read as a fallback); project configs may keep safe fields such as extensions, language IDs, and priorities. `lsp_rename` still runs sequentially, and post-edit diagnostics keep using the daemon after edits without stopping it.
@@ -1,2 +1,2 @@
1
- // omo:haTcOnW4Q7NFRriYnPezqeOoaLFn_eHDlCpcX3dHCV4:ELjiv3uXvehilVGUyp2URd8J4PhruHKfVy8EzTtMliw
2
- import{chmodSync as e,closeSync as i,existsSync as t,mkdirSync as n,openSync as r}from"node:fs";import{join as d}from"node:path";import{setTimeout as s}from"node:timers/promises";import{parentPort as a}from"node:worker_threads";function o(e,i,t){return Object.assign(Error(`gateway store lock wait exceeded: ${e} waited ${i} ms for the write lock (limit ${t} ms); another process holds it`),{code:"gateway_lock_wait_exceeded"})}import{join as _}from"node:path";function u(e){return _(e,"gateway")}function l(e,i){return _(u(e),"inbox",i)}import{execFile as c}from"node:child_process";var p="epoch:",E=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function g(e){return new Promise(i=>{c("ps",["-o","lstart=","-p",String(e)],{env:{...process.env,LC_ALL:"C",LANG:"C",TZ:"UTC"},windowsHide:!0,timeout:5e3},(e,t)=>{let n=null===e?function(e){let i=/^[A-Z][a-z]{2} ([A-Z][a-z]{2}) +(\d{1,2}) (\d{2}):(\d{2}):(\d{2}) (\d{4})$/.exec(e.trim());if(null===i)return null;let[,t,n,r,d,s,a]=i,o=E.indexOf(t);return o<0?null:Date.UTC(Number(a),o,Number(n),Number(r),Number(d),Number(s))/1e3}(t):null;i(null===n?null:`${p}${n}`)})})}async function m(e){if(!function(e){try{return process.kill(e,0),!0}catch(e){return!(e instanceof Error&&"code"in e&&"ESRCH"===e.code)}}(e.pid))return!0;if(null===e.process_start_time||!e.process_start_time.startsWith(p))return!1;let i=await g(e.pid);return null!==i&&i!==e.process_start_time}function b(e,i){return e.pid===i.pid&&e.process_start_time===i.process_start_time&&e.instance_id===i.instance_id}class f{params=[];sinkRows=[];db;constructor(e){this.db=e,e.function("gw_p",{deterministic:!1},e=>this.params[e]??null),e.function("gw_sink",{varargs:!0,deterministic:!1},(...e)=>(this.sinkRows.push(e),null))}exec(e){this.db.exec(e)}run(e,i=[]){this.params=i;try{this.db.exec(T(e))}finally{this.params=[]}return Number(this.all(["n"],"SELECT changes() AS n")[0]?.n??0)}all(e,i,t=[],n){this.params=t,this.sinkRows=[];try{let t=void 0===n?"0":`row_number() OVER (ORDER BY ${n})`;return this.db.exec(`SELECT gw_sink(${t}, ${e.join(", ")}) FROM (${T(i)})${void 0===n?"":` ORDER BY ${n}`}`),(void 0===n?this.sinkRows:this.sinkRows.toSorted((e,i)=>Number(e[0])-Number(i[0]))).map(i=>Object.fromEntries(e.map((e,t)=>[e,i[t+1]??null])))}finally{this.params=[],this.sinkRows=[]}}one(e,i,t=[]){return this.all(e,i,t)[0]}}function T(e){let i=0;return e.replace(/\?/g,()=>`gw_p(${i++})`)}function N(e){if("object"!=typeof e||null===e)return!1;let i=e;return 5===i.errcode||6===i.errcode||"string"==typeof i.message&&/database is (locked|busy)/i.test(i.message)}import{createHash as y,randomUUID as v}from"node:crypto";import{closeSync as h,constants as w,mkdirSync as L,openSync as k,readdirSync as R,readFileSync as O,rmSync as S,writeSync as A}from"node:fs";import{userInfo as q}from"node:os";import{join as x}from"node:path";function I(e,i,t){return i===t||function(e,i,t){let n=new Map;for(let i of e){let e=n.get(i.from);void 0===e?n.set(i.from,[i.to]):e.push(i.to)}let r=new Set([i]),d=[i];for(;d.length>0;){let e=d.pop();if(e===t)return!0;for(let i of n.get(e)??[])r.has(i)||(r.add(i),d.push(i))}return!1}(e,t,i)}var D=5e3,U=864e5,C=6048e5,M=1048576,H=2592e6,W=2592e6,X=256,F="session_released";import{existsSync as $,readFileSync as G}from"node:fs";import{join as P}from"node:path";function B(e){let i=P(e,"mailbox.jsonl");if($(i))return function(e){let i=e.slice(0,e.lastIndexOf("\n")+1),t=new Map;for(let e of i.split("\n")){if(0===e.length)continue;let i=JSON.parse(e);if(!j(i)||1!==i.version)throw Error("invalid legacy mailbox event");if("snapshot"===i.kind&&Array.isArray(i.items)){t.clear();for(let e of i.items){let i=K(e);t.set(i.message_seq,i)}}else if("enqueue"===i.kind){let e=K(i.item);t.set(e.message_seq,e)}else{if("remove"!==i.kind||"number"!=typeof i.message_seq)throw Error("invalid legacy mailbox event");t.delete(i.message_seq)}}return J([...t.values()])}(G(i,"utf8"));let t=P(e,"mailbox.json");if(!$(t))return null;let n=JSON.parse(G(t,"utf8"));if(!j(n)||!j(n.queues))throw Error(`invalid legacy mailbox state: ${t}`);let r=[];for(let e of Object.values(n.queues)){if(!Array.isArray(e))throw Error(`invalid legacy mailbox queue: ${t}`);for(let i of e)r.push(K(i))}return J(r)}function J(e){return e.toSorted((e,i)=>e.message_seq-i.message_seq)}function K(e){if(!j(e)||"string"!=typeof e.target||"string"!=typeof e.message||"number"!=typeof e.message_seq||!Number.isInteger(e.message_seq)||"auto"!==e.delivery&&"steer"!==e.delivery&&"follow_up"!==e.delivery||void 0!==e.expected_turn_id&&"string"!=typeof e.expected_turn_id||"string"!=typeof e.operation_id||"string"!=typeof e.accepted_at)throw Error("invalid legacy mailbox item");return{target:e.target,message:e.message,message_seq:e.message_seq,delivery:e.delivery,expected_turn_id:void 0===e.expected_turn_id?null:Y(e.expected_turn_id),operation_id:e.operation_id,accepted_at:e.accepted_at}}function Y(e){let i=/^turn-(0|[1-9]\d*)$/.exec(e);if(null===i)return null;let t=Number(i[1]);return Number.isSafeInteger(t)?t:null}function j(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}import{createHash as V,createHmac as z,randomUUID as Z,timingSafeEqual as Q}from"node:crypto";var ee=2592e6;function ie(e){return new Date(e).toISOString()}function te(e){return Buffer.from(e).toString("base64url")}function ne(e,i){return te(JSON.stringify({v:1,as_of:e,after:i}))}var re="rt1";function de(e,i){return z("sha256",e).update(`${re}.${i}`).digest().subarray(0,16).toString("base64url")}var se=new WeakMap;function ae(e,i,t){return ye(e,"DELETE FROM receipts WHERE principal = ? AND operation = ? AND idempotency_key = ? AND expires_at <= ?",[i.principal,i.operation,i.idempotency_key,t])}function oe(e,i,t=0){if(i<(se.get(e)??Number.NEGATIVE_INFINITY))return null;let n=function(e,i,t=256){let n=X,r=ye(e,"DELETE FROM receipts WHERE rowid IN (SELECT rowid FROM receipts WHERE expires_at <= ? LIMIT ?)",[i,t]),d=ye(e,"DELETE FROM deliveries WHERE delivery_id IN (SELECT d.delivery_id FROM deliveries d WHERE d.state IN ('applied', 'refused') AND d.updated_at <= ? AND NOT EXISTS (SELECT 1 FROM receipts r WHERE r.delivery_id = d.delivery_id) LIMIT ?)",[i-W,n]),s=ye(e,"DELETE FROM causal_edges WHERE rowid IN (SELECT e.rowid FROM causal_edges e JOIN causal_roots r ON r.root_id = e.root_id WHERE r.expires_at <= ? LIMIT ?)",[i,n]),a=ye(e,"DELETE FROM causal_roots WHERE root_id IN (SELECT r.root_id FROM causal_roots r WHERE r.expires_at <= ? AND NOT EXISTS (SELECT 1 FROM causal_edges e WHERE e.root_id = r.root_id) LIMIT ?)",[i,n]),o=ye(e,"DELETE FROM rate_buckets WHERE rowid IN (SELECT rowid FROM rate_buckets WHERE updated_at <= ? LIMIT ?)",[i-4e4,n]),_=ye(e,`DELETE FROM bindings WHERE binding_id IN (SELECT b.binding_id FROM bindings b WHERE b.status != 'active' AND b.updated_at <= ?\n AND NOT EXISTS (SELECT 1 FROM outbox o WHERE o.binding_id = b.binding_id)\n AND NOT EXISTS (SELECT 1 FROM completion_arms a WHERE a.binding_id = b.binding_id)\n AND NOT EXISTS (SELECT 1 FROM deliveries d WHERE d.binding_id = b.binding_id AND d.state IN ${ge}) LIMIT ?)`,[ie(i-ee),n]),u=ye(e,"DELETE FROM outbox_cursors WHERE binding_id IN (SELECT c.binding_id FROM outbox_cursors c WHERE NOT EXISTS (SELECT 1 FROM bindings b WHERE b.binding_id = c.binding_id) LIMIT ?)",[n]),l=ye(e,"DELETE FROM session_meta WHERE durable_id IN (SELECT m.durable_id FROM session_meta m WHERE\n m.incarnation IS NULL\n AND NOT EXISTS (SELECT 1 FROM deliveries d WHERE d.target_durable_id = m.durable_id)\n AND NOT EXISTS (SELECT 1 FROM bindings b WHERE b.session_durable_id = m.durable_id)\n AND NOT EXISTS (SELECT 1 FROM outbox o WHERE o.session_durable_id = m.durable_id)\n AND NOT EXISTS (SELECT 1 FROM completion_arms a WHERE a.session_durable_id = m.durable_id) LIMIT ?)",[n]);return{receipts:r,deliveries:d,causal_edges:s,causal_roots:a,rate_buckets:o,bindings:_,outbox_cursors:u,session_meta:l}}(e,i,Math.max(X-t,0)),r=n.receipts+t>=X||Object.values(n).some(e=>e>=X);return se.set(e,r?i:i+36e5),n}var _e=new Set(["invalid_arguments","caller_context_missing","not_found","ambiguous_target","scope_denied","name_conflict","not_resumable","orphaned","foreign_live_owner","no_active_turn","turn_conflict","not_steerable","message_too_large","queue_full","cursor_invalid","cursor_stale","idempotency_conflict","idempotency_in_progress","idempotency_uncertain","approval_unavailable","approval_route_locked","partial_commit","unsupported","overloaded","transport_closed","host_unavailable","internal_error","model_not_found","model_ambiguous","thinking_level_unsupported","loop_detected","binding_conflict","binding_mismatch","binding_inactive","stale_revision","stale_token","already_answered","answer_in_progress"]);function ue(e,i,t,n){if("string"!=typeof(r=e)||!_e.has(r))throw Error(`unknown thread error code: ${String(e)}`);var r;return{code:e,message:i,next_action:t,...void 0===n?{}:{details:n}}}var le={not_steerable:{code:"not_steerable",next:"Send with delivery auto or follow_up; a steer needs a running turn."},turn_conflict:{code:"turn_conflict",next:"Read the target again and retry with its current turn id, or send with delivery auto."},expired:{code:"not_resumable",next:"The target did not take the message within its lifetime; send it again if it still matters."},binding_closed:{code:"invalid_arguments",next:"The binding this message was queued under was detached or rebound; re-read the binding and send again."}};function ce(e,i,t,n,r){let d={kind:"ok",thread_id:e.target_durable_id,delivery_id:e.delivery_id,message_seq:e.seq,effective_mode:e.mode_effective??e.mode_requested,endpoint_kind:t,deduplicated:n};if("admitted"===e.state||"applied"===e.state)return"started"===e.admission_kind||"steered"===e.admission_kind?{...d,delivery:{kind:e.admission_kind,turn_id:String(e.turn_epoch??0)}}:{...d,delivery:{kind:"queued",queue_position:Math.max(i,1)}};if("refused"===e.state){let i=le[e.reason??""]??{code:"internal_error",next:"Call thread_list and check the target."};return{kind:"error",error:ue(i.code,`Delivery ${e.delivery_id} was refused: ${e.reason??"unknown"}.`,i.next,{delivery_id:e.delivery_id})}}return"uncertain"===e.state?{kind:"error",error:ue("idempotency_uncertain",`Delivery ${e.delivery_id} may or may not have reached the target.`,"Read the target transcript before deciding whether to send again.",{delivery_id:e.delivery_id})}:{...d,delivery:{kind:r?"queued_offline":"queued",queue_position:Math.max(i,1)}}}var pe=[["CREATE TABLE deliveries (\n delivery_id TEXT PRIMARY KEY,\n target_durable_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n sender TEXT NOT NULL,\n sender_turn TEXT,\n envelope TEXT NOT NULL,\n body TEXT NOT NULL,\n bytes INTEGER NOT NULL,\n mode_requested TEXT NOT NULL CHECK (mode_requested IN ('auto', 'steer', 'follow_up')),\n mode_effective TEXT CHECK (mode_effective IS NULL OR mode_effective IN ('steer', 'follow_up')),\n expected_turn_id INTEGER,\n state TEXT NOT NULL CHECK (state IN ('queued', 'admitting', 'admitted', 'applied', 'refused', 'uncertain')),\n reason TEXT,\n admitted_by TEXT,\n claimed_at INTEGER,\n attempt INTEGER NOT NULL DEFAULT 0,\n admission_kind TEXT,\n turn_epoch INTEGER,\n root_id TEXT NOT NULL,\n hop INTEGER NOT NULL,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n expires_at INTEGER NOT NULL,\n binding_id TEXT,\n binding_revision INTEGER,\n UNIQUE (target_durable_id, seq)\n )","CREATE INDEX deliveries_target_state_seq ON deliveries (target_durable_id, state, seq)","CREATE INDEX deliveries_root ON deliveries (root_id)","CREATE INDEX deliveries_sender_turn ON deliveries (sender, sender_turn)","CREATE TABLE receipts (\n principal TEXT NOT NULL,\n operation TEXT NOT NULL,\n idempotency_key TEXT NOT NULL,\n args_hash TEXT NOT NULL,\n status TEXT NOT NULL CHECK (status IN ('prepared', 'completed', 'uncertain')),\n delivery_id TEXT,\n owner_instance TEXT NOT NULL,\n result TEXT,\n error_note TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n expires_at INTEGER NOT NULL,\n PRIMARY KEY (principal, operation, idempotency_key)\n )","CREATE INDEX receipts_expiry ON receipts (expires_at)","CREATE TABLE causal_roots (\n root_id TEXT PRIMARY KEY,\n origin_principal TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n expires_at INTEGER NOT NULL\n )","CREATE TABLE causal_edges (\n root_id TEXT NOT NULL,\n from_durable_id TEXT NOT NULL,\n to_durable_id TEXT NOT NULL,\n delivery_id TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n PRIMARY KEY (root_id, from_durable_id, to_durable_id)\n )","CREATE TABLE rate_buckets (\n sender TEXT NOT NULL,\n target_durable_id TEXT NOT NULL,\n tokens REAL NOT NULL,\n updated_at INTEGER NOT NULL,\n PRIMARY KEY (sender, target_durable_id)\n )","CREATE TABLE session_meta (\n durable_id TEXT PRIMARY KEY,\n next_seq INTEGER NOT NULL,\n applied_seq INTEGER NOT NULL DEFAULT 0\n )","CREATE TABLE bindings (\n seq INTEGER PRIMARY KEY AUTOINCREMENT,\n binding_id TEXT NOT NULL UNIQUE,\n schema_version INTEGER NOT NULL DEFAULT 1,\n revision INTEGER NOT NULL CHECK (revision >= 1),\n status TEXT NOT NULL CHECK (status IN ('active', 'detached', 'expired')),\n platform TEXT NOT NULL CHECK (platform IN ('discord', 'telegram', 'slack', 'notion', 'feishu', 'herdr', 'custom')),\n account_id TEXT NOT NULL,\n chat_id TEXT NOT NULL,\n thread_id TEXT NOT NULL,\n root_message_id TEXT,\n progress_message_id TEXT,\n session_realm_id TEXT NOT NULL,\n session_durable_id TEXT NOT NULL,\n direction_inbound INTEGER NOT NULL CHECK (direction_inbound IN (0, 1)),\n direction_outbound INTEGER NOT NULL CHECK (direction_outbound IN (0, 1)),\n inbound_mode TEXT NOT NULL CHECK (inbound_mode IN ('auto', 'follow_up')),\n outbound_events TEXT NOT NULL,\n policy_id TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n lease_started_at TEXT NOT NULL,\n ttl_seconds INTEGER,\n expires_at TEXT,\n CHECK (direction_inbound = 1 OR direction_outbound = 1)\n )","CREATE UNIQUE INDEX bindings_one_active_thread ON bindings (platform, account_id, chat_id, thread_id) WHERE status = 'active'","CREATE INDEX bindings_session ON bindings (session_durable_id, status)","CREATE TABLE outbox (\n cursor INTEGER PRIMARY KEY AUTOINCREMENT,\n binding_id TEXT NOT NULL,\n revision INTEGER NOT NULL,\n event_kind TEXT NOT NULL CHECK (event_kind IN ('milestone', 'report', 'question', 'completion', 'question_closed')),\n payload TEXT NOT NULL,\n state TEXT NOT NULL CHECK (state IN ('pending', 'acked')),\n provider_message_id TEXT,\n created_at INTEGER NOT NULL,\n acked_at INTEGER\n )","CREATE INDEX outbox_binding_cursor ON outbox (binding_id, cursor)","CREATE TABLE gateway_meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n )"],["ALTER TABLE session_meta ADD COLUMN incarnation TEXT","ALTER TABLE outbox ADD COLUMN session_durable_id TEXT","ALTER TABLE outbox ADD COLUMN reply_token TEXT","ALTER TABLE outbox ADD COLUMN ui_request_id TEXT","ALTER TABLE outbox ADD COLUMN incarnation TEXT","ALTER TABLE outbox ADD COLUMN question_state TEXT CHECK (question_state IS NULL OR question_state IN ('pending', 'answered', 'expired', 'cancelled'))","ALTER TABLE outbox ADD COLUMN answer TEXT","ALTER TABLE outbox ADD COLUMN answered_at INTEGER","ALTER TABLE outbox ADD COLUMN outcome TEXT CHECK (outcome IS NULL OR outcome IN ('completed', 'failed', 'cancelled'))","CREATE UNIQUE INDEX outbox_reply_token ON outbox (reply_token) WHERE reply_token IS NOT NULL","CREATE TABLE outbox_cursors (\n binding_id TEXT PRIMARY KEY,\n acked_cursor INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n )","CREATE TABLE completion_arms (\n arm_seq INTEGER PRIMARY KEY AUTOINCREMENT,\n session_durable_id TEXT NOT NULL,\n binding_id TEXT NOT NULL,\n revision INTEGER NOT NULL,\n text TEXT NOT NULL,\n armed_at INTEGER NOT NULL\n )","CREATE INDEX completion_arms_session ON completion_arms (session_durable_id, armed_at)","INSERT OR IGNORE INTO gateway_meta (key, value) VALUES ('realm_id', 'realm-' || lower(hex(randomblob(16))))","INSERT OR IGNORE INTO gateway_meta (key, value) VALUES ('token_secret', lower(hex(randomblob(32))))"],["ALTER TABLE outbox ADD COLUMN ui_request_kind TEXT CHECK (ui_request_kind IS NULL OR ui_request_kind IN ('question', 'select', 'confirm', 'input', 'editor'))","ALTER TABLE outbox ADD COLUMN answer_state TEXT CHECK (answer_state IS NULL OR answer_state IN ('in_flight', 'delivered'))"],["ALTER TABLE outbox ADD COLUMN answered_by TEXT"],["ALTER TABLE session_meta ADD COLUMN endpoint_socket TEXT","ALTER TABLE session_meta ADD COLUMN endpoint_kind TEXT CHECK (endpoint_kind IS NULL OR endpoint_kind IN ('tui', 'rpc_host'))"]],Ee=["delivery_id","target_durable_id","seq","sender","sender_turn","envelope","body","bytes","mode_requested","mode_effective","expected_turn_id","state","reason","admitted_by","claimed_at","attempt","admission_kind","turn_epoch","root_id","hop","created_at","updated_at","expires_at","binding_id","binding_revision"],ge="('queued', 'admitting', 'admitted')",me=/^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/;function be(e,i,t){return{kind:"refused",code:e,message:i,...void 0===t?{}:{details:t}}}function fe(e){let i=e=>null==e?null:Number(e);return{delivery_id:String(e.delivery_id),target_durable_id:String(e.target_durable_id),seq:Number(e.seq),sender:String(e.sender),sender_turn:null===e.sender_turn?null:String(e.sender_turn),envelope:JSON.parse(String(e.envelope)),body:String(e.body),bytes:Number(e.bytes),mode_requested:e.mode_requested,mode_effective:e.mode_effective??null,expected_turn_id:i(e.expected_turn_id),state:e.state,reason:null===e.reason?null:String(e.reason),admitted_by:null===e.admitted_by?null:JSON.parse(String(e.admitted_by)),claimed_at:i(e.claimed_at),attempt:Number(e.attempt),admission_kind:null===e.admission_kind?null:String(e.admission_kind),turn_epoch:i(e.turn_epoch),root_id:String(e.root_id),hop:Number(e.hop),created_at:Number(e.created_at),updated_at:Number(e.updated_at),expires_at:Number(e.expires_at),binding_id:null===e.binding_id?null:String(e.binding_id),binding_revision:i(e.binding_revision)}}function Te(e,i,t,n){return e.sql.all(Ee,`SELECT ${Ee.join(", ")} FROM deliveries WHERE ${i}`,t,n).map(fe)}function Ne(e,i){return Te(e,"delivery_id = ?",[i])[0]}function ye(e,i,t=[]){let n=e.sql.run(i,t);return e.stats.writes+=n,n}function ve(e,i){if("queued"!==i.state&&"admitting"!==i.state&&"admitted"!==i.state)return 0;let t=e.sql.one(["n"],`SELECT COUNT(*) AS n FROM deliveries WHERE target_durable_id = ? AND state IN ${ge} AND seq <= ?`,[i.target_durable_id,i.seq]);return Number(t?.n??1)}async function he(e,i,t){let n=Date.now();for(;;)try{return e.sql.exec("BEGIN IMMEDIATE"),e.stats.transactions++,!0}catch(r){if(!N(r))throw r;if(e.emit({kind:"busy",op:i}),!t)return!1;let d=Date.now()-n;if(d+2*e.config.busy_timeout_ms>e.config.lock_wait_max_ms)throw e.emit({kind:"lock_wait_exceeded",op:i,waited_ms:d}),o(i,d,e.config.lock_wait_max_ms);await e.delay(e.config.busy_timeout_ms)}}function we(e){try{e.sql.exec("ROLLBACK")}catch{return}}async function Le(e,i,t){await he(e,i,!0);try{let i=t();return e.sql.exec("COMMIT"),i}catch(i){throw we(e),i}}function ke(e,i,t,n){let r=l(e.config.agent_dir,i);L(r,{recursive:!0,mode:448});let d,s=x(r,t);try{d=k(s,w.O_CREAT|w.O_EXCL|w.O_WRONLY,384)}catch(e){if(n&&e instanceof Error&&"code"in e&&"EEXIST"===e.code)return s;throw e}try{A(d,JSON.stringify({pid:e.self.pid,process_start_time:e.self.process_start_time}))}finally{h(d)}return s}function Re(e,i,t){let n=x(l(e.config.agent_dir,i),t);try{S(n),e.stats.marker_unlinks++}catch(e){if(!(e instanceof Error&&"code"in e&&"ENOENT"===e.code))throw e}}function Oe(e,i){try{return R(l(e.config.agent_dir,i)).filter(e=>!e.startsWith("."))}catch(e){if(e instanceof Error&&"code"in e&&"ENOENT"===e.code)return[];throw e}}function Se(e,i){let t=e.sql.one(["next_seq"],"SELECT next_seq FROM session_meta WHERE durable_id = ?",[i]),n=Number(void 0===t?e.sql.one(["m"],"SELECT COALESCE(MAX(seq), 0) + 1 AS m FROM deliveries WHERE target_durable_id = ?",[i])?.m??1:t.next_seq);return ye(e,"INSERT INTO session_meta (durable_id, next_seq) VALUES (?, ?) ON CONFLICT(durable_id) DO UPDATE SET next_seq = excluded.next_seq",[i,n+1]),n}function Ae(e,i){ye(e,`INSERT INTO deliveries (${Ee.join(", ")}) VALUES (${Ee.map(()=>"?").join(", ")})`,[i.delivery_id,i.target_durable_id,i.seq,i.sender,i.sender_turn,JSON.stringify(i.envelope),i.body,i.bytes,i.mode_requested,i.mode_effective,i.expected_turn_id,i.state,i.reason,null===i.admitted_by?null:JSON.stringify(i.admitted_by),i.claimed_at,i.attempt,i.admission_kind,i.turn_epoch,i.root_id,i.hop,i.created_at,i.updated_at,i.expires_at,i.binding_id,i.binding_revision])}function qe(e){return y("sha256").update(JSON.stringify(e)).digest("hex")}function xe(e){return Number(e.sql.one(["user_version"],"SELECT user_version FROM pragma_user_version()")?.user_version??0)}function Ie(e,i,t){let n=e.sql.one(["args_hash","status","delivery_id","owner_instance","result","expires_at"],"SELECT args_hash, status, delivery_id, owner_instance, result, expires_at FROM receipts WHERE principal = ? AND operation = 'deliver' AND idempotency_key = ?",[i,t]);if(void 0!==n)return{args_hash:String(n.args_hash),status:n.status,delivery_id:null===n.delivery_id?null:String(n.delivery_id),owner_instance:String(n.owner_instance),result:null===n.result?null:String(n.result),expires_at:Number(n.expires_at)}}function De(e,i,t){if(t.args_hash!==i.receipt.args_hash)return be("idempotency_conflict","The idempotency key was already used with different arguments.");if("completed"===t.status&&null!==t.result)return{kind:"replay",result:JSON.parse(t.result)};let n=null===t.delivery_id?void 0:Ne(e,t.delivery_id),r=void 0!==n&&("admitted"===n.state||"applied"===n.state||"refused"===n.state);if("prepared"===t.status&&!r&&t.owner_instance===e.config.instance_id)return be("idempotency_in_progress","The same delivery is already in progress.");if("prepared"===t.status&&r){let t={...ce(n,ve(e,n),i.endpoint_kind,!0,!1)};return ye(e,"UPDATE receipts SET status = 'completed', result = ?, updated_at = ? WHERE principal = ? AND operation = 'deliver' AND idempotency_key = ?",[JSON.stringify(t),i.now,i.sender_principal,i.receipt.idempotency_key]),{kind:"replay",result:t}}return"prepared"===t.status&&ye(e,"UPDATE receipts SET status = 'uncertain', error_note = ?, updated_at = ? WHERE principal = ? AND operation = 'deliver' AND idempotency_key = ?",["the sender lost the acknowledgement before the target admitted the delivery",i.now,i.sender_principal,i.receipt.idempotency_key]),be("idempotency_uncertain","The earlier delivery may or may not reach the target; it is never sent twice.",{delivery_id:t.delivery_id,state:n?.state??null})}async function Ue(e,i){if(!me.test(i.target_durable_id)||!me.test(i.delivery_id))return be("invalid_arguments","The target session id is not a durable session id.");if(!await he(e,"enqueue",!1))return{kind:"busy"};let t=null,n=!1;try{let r=ae(e,{principal:i.sender_principal,operation:"deliver",idempotency_key:i.receipt.idempotency_key},i.now),d=Ie(e,i.sender_principal,i.receipt.idempotency_key);if(void 0!==d){let t=De(e,i,d);return e.sql.exec("COMMIT"),n=!0,t}let s=function(e,i){if(null===i.binding)return{expires_at:null};let t=e.sql.one(["revision","status","session_durable_id","direction_inbound","expires_at"],"SELECT revision, status, session_durable_id, direction_inbound, expires_at FROM bindings WHERE binding_id = ?",[i.binding.binding_id]),n=null==t?.expires_at?null:Date.parse(String(t.expires_at));return void 0===t||"active"!==t.status||Number(t.revision)!==i.binding.revision||String(t.session_durable_id)!==i.target_durable_id||1!==Number(t.direction_inbound)||null!==n&&n<=i.now?be("invalid_arguments","The binding is not active for this session at this revision.",{binding:i.binding.binding_id}):{expires_at:n}}(e,i);if("kind"in s)return we(e),s;let a=e.sql.one(["n","b"],`SELECT COUNT(*) AS n, COALESCE(SUM(bytes), 0) AS b FROM deliveries WHERE target_durable_id = ? AND state IN ${ge}`,[i.target_durable_id]),o=Buffer.byteLength(i.body);if(Number(a?.n??0)>=128||Number(a?.b??0)+o>M)return we(e),be("queue_full","The target's delivery backlog is full.",{max_messages:128,max_bytes:M});let _=function(e,i){let t;if(null!==i.cause_delivery_id){let n=Ne(e,i.cause_delivery_id);if(void 0===n||n.target_durable_id!==i.sender_node||"admitting"!==n.state&&"admitted"!==n.state&&"applied"!==n.state)return be("invalid_arguments","The delivery this send continues is not one the sender received.",{guard:"unknown_cause"});t={root_id:n.root_id,hop:n.hop+1,via:[...n.envelope.via,i.sender_node],new_root:!1}}else t={root_id:`root-${v()}`,hop:1,via:[i.sender_node],new_root:!0};if(null!==i.claimed_root_id&&i.claimed_root_id!==t.root_id)return be("invalid_arguments","The causal root is derived by the gateway and cannot be chosen by the caller.",{guard:"forged_root"});if(!t.new_root){let n=e.sql.one(["expires_at"],"SELECT expires_at FROM causal_roots WHERE root_id = ?",[t.root_id]);if(void 0===n||Number(n.expires_at)<=i.now)return be("loop_detected","This causal chain is older than its lifetime.",{guard:"root_expired",root_id:t.root_id})}if(i.target_durable_id===i.sender_node)return be("loop_detected","A session cannot deliver to itself through the gateway.",{guard:"self_send"});if(t.hop>4)return be("loop_detected",`This delivery would be hop ${t.hop}; at most 4 are allowed.`,{guard:"hop_limit",hop:t.hop});let n=Number(e.sql.one(["n"],"SELECT COUNT(*) AS n FROM deliveries WHERE root_id = ? AND state != 'refused'",[t.root_id])?.n??0);return n>=64?be("loop_detected",`This causal chain already carried ${n} deliveries.`,{guard:"causal_budget",root_id:t.root_id}):I(e.sql.all(["from_durable_id","to_durable_id"],"SELECT from_durable_id, to_durable_id FROM causal_edges WHERE root_id = ?",[t.root_id]).map(e=>({from:String(e.from_durable_id),to:String(e.to_durable_id)})),i.sender_node,i.target_durable_id)?be("loop_detected","The target already leads back to the sender in this causal chain.",{guard:"cycle",root_id:t.root_id}):t}(e,i);if("kind"in _)return we(e),_;let u=function(e,i){if(null===i.sender_turn)return;let t=new Set(e.sql.all(["t"],"SELECT DISTINCT target_durable_id AS t FROM deliveries WHERE sender = ? AND sender_turn = ? AND state != 'refused'",[i.sender_principal,i.sender_turn]).map(e=>String(e.t)));return t.has(i.target_durable_id)||t.size<16?void 0:be("overloaded","One turn may reach at most 16 sessions.",{budget:"fanout"})}(e,i)??function(e,i){let t=i.rate_principal??i.sender_principal,n=e.sql.one(["tokens","updated_at"],"SELECT tokens, updated_at FROM rate_buckets WHERE sender = ? AND target_durable_id = ?",[t,i.target_durable_id]),r=void 0===n?8:Math.min(8,Number(n.tokens)+Math.max(0,i.now-Number(n.updated_at))/D);if(r<1)return be("overloaded","Too many deliveries to this session; wait before sending again.",{budget:"pair_rate",retry_after_ms:Math.ceil((1-r)*D)});ye(e,"INSERT INTO rate_buckets (sender, target_durable_id, tokens, updated_at) VALUES (?, ?, ?, ?) ON CONFLICT(sender, target_durable_id) DO UPDATE SET tokens = excluded.tokens, updated_at = excluded.updated_at",[t,i.target_durable_id,r-1,i.now])}(e,i);if(void 0!==u)return we(e),u;_.new_root&&ye(e,"INSERT INTO causal_roots (root_id, origin_principal, created_at, expires_at) VALUES (?, ?, ?, ?)",[_.root_id,i.sender_principal,i.now,i.now+C]),ye(e,"INSERT OR IGNORE INTO causal_edges (root_id, from_durable_id, to_durable_id, delivery_id, created_at) VALUES (?, ?, ?, ?, ?)",[_.root_id,i.sender_node,i.target_durable_id,i.delivery_id,i.now]);let l={delivery_id:i.delivery_id,target_durable_id:i.target_durable_id,seq:Se(e,i.target_durable_id),sender:i.sender_principal,sender_turn:i.sender_turn,envelope:{origin:i.origin,actor:i.actor,via:_.via,root_id:_.root_id,hop:_.hop,delivery_id:i.delivery_id},body:i.body,bytes:o,mode_requested:i.mode,mode_effective:null,expected_turn_id:i.expected_turn_id,state:"queued",reason:null,admitted_by:null,claimed_at:null,attempt:0,admission_kind:null,turn_epoch:null,root_id:_.root_id,hop:_.hop,created_at:i.now,updated_at:i.now,expires_at:Math.min(i.now+U,s.expires_at??Number.POSITIVE_INFINITY),binding_id:i.binding?.binding_id??null,binding_revision:i.binding?.revision??null};Ae(e,l),ye(e,"INSERT INTO receipts (principal, operation, idempotency_key, args_hash, status, delivery_id, owner_instance, created_at, updated_at, expires_at) VALUES (?, 'deliver', ?, ?, 'prepared', ?, ?, ?, ?, ?)",[i.sender_principal,i.receipt.idempotency_key,i.receipt.args_hash,l.delivery_id,e.config.instance_id,i.now,i.now,i.now+H]),t=ke(e,l.target_durable_id,l.delivery_id,!1);let c=ve(e,l);return oe(e,i.now,r),await e.hook("beforeDbCommit"),e.sql.exec("COMMIT"),n=!0,await e.hook("afterDbCommit"),{kind:"inserted",row:l,queue_position:c}}catch(i){throw n||(we(e),null!==t&&S(t,{force:!0})),i}}function Ce(e,i){if(null===e)return"";let t=i.get(e);if(void 0===t){try{t=O(e,"utf8")}catch(e){if(!(e instanceof Error&&"code"in e&&"ENOENT"===e.code))throw e;t=""}i.set(e,t)}return t}function Me(e,i,t){if(null===e.runtime_instance||null===i)return!1;let n=t().get(e.runtime_instance);return void 0!==n&&i<=n}function He(e,i,t){for(let n of Ce(e,t).split("\n")){if(!n.includes(i))continue;let e;try{e=JSON.parse(n)}catch{continue}if("object"!=typeof e||null===e)continue;let t=e;if("custom_message"===t.type&&"session_control_delivery"===t.customType&&t.details?.delivery_id===i)return!0}return!1}function We(e){return`${JSON.stringify(e.admitted_by)}#${e.attempt}`}function Xe(e,i,t,n,r={}){"queued"!==t?"refused"!==t?(ye(e,"UPDATE deliveries SET state = ?, updated_at = ? WHERE delivery_id = ?",[t,n,i.delivery_id]),"applied"===t&&ye(e,"UPDATE session_meta SET applied_seq = MAX(applied_seq, ?) WHERE durable_id = ?",[i.seq,i.target_durable_id])):ye(e,"UPDATE deliveries SET state = 'refused', reason = ?, updated_at = ? WHERE delivery_id = ?",[r.reason??null,n,i.delivery_id]):ye(e,"UPDATE deliveries SET state = 'queued', admitted_by = NULL, claimed_at = NULL, mode_effective = NULL, admission_kind = NULL, turn_epoch = NULL, updated_at = ? WHERE delivery_id = ?",[n,i.delivery_id])}async function Fe(e,i){let t,n=i.target_durable_id,r=new Map,d=new Map,s=new Map,a=()=>(t??=function(e,i){let t=new Map;for(let n of Ce(e,i).split("\n")){if(!n.includes(F))continue;let e;try{e=JSON.parse(n)}catch{continue}let i=e;if("custom"!==i.type||i.customType!==F)continue;let r=i.data?.host_instance,d="string"==typeof i.data?.released_at?Date.parse(i.data.released_at):Number.NaN;"string"==typeof r&&0!==r.length&&Number.isFinite(d)&&t.set(r,Math.max(d,t.get(r)??d))}return t}(i.session_path,d),t);for(let t of Te(e,"target_durable_id = ? AND state IN ('admitting', 'admitted')",[n])){if(null===t.admitted_by||b(t.admitted_by,i.self))continue;let e=JSON.stringify(t.admitted_by),n=s.get(e);void 0===n&&(n=await m(t.admitted_by),s.set(e,n));let o=n||Me(t.admitted_by,t.claimed_at,a)?He(i.session_path,t.delivery_id,d)?"applied":"queued":"dual";r.set(t.delivery_id,{fingerprint:We(t),to:o})}return!0===e.config.test_hooks.announceBarrier&&e.emit({kind:"barrier",op:"reconcile"}),await Le(e,"reconcile",()=>{let t=new Set(i.ledger.pending),d=new Set(i.ledger.emitted),s=[],a=[];for(let o of Te(e,`target_durable_id = ? AND state IN ${ge}`,[n],"seq")){let n=o.state;if("queued"!==o.state){if(null!==o.admitted_by&&b(o.admitted_by,i.self))n=d.has(o.delivery_id)?"applied":t.has(o.delivery_id)?"admitted":"queued";else if(null===o.admitted_by)n="queued";else{let e=r.get(o.delivery_id);if(void 0===e||e.fingerprint!==We(o)||"dual"===e.to){a.push(o.delivery_id);continue}n=e.to}n!==o.state&&(Xe(e,o,n,i.now),s.push({delivery_id:o.delivery_id,from:o.state,to:n}))}else o.expires_at<=i.now&&(Xe(e,o,"refused",i.now,{reason:"expired"}),s.push({delivery_id:o.delivery_id,from:o.state,to:"refused"}))}for(let i of Oe(e,n))"queued"!==e.sql.one(["state"],"SELECT state FROM deliveries WHERE delivery_id = ?",[i])?.state&&Re(e,n,i);return{queued:Te(e,"target_durable_id = ? AND state = 'queued'",[n],"seq"),transitions:s,dual_runtime:a}})}function $e(){try{return q().username}catch{return"unknown"}}import{randomUUID as Ge}from"node:crypto";import{renameSync as Pe,writeFileSync as Be}from"node:fs";var Je=["question","select","confirm","input","editor"];var Ke=new Map([["yes",!0],["y",!0],["true",!0],["no",!1],["n",!1],["false",!1]]);function Ye(e){return""===e.replace(/[\s\p{Cf}]/gu,"")}function je(e){let i=Ke.get(e.trim().toLowerCase());return void 0===i?{value:e,answers:{},comment:e}:{value:e,answers:{},comment:e,confirmed:i}}function Ve(e,i){switch(e){case null:return Ye(i)?{ok:!1,reason:"The question declared no request kind, so the answer needs text; this one is blank. An input or editor that takes an empty answer must be reported with its request kind."}:{ok:!0,fields:je(i)};case"input":case"editor":return{ok:!0,fields:{value:i}};case"select":return Ye(i)?{ok:!1,reason:"A select answer names one of its options; the text is blank."}:{ok:!0,fields:{value:i}};case"question":return Ye(i)?{ok:!1,reason:"A question answer needs text; this one is blank."}:{ok:!0,fields:{answers:{},comment:i}};case"confirm":{let e=Ke.get(i.trim().toLowerCase());return void 0===e?{ok:!1,reason:"A confirm answer is yes or no (also y/n, true/false; any case, surrounding spaces ignored)."}:{ok:!0,fields:{confirmed:e}}}default:return function(e){throw Error(`unknown extension UI request kind: ${String(e)}`)}(e)}}var ze=["binding_id","schema_version","revision","status","platform","account_id","chat_id","thread_id","root_message_id","progress_message_id","session_realm_id","session_durable_id","direction_inbound","direction_outbound","inbound_mode","outbound_events","policy_id","created_at","updated_at","lease_started_at","ttl_seconds","expires_at"],Ze=["cursor","binding_id","revision","event_kind","payload","state","provider_message_id","created_at","reply_token","question_state","outcome","answered_by"];function Qe(e,i,t){return{kind:"refused",code:e,message:i,...void 0===t?{}:{details:t}}}function ei(e){return null==e?null:String(e)}function ii(e){return null==e?null:JSON.stringify(e)}function ti(e){return null==e?null:JSON.parse(String(e))}function ni(e,i,t,n){let r=(s=e.config.agent_dir,_(u(s),"outbox.marker")),d=`${r}.${process.pid}.${Ge()}.tmp`;var s;Be(d,JSON.stringify({binding_id:i,cursor:t,written_at:ie(n)}),{mode:384}),Pe(d,r)}function ri(e){return{schema_version:1,binding_id:String(e.binding_id),revision:Number(e.revision),status:e.status,platform:e.platform,account_id:String(e.account_id),chat_id:String(e.chat_id),thread_id:String(e.thread_id),root_message_id:ei(e.root_message_id),progress_message_id:ei(e.progress_message_id),session_realm_id:String(e.session_realm_id),session_durable_id:String(e.session_durable_id),direction:{inbound:1===Number(e.direction_inbound),outbound:1===Number(e.direction_outbound)},inbound_mode:e.inbound_mode,outbound_events:JSON.parse(String(e.outbound_events)),policy_id:String(e.policy_id),created_at:String(e.created_at),updated_at:String(e.updated_at),lease_started_at:String(e.lease_started_at),ttl_seconds:null===e.ttl_seconds||void 0===e.ttl_seconds?null:Number(e.ttl_seconds),expires_at:ei(e.expires_at)}}function di(e,i,t,n){let r=`SELECT ${ze.join(", ")} FROM bindings WHERE ${i}${void 0===n?"":` ORDER BY ${n.orderBy} LIMIT ?`}`;return e.sql.all(ze,r,void 0===n?t:[...t,n.limit],n?.orderBy).map(ri)}function si(e,i){return di(e,"binding_id = ?",[i])[0]}function ai(e,i){let t=e.sql.one(["value"],"SELECT value FROM gateway_meta WHERE key = ?",[i]);if(void 0===t)throw Error(`gateway_meta ${i} is missing`);return String(t.value)}function oi(e,i){let t=ie(i);ye(e,"UPDATE bindings SET status = 'expired', updated_at = ? WHERE status = 'active' AND expires_at IS NOT NULL AND expires_at <= ?",[t,t])}function _i(e,i){ye(e,"DELETE FROM outbox WHERE state = 'acked' AND acked_at IS NOT NULL AND acked_at <= ?",[i-ee]),ye(e,"DELETE FROM outbox WHERE state = 'pending' AND binding_id IN (SELECT binding_id FROM bindings WHERE status != 'active' AND updated_at <= ?)",[ie(i-ee)])}function ui(e,i){let t=e.sql.one(["args_hash","status","owner_instance","result"],"SELECT args_hash, status, owner_instance, result FROM receipts WHERE principal = ? AND operation = ? AND idempotency_key = ?",[i.principal,i.operation,i.idempotency_key]);if(void 0!==t)return{args_hash:String(t.args_hash),status:String(t.status),owner_instance:String(t.owner_instance),result:ei(t.result)}}async function li(e,i,t,n,r){return await Le(e,i,()=>{oi(e,t);let i=null===n?0:ae(e,n,t),d=function(e,i){if(null===i)return;let t=ui(e,i);return void 0!==t?t.args_hash!==i.args_hash?Qe("idempotency_conflict","The idempotency key was already used with different arguments."):"completed"===t.status&&null!==t.result?{...JSON.parse(t.result),kind:"ok",deduplicated:!0}:Qe("idempotency_uncertain","An earlier call under this key did not record its outcome."):void 0}(e,n);if(void 0!==d)return d;let s=r();return"ok"===s.kind&&function(e,i,t,n){null!==i&&ye(e,"INSERT INTO receipts (principal, operation, idempotency_key, args_hash, status, delivery_id, owner_instance, result, created_at, updated_at, expires_at) VALUES (?, ?, ?, ?, 'completed', NULL, ?, ?, ?, ?, ?)",[i.principal,i.operation,i.idempotency_key,i.args_hash,e.config.instance_id,JSON.stringify(n),t,t,t+H])}(e,n,t,{...s,deduplicated:!1}),oe(e,t,i),"ok"===s.kind?{...s,deduplicated:!1}:s})}async function ci(e,i){return await Le(e,"tool_receipt_begin",()=>{let t=ae(e,i,i.now),n=function(e,i){let t=ui(e,i);if(void 0===t)return ye(e,"INSERT INTO receipts (principal, operation, idempotency_key, args_hash, status, delivery_id, owner_instance, created_at, updated_at, expires_at) VALUES (?, ?, ?, ?, 'prepared', NULL, ?, ?, ?, ?)",[i.principal,i.operation,i.idempotency_key,i.args_hash,e.config.instance_id,i.now,i.now,i.now+H]),{kind:"accepted"};if(t.args_hash!==i.args_hash)return{kind:"conflict"};if("completed"===t.status)return{kind:"replay",result:null===t.result?null:JSON.parse(t.result)};if("prepared"===t.status&&t.owner_instance===e.config.instance_id)return{kind:"in_progress"};"prepared"===t.status&&ye(e,"UPDATE receipts SET status = 'uncertain', error_note = ?, updated_at = ? WHERE principal = ? AND operation = ? AND idempotency_key = ?",["the process that began this call ended before recording its outcome",i.now,i.principal,i.operation,i.idempotency_key]);let n=e.sql.one(["error_note"],"SELECT error_note FROM receipts WHERE principal = ? AND operation = ? AND idempotency_key = ?",[i.principal,i.operation,i.idempotency_key]);return{kind:"uncertain",error_note:ei(n?.error_note)}}(e,i);return oe(e,i.now,t),n})}function pi(e,i){return e.sql.all(["delivery_id"],`SELECT delivery_id, seq FROM deliveries WHERE binding_id = ? AND state IN ${ge}`,[i],"seq").map(e=>String(e.delivery_id))}async function Ei(e,i){let t=void 0===i.cursor?null:function(e){try{let i=JSON.parse(Buffer.from(e,"base64url").toString("utf8"));if(1!==i.v||"number"!=typeof i.as_of||!Number.isInteger(i.as_of))return null;let t=i.after;return null===t||Array.isArray(t)&&2===t.length&&t.every(e=>"string"==typeof e)?{v:1,as_of:i.as_of,after:t}:null}catch{return null}}(i.cursor);if(void 0!==i.cursor&&null===t)return Qe("cursor_invalid","The bindings cursor is not one this gateway issued.");let n=Math.min(Math.max(i.limit??50,1),200);return await Le(e,"list_bindings",()=>{oi(e,i.now);let r=t?.as_of??Number(e.sql.one(["m"],"SELECT COALESCE(MAX(rowid), 0) AS m FROM bindings")?.m??0),d=["rowid <= ?"],s=[r],a=[["session_durable_id","session_durable_id"],["platform","platform"],["account_id","account_id"],["chat_id","chat_id"],["thread_id","thread_id"],["status","status"]];for(let[e,t]of a){let n=i.filter[e];void 0!==n&&(d.push(`${t} = ?`),s.push(n))}null!=t?.after&&(d.push("(created_at > ? OR (created_at = ? AND binding_id > ?))"),s.push(t.after[0],t.after[0],t.after[1]));let o=di(e,d.join(" AND "),s,{orderBy:"created_at, binding_id",limit:n+1}),_=o.slice(0,n),u=_.at(-1);return{kind:"ok",bindings:_,next_cursor:o.length>n&&void 0!==u?ne(r,[u.created_at,u.binding_id]):null}})}function gi(e,i){return ei(e.sql.one(["incarnation"],"SELECT incarnation FROM session_meta WHERE durable_id = ?",[i])?.incarnation)}function mi(e,i){ye(e,"INSERT INTO outbox (binding_id, revision, event_kind, payload, state, provider_message_id, created_at, acked_at, session_durable_id, reply_token, ui_request_id, ui_request_kind, incarnation, question_state, answer, answered_at, outcome) VALUES (?, ?, ?, ?, 'pending', NULL, ?, NULL, ?, ?, ?, ?, ?, ?, NULL, NULL, ?)",[i.binding.binding_id,i.binding.revision,i.event,JSON.stringify({text:i.text}),i.now,i.binding.session_durable_id,i.reply_token??null,i.ui_request_id??null,i.ui_request_kind??null,i.incarnation??null,void 0===i.reply_token?null:"pending",i.outcome??null]);let t=Number(e.sql.one(["c"],"SELECT last_insert_rowid() AS c")?.c);return ni(e,i.binding.binding_id,t,i.now),t}async function bi(e,i){return await li(e,"report",i.now,i.receipt,()=>{let t=null===i.binding_id?function(e,i,t,n){let r=[...new Set(t.flatMap(t=>{let n=e.sql.one(["binding_id"],"SELECT binding_id FROM deliveries WHERE delivery_id = ? AND target_durable_id = ?",[t,i]),r=ei(n?.binding_id);return null===r?[]:[r]}))].sort(),d=e.sql.all(["binding_id"],"SELECT binding_id FROM bindings WHERE session_durable_id = ? AND status = 'active' AND direction_outbound = 1",[i],"binding_id").map(e=>String(e.binding_id)),[s,...a]=r;if(void 0!==s&&a.length>0)return Qe("invalid_arguments",`This session's current run answers messages from ${r.length} bound threads; name binding_id.`,{binding_ids:r});if(void 0!==s&&n&&d.some(e=>e!==s))return Qe("invalid_arguments","This session's current run answers a bound thread's message and a user message (typed in its terminal or sent by an extension) together; name binding_id.",{binding_ids:d});if(void 0!==s)return{binding_id:s};let[o,..._]=d;return void 0!==o&&0===_.length?{binding_id:o}:void 0===o?Qe("invalid_arguments","This session has no active outbound binding and its current run answers no bound message; name binding_id."):Qe("invalid_arguments",`This session has ${d.length} active outbound bindings and its current run answers no bound message; name binding_id.`,{binding_ids:d})}(e,i.session_durable_id,i.origin_delivery_ids,!0===i.origin_local_input):{binding_id:i.binding_id};if("kind"in t)return t;let n=t.binding_id,r=si(e,n);if(void 0===r)return Qe("not_found","No binding has this id.",{binding_id:n});if(r.session_durable_id!==i.session_durable_id)return Qe("scope_denied","The binding is attached to another session.",{binding_id:n});if("active"!==r.status)return Qe("binding_inactive",`The binding is ${r.status}.`,{binding_id:n,status:r.status});if(!r.direction.outbound)return Qe("unsupported","The binding carries no outbound direction.",{binding_id:n,direction:r.direction});if(!r.outbound_events.includes(i.event))return Qe("unsupported",`The binding is not subscribed to ${i.event} events.`,{binding_id:n,outbound_events:r.outbound_events});if(null!==i.ui_request_kind&&"question"!==i.event)return Qe("invalid_arguments","Only a question names a request kind.");let d={binding_id:n,revision:r.revision,event:i.event};if("completion"===i.event){ye(e,"INSERT INTO completion_arms (session_durable_id, binding_id, revision, text, armed_at) VALUES (?, ?, ?, ?, ?)",[i.session_durable_id,n,r.revision,i.text,i.now]);let t=Number(e.sql.one(["s"],"SELECT last_insert_rowid() AS s")?.s);return{kind:"ok",...d,cursor:null,reply_token:null,armed:!0,arm_seq:t}}if("question"===i.event){if(null===i.ui_request_id)return Qe("invalid_arguments","A question names the session's pending extension UI request (request_id).");let t=gi(e,i.session_durable_id),s=function(e,i){let t={b:i.binding_id,r:i.revision,s:i.session_durable_id,i:i.incarnation,q:i.ui_request_id,n:Z()},n=te(JSON.stringify(t));return`${re}.${n}.${de(e,n)}`}(ai(e,"token_secret"),{binding_id:n,revision:r.revision,session_durable_id:i.session_durable_id,incarnation:t,ui_request_id:i.ui_request_id}),a=mi(e,{binding:r,event:"question",text:i.text,now:i.now,reply_token:s,ui_request_id:i.ui_request_id,...null===i.ui_request_kind?{}:{ui_request_kind:i.ui_request_kind},incarnation:t});return _i(e,i.now),{kind:"ok",...d,cursor:a,reply_token:s,armed:!1,arm_seq:null}}let s=mi(e,{binding:r,event:i.event,text:i.text,now:i.now});return _i(e,i.now),{kind:"ok",...d,cursor:s,reply_token:null,armed:!1,arm_seq:null}})}function fi(e,i){return Number(e.sql.one(["acked_cursor"],"SELECT acked_cursor FROM outbox_cursors WHERE binding_id = ?",[i])?.acked_cursor??0)}async function Ti(e,i){let t=Math.min(Math.max(i.limit??100,1),500);return await Le(e,"read_outbox",()=>{oi(e,i.now),_i(e,i.now);let n=si(e,i.binding_id);if(void 0===n)return Qe("not_found","No binding has this id.",{binding_id:i.binding_id});let r=fi(e,n.binding_id),d=i.after_cursor??r,s=e.sql.all(Ze,`SELECT ${Ze.join(", ")} FROM outbox WHERE binding_id = ? AND cursor > ? ORDER BY cursor LIMIT ?`,[n.binding_id,d,t],"cursor").map(e=>function(e,i){let t=e.event_kind;return{cursor:Number(e.cursor),binding_id:String(e.binding_id),revision:Number(e.revision),event:t,text:String(JSON.parse(String(e.payload)).text??""),state:e.state,created_at:ie(Number(e.created_at)),edit_message_id:"milestone"===t?i.progress_message_id:null,provider_message_id:ei(e.provider_message_id),reply_token:ei(e.reply_token),question_state:e.question_state??null,outcome:e.outcome??null,answered_by:ti(e.answered_by)}}(e,n));return oe(e,i.now),{kind:"ok",binding_id:n.binding_id,revision:n.revision,status:n.status,rows:s,next_cursor:s.at(-1)?.cursor??d,acked_cursor:r}})}async function Ni(e,i){return await Le(e,"claim_answer",()=>{oi(e,i.now);let t=function(e,i){let t=i.split(".");if(3!==t.length||t[0]!==re)return null;let n=Buffer.from(de(e,t[1])),r=Buffer.from(t[2]);if(n.length!==r.length||!Q(n,r))return null;try{let e=JSON.parse(Buffer.from(t[1],"base64url").toString("utf8"));return"string"!=typeof e.b||"number"!=typeof e.r||"string"!=typeof e.s||"string"!=typeof e.q||null!==e.i&&"string"!=typeof e.i?null:{binding_id:e.b,revision:e.r,session_durable_id:e.s,incarnation:e.i??null,ui_request_id:e.q}}catch{return null}}(ai(e,"token_secret"),i.reply_token);if(null===t)return Qe("invalid_arguments","This is not a reply token this gateway issued.");if(t.binding_id!==i.binding_id)return Qe("binding_mismatch","The answer arrived through a different binding than the one that asked the question.",{binding_id:i.binding_id});let n=e.sql.one(["cursor","question_state","answer_state","answer","answered_at","answered_by","ui_request_id","ui_request_kind","session"],"SELECT cursor, question_state, answer_state, answer, answered_at, answered_by, ui_request_id, ui_request_kind, session_durable_id AS session FROM outbox WHERE reply_token = ? AND binding_id = ?",[i.reply_token,t.binding_id]);if(void 0===n)return Qe("not_found","The question this token belongs to is no longer in the outbox.");let r="answered"===n.question_state&&"delivered"!==n.answer_state,d=r&&Number(n.answered_at)+12e4<=i.now;if(r&&!d)return Qe("answer_in_progress","Another answer to this question is still being handed to the session.",{cursor:Number(n.cursor)});if("answered"===n.question_state&&!d)return Qe("already_answered",null===n.answer&&"delivered"===n.answer_state?"The session no longer waits for this question (answered or closed elsewhere).":"This question was already answered.",{cursor:Number(n.cursor)});let s="string"==typeof(o=n.ui_request_kind)&&Je.includes(o)?n.ui_request_kind:null,a=Ve(s,i.answer);var o;if(!a.ok)return Qe("invalid_arguments",a.reason,{ui_request_kind:s});let _=si(e,t.binding_id);return void 0===_||"active"!==_.status||_.revision!==t.revision||_.session_durable_id!==t.session_durable_id||gi(e,t.session_durable_id)!==t.incarnation||ei(n.ui_request_id)!==t.ui_request_id?Qe("stale_token","The binding or the session changed since the question was asked.",{binding_id:t.binding_id}):(ye(e,"UPDATE outbox SET question_state = 'answered', answer_state = 'in_flight', answer = ?, answered_at = ?, answered_by = ? WHERE reply_token = ?",[i.answer,i.now,ii(i.answered_by),i.reply_token]),{kind:"ok",session_durable_id:t.session_durable_id,ui_request_id:t.ui_request_id,ui_request_kind:s,cursor:Number(n.cursor),claimed_at:i.now,taken_over:d?{answer:ei(n.answer),answered_at:null===n.answered_at||void 0===n.answered_at?null:Number(n.answered_at),answered_by:ti(n.answered_by)}:null})})}var yi=a;if(null===yi)throw Error("the gateway store worker must run as a worker thread");var vi,hi,wi=[],Li=new Map,ki=!1;function Ri(e){yi?.postMessage({type:"event",event:e})}async function Oi(a,l){if("init"===a)return await async function(a){let{config:l}=a,c=u(l.agent_dir);n(d(c,"inbox"),{recursive:!0,mode:448}),e(c,448);let p=(E=l.agent_dir,_(u(E),"gateway.sqlite"));var E;i(r(p,"a",384)),e(p,384);let m=await(import("node:sqlite"));hi=new m.DatabaseSync(p,{timeout:l.busy_timeout_ms});let b=new f(hi);b.exec(`PRAGMA busy_timeout = ${Math.trunc(l.busy_timeout_ms)}`);let T=Date.now();for(;;)try{b.exec("PRAGMA journal_mode = WAL");break}catch(e){if(!N(e))throw e;let i=Date.now()-T;if(i+10>l.lock_wait_max_ms)throw Ri({kind:"lock_wait_exceeded",op:"open",waited_ms:i}),o("open",i,l.lock_wait_max_ms);await s(10)}b.exec("PRAGMA synchronous = FULL");for(let i of["-wal","-shm"])t(`${p}${i}`)&&e(`${p}${i}`,384);let y={pid:process.pid,process_start_time:await g(process.pid),instance_id:l.instance_id,runtime_instance:l.runtime_instance};vi={sql:b,config:l,self:y,stats:{writes:0,marker_unlinks:0,transactions:0},emit:Ri,hook:Si,delay:e=>s(e)},await async function(e){if(!(xe(e)>=pe.length))for(;;)if(!await Le(e,"migrate",()=>{let i=xe(e);if(i>=pe.length)return!1;for(let t of pe[i])e.sql.exec(t);return e.sql.exec(`PRAGMA user_version = ${i+1}`),!0}))return}(vi);let h=await async function(e,i){let t=0;for(let n of e.config.legacy_mailbox_directories){let r,d=`legacy_mailbox:${n}`;if(void 0!==e.sql.one(["value"],"SELECT value FROM gateway_meta WHERE key = ?",[d]))continue;try{r=B(n)}catch(i){e.emit({kind:"legacy_mailbox_invalid",directory:n,error:i instanceof Error?i.message:String(i)});continue}if(null===r)continue;let s=$e(),a=r.filter(e=>!me.test(e.target)).map(e=>({message_seq:e.message_seq,target:e.target,reason:"invalid_target"})),o=r.filter(e=>me.test(e.target));t+=await Le(e,"migrate_legacy",()=>{let t=0;for(let r of o){let d=`legacy-${qe([n,r.message_seq]).slice(0,32)}`;if(void 0!==Ne(e,d))continue;let a=`root-${v()}`,o=`legacy:${n}`;ye(e,"INSERT INTO causal_roots (root_id, origin_principal, created_at, expires_at) VALUES (?, ?, ?, ?)",[a,o,i,i+C]);let _=Date.parse(r.accepted_at);Ae(e,{delivery_id:d,target_durable_id:r.target,seq:Se(e,r.target),sender:o,sender_turn:null,envelope:{origin:{external:{platform:"legacy_mailbox",account_id:s,chat_id:n,thread_id:"@chat",message_id:r.operation_id}},actor:"legacy thread mailbox",via:[o],root_id:a,hop:1,delivery_id:d},body:r.message,bytes:Buffer.byteLength(r.message),mode_requested:r.delivery,mode_effective:null,expected_turn_id:r.expected_turn_id,state:"queued",reason:null,admitted_by:null,claimed_at:null,attempt:0,admission_kind:null,turn_epoch:null,root_id:a,hop:1,created_at:Number.isFinite(_)?_:i,updated_at:i,expires_at:i+U,binding_id:null,binding_revision:null}),ke(e,r.target,d,!0),t++}return ye(e,"INSERT INTO gateway_meta (key, value) VALUES (?, ?)",[d,JSON.stringify({migrated_at:i,count:t,skipped:a})]),t}),a.length>0&&e.emit({kind:"legacy_mailbox_skipped",directory:n,items:a})}return t}(vi,a.now);return vi.stats.writes=0,vi.stats.transactions=0,vi.stats.marker_unlinks=0,{self:y,legacy_migrated:h}}(l);if("close"===a)return hi?.close(),hi=void 0,vi=void 0,null;let c=function(){if(void 0===vi)throw Error("the gateway store is not open");return vi}();switch(a){case"enqueue":return await Ue(c,l);case"reconcile":return await Fe(c,l);case"claim":return await async function(e,i){return await Le(e,"claim",()=>{let t=Ne(e,i.delivery_id);return void 0===t||"queued"!==t.state?{kind:"lost",state:t?.state??null}:t.expires_at<=i.now?(Xe(e,t,"refused",i.now,{reason:"expired"}),Re(e,t.target_durable_id,t.delivery_id),{kind:"lost",state:"refused"}):(ye(e,"UPDATE deliveries SET state = 'admitting', admitted_by = ?, claimed_at = ?, attempt = attempt + 1, mode_effective = ?, updated_at = ? WHERE delivery_id = ? AND state = 'queued'",[JSON.stringify(i.self),i.now,i.lane,i.now,i.delivery_id]),Re(e,t.target_durable_id,t.delivery_id),{kind:"claimed",row:Ne(e,i.delivery_id)})})}(c,l);case"record_outcome":return await async function(e,i){return await Le(e,"record_outcome",()=>{let t=Ne(e,i.delivery_id);if(void 0===t||"admitting"!==t.state&&"admitted"!==t.state||null===t.admitted_by||!b(t.admitted_by,i.self))return{kind:"lost",state:t?.state??null};let n=i.outcome;return"requeue"===n.kind?Xe(e,t,"queued",i.now):"refused"===n.kind?Xe(e,t,"refused",i.now,{reason:n.reason}):(ye(e,"UPDATE deliveries SET admission_kind = ?, turn_epoch = ?, updated_at = ? WHERE delivery_id = ?",[n.admission_kind,n.turn_epoch,i.now,t.delivery_id]),t.state!==n.kind&&Xe(e,t,n.kind,i.now)),{kind:"claimed",row:Ne(e,i.delivery_id)}})}(c,l);case"refuse_queued":return await async function(e,i){return await Le(e,"refuse",()=>{let t=Ne(e,i.delivery_id);return void 0!==t&&"queued"===t.state&&(Xe(e,t,"refused",i.now,{reason:i.reason}),Re(e,t.target_durable_id,t.delivery_id),!0)})}(c,l);case"complete_receipt":return await async function(e,i){return await Le(e,"complete_receipt",()=>1===ye(e,"UPDATE receipts SET status = 'completed', result = ?, updated_at = ? WHERE principal = ? AND operation = 'deliver' AND idempotency_key = ? AND status = 'prepared' AND owner_instance = ?",[JSON.stringify(i.result),i.now,i.principal,i.idempotency_key,e.config.instance_id]))}(c,l);case"abandon_receipt":return await async function(e,i){return await Le(e,"abandon_receipt",()=>1===ye(e,"UPDATE receipts SET status = 'uncertain', error_note = ?, updated_at = ? WHERE principal = ? AND operation = 'deliver' AND idempotency_key = ? AND status = 'prepared' AND owner_instance = ?",[i.error_note,i.now,i.principal,i.idempotency_key,e.config.instance_id]))}(c,l);case"delivery_view":return function(e,i){let t=Ne(e,i);return void 0===t?null:{row:t,queue_position:ve(e,t)}}(c,l);case"delivery_receipt":return function(e,i){let t=Ie(e,i.principal,i.idempotency_key);if(void 0===t||t.expires_at<=i.now||null===t.delivery_id)return null;let n=Ne(e,t.delivery_id);if(void 0===n)return null;let r="completed"===t.status&&null!==t.result;return{args_hash:t.args_hash,completed:r,result:r?JSON.parse(t.result):null,target_durable_id:n.target_durable_id,binding_revision:n.binding_revision}}(c,l);case"recover_delivery":return await async function(e,i){return await Le(e,"recover_delivery",()=>{let t=Ie(e,i.principal,i.idempotency_key);return void 0===t||t.expires_at<=i.now?null:De(e,{now:i.now,sender_principal:i.principal,endpoint_kind:null,receipt:{idempotency_key:i.idempotency_key,args_hash:i.args_hash}},t)})}(c,l);case"list":return function(e,i){return void 0!==i.target_durable_id?Te(e,"target_durable_id = ?",[i.target_durable_id],"seq"):void 0!==i.root_id?Te(e,"root_id = ?",[i.root_id],"created_at, seq"):Te(e,"1 = 1",[],"created_at, seq")}(c,l);case"is_referenced":return function(e,i){return Number(e.sql.one(["n"],`SELECT COUNT(*) AS n FROM deliveries WHERE target_durable_id = ? AND state IN ${ge}`,[i])?.n??0)>0||Number(e.sql.one(["n"],"SELECT COUNT(*) AS n FROM bindings WHERE session_durable_id = ? AND status = 'active'",[i])?.n??0)>0||Oe(e,i).length>0}(c,l);case"journal_mode":return function(e){return String(e.sql.one(["journal_mode"],"SELECT journal_mode FROM pragma_journal_mode()")?.journal_mode??"")}(c);case"stats":return function(e){return{...e.stats}}(c);case"tool_receipt_begin":return await ci(c,l);case"tool_receipt_settle":return await async function(e,i){return await Le(e,"tool_receipt_settle",()=>{let t="result"in i;return 1===ye(e,`UPDATE receipts SET status = ?, ${t?"result":"error_note"} = ?, updated_at = ? WHERE principal = ? AND operation = ? AND idempotency_key = ? AND status = 'prepared' AND owner_instance = ?`,[t?"completed":"uncertain",t?JSON.stringify(i.result):i.error_note,i.now,i.principal,i.operation,i.idempotency_key,e.config.instance_id])})}(c,l);case"bind":return await async function(e,i){let t=i.binding;return await li(e,"bind",i.now,i.receipt,()=>{let n=di(e,"platform = ? AND account_id = ? AND chat_id = ? AND thread_id = ? AND status = 'active'",[t.platform,t.account_id,t.chat_id,t.thread_id])[0];if(void 0!==n)return Qe("binding_conflict",n.session_durable_id===t.session_durable_id?"This thread is already bound to that session.":"This thread is bound to another session; rebind it explicitly to move it.",{binding_id:n.binding_id,revision:n.revision,session:n.session_durable_id});let r=ie(i.now),d={schema_version:1,binding_id:`bnd-${Z()}`,revision:1,status:"active",platform:t.platform,account_id:t.account_id,chat_id:t.chat_id,thread_id:t.thread_id,root_message_id:t.root_message_id,progress_message_id:t.progress_message_id,session_realm_id:ai(e,"realm_id"),session_durable_id:t.session_durable_id,direction:t.direction,inbound_mode:t.inbound_mode,outbound_events:t.outbound_events,policy_id:t.policy_id,created_at:r,updated_at:r,lease_started_at:r,ttl_seconds:t.ttl_seconds,expires_at:null===t.ttl_seconds?null:ie(i.now+1e3*t.ttl_seconds)};return ye(e,`INSERT INTO bindings (${ze.join(", ")}) VALUES (${ze.map(()=>"?").join(", ")})`,[d.binding_id,d.schema_version,d.revision,d.status,d.platform,d.account_id,d.chat_id,d.thread_id,d.root_message_id,d.progress_message_id,d.session_realm_id,d.session_durable_id,d.direction.inbound?1:0,d.direction.outbound?1:0,d.inbound_mode,JSON.stringify(d.outbound_events),d.policy_id,d.created_at,d.updated_at,d.lease_started_at,d.ttl_seconds,d.expires_at]),{kind:"ok",binding:d}})}(c,l);case"unbind":return await async function(e,i){return await li(e,"unbind",i.now,i.receipt,()=>{let t=si(e,i.binding_id);if(void 0===t)return Qe("not_found","No binding has this id.",{binding_id:i.binding_id});if("active"!==t.status)return{kind:"ok",binding:t,already_closed:!0,in_flight:pi(e,t.binding_id)};if(t.revision!==i.expected_revision)return Qe("stale_revision","The binding changed since that revision.",{binding_id:t.binding_id,revision:t.revision});let n=ie(i.now);return ye(e,"UPDATE bindings SET status = 'detached', revision = revision + 1, updated_at = ? WHERE binding_id = ? AND revision = ?",[n,t.binding_id,t.revision]),ye(e,"DELETE FROM completion_arms WHERE binding_id = ?",[t.binding_id]),{kind:"ok",binding:si(e,t.binding_id),already_closed:!1,in_flight:pi(e,t.binding_id)}})}(c,l);case"rebind":return await async function(e,i){return await li(e,"rebind",i.now,i.receipt,()=>{let t=si(e,i.binding_id);if(void 0===t)return Qe("not_found","No binding has this id.",{binding_id:i.binding_id});if("active"!==t.status)return Qe("binding_inactive",`The binding is ${t.status}.`,{binding_id:t.binding_id,status:t.status});if(t.revision!==i.expected_revision)return Qe("stale_revision","The binding changed since that revision.",{binding_id:t.binding_id,revision:t.revision});if(t.session_durable_id===i.session_durable_id)return Qe("invalid_arguments","The binding is already attached to that session.",{binding_id:t.binding_id});let n=ie(i.now),r=e.sql.all(["delivery_id","target"],"SELECT delivery_id, target_durable_id AS target, seq FROM deliveries WHERE binding_id = ? AND binding_revision = ? AND state = 'queued'",[t.binding_id,t.revision],"seq").map(e=>({delivery_id:String(e.delivery_id),target:String(e.target)}));for(let t of r)ye(e,"UPDATE deliveries SET state = 'refused', reason = 'binding_closed', updated_at = ? WHERE delivery_id = ? AND state = 'queued'",[i.now,t.delivery_id]),Re(e,t.target,t.delivery_id);return ye(e,"UPDATE bindings SET session_durable_id = ?, revision = revision + 1, lease_started_at = ?, updated_at = ? WHERE binding_id = ? AND revision = ?",[i.session_durable_id,n,n,t.binding_id,t.revision]),ye(e,"DELETE FROM completion_arms WHERE binding_id = ?",[t.binding_id]),{kind:"ok",binding:si(e,t.binding_id),closed:r.map(e=>e.delivery_id)}})}(c,l);case"list_bindings":return await Ei(c,l);case"binding_view":return await async function(e,i){return await Le(e,"binding_view",()=>(oi(e,i.now),si(e,i.binding_id)??null))}(c,l);case"register_incarnation":return await async function(e,i){await Le(e,"register_incarnation",()=>{ye(e,"INSERT INTO session_meta (durable_id, next_seq, incarnation, endpoint_socket, endpoint_kind)\n VALUES (?, (SELECT COALESCE(MAX(seq), 0) + 1 FROM deliveries WHERE target_durable_id = ?), ?, ?, ?)\n ON CONFLICT(durable_id) DO UPDATE SET incarnation = excluded.incarnation,\n endpoint_socket = excluded.endpoint_socket, endpoint_kind = excluded.endpoint_kind",[i.durable_id,i.durable_id,i.incarnation,i.endpoint?.socket??null,i.endpoint?.kind??null])})}(c,l);case"clear_endpoint":return await async function(e,i){await Le(e,"clear_endpoint",()=>{ye(e,"UPDATE session_meta SET endpoint_socket = NULL, endpoint_kind = NULL WHERE durable_id = ? AND incarnation = ?",[i.durable_id,i.incarnation])})}(c,l);case"session_owner":return function(e,i){let t=e.sql.one(["incarnation","endpoint_socket","endpoint_kind"],"SELECT incarnation, endpoint_socket, endpoint_kind FROM session_meta WHERE durable_id = ?",[i]);return void 0===t||"string"!=typeof t.incarnation?null:{incarnation:t.incarnation,endpoint:"string"!=typeof t.endpoint_socket||"tui"!==t.endpoint_kind&&"rpc_host"!==t.endpoint_kind?null:{socket:t.endpoint_socket,kind:t.endpoint_kind}}}(c,l);case"report":return await bi(c,l);case"emit_completions":return await async function(e,i){return await Le(e,"emit_completions",()=>{oi(e,i.now);let t=["arm_seq","binding_id","revision","text"],n=void 0===i.through_arm_seq?e.sql.all(t,"SELECT arm_seq, binding_id, revision, text FROM completion_arms WHERE session_durable_id = ?",[i.session_durable_id],"arm_seq"):e.sql.all(t,"SELECT arm_seq, binding_id, revision, text FROM completion_arms WHERE session_durable_id = ? AND arm_seq <= ?",[i.session_durable_id,i.through_arm_seq],"arm_seq"),r=new Map;for(let i of n)ye(e,"DELETE FROM completion_arms WHERE arm_seq = ?",[Number(i.arm_seq)]),r.set(String(i.binding_id),i);let d=[];for(let t of[...r.values()].toSorted((e,i)=>String(e.binding_id)<String(i.binding_id)?-1:1)){let n=si(e,String(t.binding_id));void 0!==n&&"active"===n.status&&n.revision===Number(t.revision)&&n.session_durable_id===i.session_durable_id&&n.direction.outbound&&n.outbound_events.includes("completion")&&d.push({binding_id:n.binding_id,cursor:mi(e,{binding:n,event:"completion",text:String(t.text),now:i.now,outcome:i.outcome})})}return d}).then(t=>(e.emit({kind:"completions_emitted",session_durable_id:i.session_durable_id,cursors:t.map(e=>e.cursor)}),t))}(c,l);case"pending_completion_arms":return function(e,i){return Number(e.sql.one(["n"],"SELECT COUNT(*) AS n FROM completion_arms WHERE session_durable_id = ?",[i])?.n??0)}(c,l);case"latest_completion_arm":return function(e,i){let t=e.sql.one(["s"],"SELECT MAX(arm_seq) AS s FROM completion_arms WHERE session_durable_id = ?",[i])?.s;return null==t?null:Number(t)}(c,l);case"read_outbox":return await Ti(c,l);case"ack_outbox":return await async function(e,i){return await Le(e,"ack_outbox",()=>{oi(e,i.now);let t=si(e,i.binding_id);if(void 0===t)return Qe("not_found","No binding has this id.",{binding_id:i.binding_id});let n=fi(e,t.binding_id);if(i.cursor<=n)return{kind:"ok",binding_id:t.binding_id,acked_cursor:n,changed:!1};if(void 0===e.sql.one(["cursor"],"SELECT cursor FROM outbox WHERE binding_id = ? AND cursor = ?",[t.binding_id,i.cursor])){let n=Number(e.sql.one(["m"],"SELECT COALESCE(MAX(cursor), 0) AS m FROM outbox WHERE binding_id = ?",[t.binding_id])?.m??0);return Qe("cursor_invalid",i.cursor>n?"The cursor is past the newest outbox row of this binding.":"The cursor names no outbox row of this binding.",{newest:n})}return ye(e,"UPDATE outbox SET state = 'acked', acked_at = ? WHERE binding_id = ? AND cursor <= ? AND state = 'pending'",[i.now,t.binding_id,i.cursor]),ye(e,"INSERT INTO outbox_cursors (binding_id, acked_cursor, updated_at) VALUES (?, ?, ?) ON CONFLICT(binding_id) DO UPDATE SET acked_cursor = excluded.acked_cursor, updated_at = excluded.updated_at",[t.binding_id,i.cursor,i.now]),void 0!==i.provider_message_id&&(ye(e,"UPDATE outbox SET provider_message_id = ? WHERE binding_id = ? AND cursor = ?",[i.provider_message_id,t.binding_id,i.cursor]),"milestone"===e.sql.one(["event_kind"],"SELECT event_kind FROM outbox WHERE binding_id = ? AND cursor = ?",[t.binding_id,i.cursor])?.event_kind&&null===t.progress_message_id&&ye(e,"UPDATE bindings SET progress_message_id = ?, updated_at = ? WHERE binding_id = ?",[i.provider_message_id,ie(i.now),t.binding_id])),{kind:"ok",binding_id:t.binding_id,acked_cursor:i.cursor,changed:!0}})}(c,l);case"claim_answer":return await Ni(c,l);case"release_answer":return await async function(e,i){return await Le(e,"release_answer",()=>1===ye(e,"UPDATE outbox SET question_state = 'pending', answer_state = NULL, answer = NULL, answered_at = NULL, answered_by = NULL WHERE reply_token = ? AND question_state = 'answered' AND answer_state = 'in_flight' AND answered_at = ?",[i.reply_token,i.claimed_at]))}(c,l);case"confirm_answer":return await async function(e,i){return await Le(e,"confirm_answer",()=>1===ye(e,"UPDATE outbox SET question_state = 'answered', answer_state = 'delivered', answer = ?, answered_at = ?, answered_by = ? WHERE reply_token = ? AND answer_state IS NOT 'delivered'",[i.answer,i.claimed_at,ii(i.answered_by),i.reply_token]))}(c,l);case"mark_prior_delivered":return await async function(e,i){return await Le(e,"mark_prior_delivered",()=>1===ye(e,"UPDATE outbox SET answer_state = 'delivered', answer = ?, answered_at = ?, answered_by = ? WHERE reply_token = ? AND question_state = 'answered' AND answer_state = 'in_flight' AND answered_at = ?",[i.prior.answer,i.prior.answered_at,ii(i.prior.answered_by),i.reply_token,i.claimed_at]))}(c,l);default:throw Error(`unknown gateway store op: ${a}`)}}async function Si(e){let i=vi?.config.test_hooks[e];if(void 0===i)return;if("throw"===i)throw Error(`gateway test hook ${e}`);"sigkill"===i&&(process.kill(process.pid,"SIGKILL"),await new Promise(()=>{}));let t=new Promise(i=>Li.set(e,i));Ri({kind:"paused",hook:e}),await t}yi.on("message",e=>{if("resume"===e.type)return Li.get(e.hook)?.(),void Li.delete(e.hook);wi.push(e),async function(){if(ki)return;ki=!0;try{for(let e=wi.shift();void 0!==e;e=wi.shift())try{let i=await Oi(e.op,e.args);yi?.postMessage({type:"response",id:e.id,ok:!0,value:i})}catch(i){yi?.postMessage({type:"response",id:e.id,ok:!1,error:{message:i instanceof Error?i.message:String(i),stack:i instanceof Error?i.stack:void 0,code:"string"==typeof i?.code?i.code:void 0}})}}finally{ki=!1}}()});
1
+ // omo:gGHJi89BUhUYvOjoEhkNR6mF1sIhU-BhqtjivzJULn4:pztMtKjLILz7eWfZicLMYySc81mXJoY_fg8EJHmPq9Y
2
+ import{chmodSync as e,closeSync as t,existsSync as i,mkdirSync as n,openSync as r}from"node:fs";import{join as s}from"node:path";import{setTimeout as a}from"node:timers/promises";import{parentPort as o}from"node:worker_threads";function d(e,t,i){return Object.assign(Error(`gateway store lock wait exceeded: ${e} waited ${t} ms for the write lock (limit ${i} ms); another process holds it`),{code:"gateway_lock_wait_exceeded"})}function u(e){return"object"==typeof e&&null!==e&&"gateway_lock_wait_exceeded"===e.code}import{join as _}from"node:path";function l(e){return _(e,"gateway")}function c(e,t){return _(l(e),"inbox",t)}import{execFile as p}from"node:child_process";var g="epoch:",m=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];function b(e){return new Promise(t=>{p("ps",["-o","lstart=","-p",String(e)],{env:{...process.env,LC_ALL:"C",LANG:"C",TZ:"UTC"},windowsHide:!0,timeout:5e3},(e,i)=>{let n=null===e?function(e){let t=/^[A-Z][a-z]{2} ([A-Z][a-z]{2}) +(\d{1,2}) (\d{2}):(\d{2}):(\d{2}) (\d{4})$/.exec(e.trim());if(null===t)return null;let[,i,n,r,s,a,o]=t,d=m.indexOf(i);return d<0?null:Date.UTC(Number(o),d,Number(n),Number(r),Number(s),Number(a))/1e3}(i):null;t(null===n?null:`${g}${n}`)})})}async function f(e){if(!function(e){try{return process.kill(e,0),!0}catch(e){return!(e instanceof Error&&"code"in e&&"ESRCH"===e.code)}}(e.pid))return!0;if(null===e.process_start_time||!e.process_start_time.startsWith(g))return!1;let t=await b(e.pid);return null!==t&&t!==e.process_start_time}function E(e,t){return e.pid===t.pid&&e.process_start_time===t.process_start_time&&e.instance_id===t.instance_id}function*h(e){for(let t=0;t<e.length;){let i,n=t,r=e[t];if(r<=" ")for(i="space";t<e.length&&e[t]<=" ";)t++;else if("-"===r&&"-"===e[t+1])for(i="comment";t<e.length&&"\n"!==e[t];)t++;else if("/"===r&&"*"===e[t+1]){for(i="comment",t+=2;t<e.length&&("*"!==e[t]||"/"!==e[t+1]);)t++;t=Math.min(t+2,e.length)}else if("'"===r||'"'===r||"`"===r||"["===r){i="quoted";let n="["===r?"]":r;for(t++;t<e.length;)if(e[t++]===n){if("["===r||e[t]!==n)break;t++}}else if("?"===r||";"===r)i="?"===r?"parameter":"semicolon",t++;else for(i="text",t++;t<e.length&&e[t]>" "&&!["'",'"',"`","[","?",";","-","/"].includes(e[t]);)t++;yield{kind:i,text:e.slice(n,t)}}}class y{params=[];sinkRows=[];db;constructor(e){this.db=e,e.function("gw_p",{deterministic:!1},e=>this.params[e]??null),e.function("gw_sink",{varargs:!0,deterministic:!1},(...e)=>(this.sinkRows.push(e),null))}exec(e){this.db.exec(e)}authorized(e,t){this.db.setAuthorizer(e);try{return t()}finally{this.db.setAuthorizer(null)}}run(e,t=[]){this.params=t;try{this.db.exec(v(e))}finally{this.params=[]}return Number(this.all(["n"],"SELECT changes() AS n")[0]?.n??0)}all(e,t,i=[],n){this.params=i,this.sinkRows=[];try{let i=void 0===n?"0":`row_number() OVER (ORDER BY ${n})`;return this.db.exec(`SELECT gw_sink(${i}, ${e.join(", ")}) FROM (${v(t)}\n)${void 0===n?"":` ORDER BY ${n}`}`),(void 0===n?this.sinkRows:this.sinkRows.toSorted((e,t)=>Number(e[0])-Number(t[0]))).map(t=>Object.fromEntries(e.map((e,i)=>[e,t[i+1]??null])))}finally{this.params=[],this.sinkRows=[]}}one(e,t,i=[]){return this.all(e,t,i)[0]}}function v(e){let t=0,i="";for(let n of h(e))i+="parameter"===n.kind?`gw_p(${t++})`:n.text;return i}function w(e){if("object"!=typeof e||null===e)return!1;let t=e;return 5===t.errcode||6===t.errcode||"string"==typeof t.message&&/database is (locked|busy)/i.test(t.message)}import{createHash as T,randomUUID as N}from"node:crypto";import{closeSync as k,constants as L,mkdirSync as x,openSync as R,readdirSync as S,readFileSync as A,rmSync as O,writeSync as q}from"node:fs";import{userInfo as D}from"node:os";import{join as I}from"node:path";function C(e,t,i){return t===i||function(e,t,i){let n=new Map;for(let t of e){let e=n.get(t.from);void 0===e?n.set(t.from,[t.to]):e.push(t.to)}let r=new Set([t]),s=[t];for(;s.length>0;){let e=s.pop();if(e===i)return!0;for(let t of n.get(e)??[])r.has(t)||(r.add(t),s.push(t))}return!1}(e,i,t)}var U=5e3,M=864e5,$=6048e5,H=1048576,W=2592e6,X=2592e6,F=256,P="session_released";import{existsSync as j,readFileSync as B}from"node:fs";import{join as G}from"node:path";function J(e){let t=G(e,"mailbox.jsonl");if(j(t))return function(e){let t=e.slice(0,e.lastIndexOf("\n")+1),i=new Map;for(let e of t.split("\n")){if(0===e.length)continue;let t=JSON.parse(e);if(!z(t)||1!==t.version)throw Error("invalid legacy mailbox event");if("snapshot"===t.kind&&Array.isArray(t.items)){i.clear();for(let e of t.items){let t=Y(e);i.set(t.message_seq,t)}}else if("enqueue"===t.kind){let e=Y(t.item);i.set(e.message_seq,e)}else{if("remove"!==t.kind||"number"!=typeof t.message_seq)throw Error("invalid legacy mailbox event");i.delete(t.message_seq)}}return K([...i.values()])}(B(t,"utf8"));let i=G(e,"mailbox.json");if(!j(i))return null;let n=JSON.parse(B(i,"utf8"));if(!z(n)||!z(n.queues))throw Error(`invalid legacy mailbox state: ${i}`);let r=[];for(let e of Object.values(n.queues)){if(!Array.isArray(e))throw Error(`invalid legacy mailbox queue: ${i}`);for(let t of e)r.push(Y(t))}return K(r)}function K(e){return e.toSorted((e,t)=>e.message_seq-t.message_seq)}function Y(e){if(!z(e)||"string"!=typeof e.target||"string"!=typeof e.message||"number"!=typeof e.message_seq||!Number.isInteger(e.message_seq)||"auto"!==e.delivery&&"steer"!==e.delivery&&"follow_up"!==e.delivery||void 0!==e.expected_turn_id&&"string"!=typeof e.expected_turn_id||"string"!=typeof e.operation_id||"string"!=typeof e.accepted_at)throw Error("invalid legacy mailbox item");return{target:e.target,message:e.message,message_seq:e.message_seq,delivery:e.delivery,expected_turn_id:void 0===e.expected_turn_id?null:V(e.expected_turn_id),operation_id:e.operation_id,accepted_at:e.accepted_at}}function V(e){let t=/^turn-(0|[1-9]\d*)$/.exec(e);if(null===t)return null;let i=Number(t[1]);return Number.isSafeInteger(i)?i:null}function z(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}import{createHash as Q,createHmac as Z,randomUUID as ee,timingSafeEqual as te}from"node:crypto";var ie=["discord","telegram","slack","notion","feishu","herdr","custom"],ne=["milestone","report","question","completion"],re=["auto","follow_up"],se=31622400,ae=2592e6;function oe(e){return new Date(e).toISOString()}function de(e){return{kind:"refused",code:"invalid_arguments",message:e}}function ue(e,t){return"string"!=typeof t||0===t.trim().length?de(`${e} must be a non-empty string.`):t.length>256?de(`${e} is longer than 256 characters.`):/[\u0000-\u001f\u007f-\u009f\u2028\u2029]/.test(t)?de(`${e} carries a control character or a line separator.`):t}function _e(e,t){return null==t?null:ue(e,t)}function le(e){return"object"==typeof e&&null!==e&&"refused"===e.kind}function ce(e){if(null===e||"object"!=typeof e)return JSON.stringify(e)??"null";if(Array.isArray(e))return`[${e.map(ce).join(",")}]`;let t=e;return`{${Object.keys(t).filter(e=>void 0!==t[e]).sort().map(e=>`${JSON.stringify(e)}:${ce(t[e])}`).join(",")}}`}function pe(e){return Buffer.from(e).toString("base64url")}function ge(e,t){return pe(JSON.stringify({v:1,as_of:e,after:t}))}var me="rt1";function be(e,t){return Z("sha256",e).update(`${me}.${t}`).digest().subarray(0,16).toString("base64url")}var fe=new WeakMap;function Ee(e,t,i){return De(e,"DELETE FROM receipts WHERE principal = ? AND operation = ? AND idempotency_key = ? AND expires_at <= ?",[t.principal,t.operation,t.idempotency_key,i])}function he(e,t,i=0){if(t<(fe.get(e.sql)??Number.NEGATIVE_INFINITY))return null;let n=function(e,t,i=256){let n=F,r=De(e,"DELETE FROM receipts WHERE rowid IN (SELECT rowid FROM receipts WHERE expires_at <= ? LIMIT ?)",[t,i]),s=De(e,"DELETE FROM deliveries WHERE delivery_id IN (SELECT d.delivery_id FROM deliveries d WHERE d.state IN ('applied', 'refused') AND d.updated_at <= ? AND NOT EXISTS (SELECT 1 FROM receipts r WHERE r.delivery_id = d.delivery_id) LIMIT ?)",[t-X,n]),a=De(e,"DELETE FROM causal_edges WHERE rowid IN (SELECT e.rowid FROM causal_edges e JOIN causal_roots r ON r.root_id = e.root_id WHERE r.expires_at <= ? LIMIT ?)",[t,n]),o=De(e,"DELETE FROM causal_roots WHERE root_id IN (SELECT r.root_id FROM causal_roots r WHERE r.expires_at <= ? AND NOT EXISTS (SELECT 1 FROM causal_edges e WHERE e.root_id = r.root_id) LIMIT ?)",[t,n]),d=De(e,"DELETE FROM rate_buckets WHERE rowid IN (SELECT rowid FROM rate_buckets WHERE updated_at <= ? LIMIT ?)",[t-4e4,n]),u=De(e,`DELETE FROM bindings WHERE binding_id IN (SELECT b.binding_id FROM bindings b WHERE b.status != 'active' AND b.updated_at <= ?\n AND NOT EXISTS (SELECT 1 FROM outbox o WHERE o.binding_id = b.binding_id)\n AND NOT EXISTS (SELECT 1 FROM completion_arms a WHERE a.binding_id = b.binding_id)\n AND NOT EXISTS (SELECT 1 FROM deliveries d WHERE d.binding_id = b.binding_id AND d.state IN ${xe}) LIMIT ?)`,[oe(t-ae),n]),_=De(e,"DELETE FROM outbox_cursors WHERE binding_id IN (SELECT c.binding_id FROM outbox_cursors c WHERE NOT EXISTS (SELECT 1 FROM bindings b WHERE b.binding_id = c.binding_id) LIMIT ?)",[n]),l=De(e,"DELETE FROM session_meta WHERE durable_id IN (SELECT m.durable_id FROM session_meta m WHERE\n m.incarnation IS NULL\n AND NOT EXISTS (SELECT 1 FROM deliveries d WHERE d.target_durable_id = m.durable_id)\n AND NOT EXISTS (SELECT 1 FROM bindings b WHERE b.session_durable_id = m.durable_id)\n AND NOT EXISTS (SELECT 1 FROM outbox o WHERE o.session_durable_id = m.durable_id)\n AND NOT EXISTS (SELECT 1 FROM completion_arms a WHERE a.session_durable_id = m.durable_id) LIMIT ?)",[n]);return{receipts:r,deliveries:s,causal_edges:a,causal_roots:o,rate_buckets:d,bindings:u,outbox_cursors:_,session_meta:l}}(e,t,Math.max(F-i,0)),r=n.receipts+i>=F||Object.values(n).some(e=>e>=F);return fe.set(e.sql,r?t:t+36e5),n}var ye=new Set(["invalid_arguments","caller_context_missing","not_found","ambiguous_target","scope_denied","name_conflict","not_resumable","orphaned","foreign_live_owner","no_active_turn","turn_conflict","not_steerable","message_too_large","queue_full","cursor_invalid","cursor_stale","idempotency_conflict","idempotency_in_progress","idempotency_uncertain","approval_unavailable","approval_route_locked","partial_commit","unsupported","overloaded","transport_closed","host_unavailable","internal_error","model_not_found","model_ambiguous","thinking_level_unsupported","loop_detected","binding_conflict","binding_mismatch","binding_inactive","stale_revision","stale_token","already_answered","answer_in_progress"]);function ve(e,t,i,n){if("string"!=typeof(r=e)||!ye.has(r))throw Error(`unknown thread error code: ${String(e)}`);var r;return{code:e,message:t,next_action:i,...void 0===n?{}:{details:n}}}var we={not_steerable:{code:"not_steerable",next:"Send with delivery auto or follow_up; a steer needs a running turn."},turn_conflict:{code:"turn_conflict",next:"Read the target again and retry with its current turn id, or send with delivery auto."},expired:{code:"not_resumable",next:"The target did not take the message within its lifetime; send it again if it still matters."},binding_closed:{code:"invalid_arguments",next:"The binding this message was queued under was detached or rebound; re-read the binding and send again."}};function Te(e,t,i,n,r){let s={kind:"ok",thread_id:e.target_durable_id,delivery_id:e.delivery_id,message_seq:e.seq,effective_mode:e.mode_effective??e.mode_requested,endpoint_kind:i,deduplicated:n};if("admitted"===e.state||"applied"===e.state)return"started"===e.admission_kind||"steered"===e.admission_kind?{...s,delivery:{kind:e.admission_kind,turn_id:String(e.turn_epoch??0)}}:{...s,delivery:{kind:"queued",queue_position:Math.max(t,1)}};if("refused"===e.state){let t=we[e.reason??""]??{code:"internal_error",next:"Call thread_list and check the target."};return{kind:"error",error:ve(t.code,`Delivery ${e.delivery_id} was refused: ${e.reason??"unknown"}.`,t.next,{delivery_id:e.delivery_id})}}return"uncertain"===e.state?{kind:"error",error:ve("idempotency_uncertain",`Delivery ${e.delivery_id} may or may not have reached the target.`,"Read the target transcript before deciding whether to send again.",{delivery_id:e.delivery_id})}:{...s,delivery:{kind:r?"queued_offline":"queued",queue_position:Math.max(t,1)}}}class Ne extends Error{found;supported;code="gateway_schema_too_new";constructor(e,t,i="Gateway"){super(`${i} schema ${e} is newer than this binary's supported version ${t}.`),this.found=e,this.supported=t}}var ke=[["CREATE TABLE deliveries (\n delivery_id TEXT PRIMARY KEY,\n target_durable_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n sender TEXT NOT NULL,\n sender_turn TEXT,\n envelope TEXT NOT NULL,\n body TEXT NOT NULL,\n bytes INTEGER NOT NULL,\n mode_requested TEXT NOT NULL CHECK (mode_requested IN ('auto', 'steer', 'follow_up')),\n mode_effective TEXT CHECK (mode_effective IS NULL OR mode_effective IN ('steer', 'follow_up')),\n expected_turn_id INTEGER,\n state TEXT NOT NULL CHECK (state IN ('queued', 'admitting', 'admitted', 'applied', 'refused', 'uncertain')),\n reason TEXT,\n admitted_by TEXT,\n claimed_at INTEGER,\n attempt INTEGER NOT NULL DEFAULT 0,\n admission_kind TEXT,\n turn_epoch INTEGER,\n root_id TEXT NOT NULL,\n hop INTEGER NOT NULL,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n expires_at INTEGER NOT NULL,\n binding_id TEXT,\n binding_revision INTEGER,\n UNIQUE (target_durable_id, seq)\n )","CREATE INDEX deliveries_target_state_seq ON deliveries (target_durable_id, state, seq)","CREATE INDEX deliveries_root ON deliveries (root_id)","CREATE INDEX deliveries_sender_turn ON deliveries (sender, sender_turn)","CREATE TABLE receipts (\n principal TEXT NOT NULL,\n operation TEXT NOT NULL,\n idempotency_key TEXT NOT NULL,\n args_hash TEXT NOT NULL,\n status TEXT NOT NULL CHECK (status IN ('prepared', 'completed', 'uncertain')),\n delivery_id TEXT,\n owner_instance TEXT NOT NULL,\n result TEXT,\n error_note TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n expires_at INTEGER NOT NULL,\n PRIMARY KEY (principal, operation, idempotency_key)\n )","CREATE INDEX receipts_expiry ON receipts (expires_at)","CREATE TABLE causal_roots (\n root_id TEXT PRIMARY KEY,\n origin_principal TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n expires_at INTEGER NOT NULL\n )","CREATE TABLE causal_edges (\n root_id TEXT NOT NULL,\n from_durable_id TEXT NOT NULL,\n to_durable_id TEXT NOT NULL,\n delivery_id TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n PRIMARY KEY (root_id, from_durable_id, to_durable_id)\n )","CREATE TABLE rate_buckets (\n sender TEXT NOT NULL,\n target_durable_id TEXT NOT NULL,\n tokens REAL NOT NULL,\n updated_at INTEGER NOT NULL,\n PRIMARY KEY (sender, target_durable_id)\n )","CREATE TABLE session_meta (\n durable_id TEXT PRIMARY KEY,\n next_seq INTEGER NOT NULL,\n applied_seq INTEGER NOT NULL DEFAULT 0\n )","CREATE TABLE bindings (\n seq INTEGER PRIMARY KEY AUTOINCREMENT,\n binding_id TEXT NOT NULL UNIQUE,\n schema_version INTEGER NOT NULL DEFAULT 1,\n revision INTEGER NOT NULL CHECK (revision >= 1),\n status TEXT NOT NULL CHECK (status IN ('active', 'detached', 'expired')),\n platform TEXT NOT NULL CHECK (platform IN ('discord', 'telegram', 'slack', 'notion', 'feishu', 'herdr', 'custom')),\n account_id TEXT NOT NULL,\n chat_id TEXT NOT NULL,\n thread_id TEXT NOT NULL,\n root_message_id TEXT,\n progress_message_id TEXT,\n session_realm_id TEXT NOT NULL,\n session_durable_id TEXT NOT NULL,\n direction_inbound INTEGER NOT NULL CHECK (direction_inbound IN (0, 1)),\n direction_outbound INTEGER NOT NULL CHECK (direction_outbound IN (0, 1)),\n inbound_mode TEXT NOT NULL CHECK (inbound_mode IN ('auto', 'follow_up')),\n outbound_events TEXT NOT NULL,\n policy_id TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n lease_started_at TEXT NOT NULL,\n ttl_seconds INTEGER,\n expires_at TEXT,\n CHECK (direction_inbound = 1 OR direction_outbound = 1)\n )","CREATE UNIQUE INDEX bindings_one_active_thread ON bindings (platform, account_id, chat_id, thread_id) WHERE status = 'active'","CREATE INDEX bindings_session ON bindings (session_durable_id, status)","CREATE TABLE outbox (\n cursor INTEGER PRIMARY KEY AUTOINCREMENT,\n binding_id TEXT NOT NULL,\n revision INTEGER NOT NULL,\n event_kind TEXT NOT NULL CHECK (event_kind IN ('milestone', 'report', 'question', 'completion', 'question_closed')),\n payload TEXT NOT NULL,\n state TEXT NOT NULL CHECK (state IN ('pending', 'acked')),\n provider_message_id TEXT,\n created_at INTEGER NOT NULL,\n acked_at INTEGER\n )","CREATE INDEX outbox_binding_cursor ON outbox (binding_id, cursor)","CREATE TABLE gateway_meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n )"],["ALTER TABLE session_meta ADD COLUMN incarnation TEXT","ALTER TABLE outbox ADD COLUMN session_durable_id TEXT","ALTER TABLE outbox ADD COLUMN reply_token TEXT","ALTER TABLE outbox ADD COLUMN ui_request_id TEXT","ALTER TABLE outbox ADD COLUMN incarnation TEXT","ALTER TABLE outbox ADD COLUMN question_state TEXT CHECK (question_state IS NULL OR question_state IN ('pending', 'answered', 'expired', 'cancelled'))","ALTER TABLE outbox ADD COLUMN answer TEXT","ALTER TABLE outbox ADD COLUMN answered_at INTEGER","ALTER TABLE outbox ADD COLUMN outcome TEXT CHECK (outcome IS NULL OR outcome IN ('completed', 'failed', 'cancelled'))","CREATE UNIQUE INDEX outbox_reply_token ON outbox (reply_token) WHERE reply_token IS NOT NULL","CREATE TABLE outbox_cursors (\n binding_id TEXT PRIMARY KEY,\n acked_cursor INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n )","CREATE TABLE completion_arms (\n arm_seq INTEGER PRIMARY KEY AUTOINCREMENT,\n session_durable_id TEXT NOT NULL,\n binding_id TEXT NOT NULL,\n revision INTEGER NOT NULL,\n text TEXT NOT NULL,\n armed_at INTEGER NOT NULL\n )","CREATE INDEX completion_arms_session ON completion_arms (session_durable_id, armed_at)","INSERT OR IGNORE INTO gateway_meta (key, value) VALUES ('realm_id', 'realm-' || lower(hex(randomblob(16))))","INSERT OR IGNORE INTO gateway_meta (key, value) VALUES ('token_secret', lower(hex(randomblob(32))))"],["ALTER TABLE outbox ADD COLUMN ui_request_kind TEXT CHECK (ui_request_kind IS NULL OR ui_request_kind IN ('question', 'select', 'confirm', 'input', 'editor'))","ALTER TABLE outbox ADD COLUMN answer_state TEXT CHECK (answer_state IS NULL OR answer_state IN ('in_flight', 'delivered'))"],["ALTER TABLE outbox ADD COLUMN answered_by TEXT"],["ALTER TABLE session_meta ADD COLUMN endpoint_socket TEXT","ALTER TABLE session_meta ADD COLUMN endpoint_kind TEXT CHECK (endpoint_kind IS NULL OR endpoint_kind IN ('tui', 'rpc_host'))"],["CREATE TABLE extension_schema (name TEXT PRIMARY KEY, version INTEGER NOT NULL, updated_at INTEGER NOT NULL)","ALTER TABLE deliveries ADD COLUMN actor_user_id TEXT","CREATE TABLE extension_objects (type TEXT NOT NULL, name TEXT NOT NULL, owner TEXT, PRIMARY KEY (type, name))","INSERT INTO extension_objects (type, name, owner) SELECT type, name, NULL FROM sqlite_schema"]],Le=["delivery_id","target_durable_id","seq","sender","sender_turn","envelope","body","bytes","mode_requested","mode_effective","expected_turn_id","state","reason","admitted_by","claimed_at","attempt","admission_kind","turn_epoch","root_id","hop","created_at","updated_at","expires_at","binding_id","binding_revision","actor_user_id"],xe="('queued', 'admitting', 'admitted')",Re=/^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/;function Se(e,t,i){return{kind:"refused",code:e,message:t,...void 0===i?{}:{details:i}}}function Ae(e){let t=e=>null==e?null:Number(e);return{delivery_id:String(e.delivery_id),target_durable_id:String(e.target_durable_id),seq:Number(e.seq),sender:String(e.sender),sender_turn:null===e.sender_turn?null:String(e.sender_turn),envelope:JSON.parse(String(e.envelope)),body:String(e.body),bytes:Number(e.bytes),mode_requested:e.mode_requested,mode_effective:e.mode_effective??null,expected_turn_id:t(e.expected_turn_id),state:e.state,reason:null===e.reason?null:String(e.reason),admitted_by:null===e.admitted_by?null:JSON.parse(String(e.admitted_by)),claimed_at:t(e.claimed_at),attempt:Number(e.attempt),admission_kind:null===e.admission_kind?null:String(e.admission_kind),turn_epoch:t(e.turn_epoch),root_id:String(e.root_id),hop:Number(e.hop),created_at:Number(e.created_at),updated_at:Number(e.updated_at),expires_at:Number(e.expires_at),binding_id:null===e.binding_id?null:String(e.binding_id),binding_revision:t(e.binding_revision),actor_user_id:null===e.actor_user_id?null:String(e.actor_user_id)}}function Oe(e,t,i,n){return e.sql.all(Le,`SELECT ${Le.join(", ")} FROM deliveries WHERE ${t}`,i,n).map(Ae)}function qe(e,t){return Oe(e,"delivery_id = ?",[t])[0]}function De(e,t,i=[]){let n=e.sql.run(t,i);return e.stats.writes+=n,n}function Ie(e,t){if("queued"!==t.state&&"admitting"!==t.state&&"admitted"!==t.state)return 0;let i=e.sql.one(["n"],`SELECT COUNT(*) AS n FROM deliveries WHERE target_durable_id = ? AND state IN ${xe} AND seq <= ?`,[t.target_durable_id,t.seq]);return Number(i?.n??1)}async function Ce(e,t,i){if(void 0!==e.afterCommit)return e.sql.exec("SAVEPOINT gateway_enqueue"),!0;let n=Date.now();for(;;)try{return e.sql.exec("BEGIN IMMEDIATE"),e.stats.transactions++,!0}catch(r){if(!w(r))throw r;if(e.emit({kind:"busy",op:t}),!i)return!1;let s=Date.now()-n;if(s+2*e.config.busy_timeout_ms>e.config.lock_wait_max_ms)throw e.emit({kind:"lock_wait_exceeded",op:t,waited_ms:s}),d(t,s,e.config.lock_wait_max_ms);await e.delay(e.config.busy_timeout_ms)}}function Ue(e){try{e.sql.exec(void 0===e.afterCommit?"ROLLBACK":"ROLLBACK TO gateway_enqueue; RELEASE gateway_enqueue")}catch{return}}async function Me(e,t,i){if(void 0!==e.afterCommit)return await i();await Ce(e,t,!0);try{let t=await i();return e.sql.exec("COMMIT"),t}catch(t){throw Ue(e),t}}function $e(e,t,i,n){let r=c(e.config.agent_dir,t);x(r,{recursive:!0,mode:448});let s,a=I(r,i);try{s=R(a,L.O_CREAT|L.O_EXCL|L.O_WRONLY,384)}catch(e){if(n&&e instanceof Error&&"code"in e&&"EEXIST"===e.code)return a;throw e}try{q(s,JSON.stringify({pid:e.self.pid,process_start_time:e.self.process_start_time}))}finally{k(s)}return e.afterRollback?.push(()=>O(a,{force:!0})),a}function He(e,t,i){if(void 0!==e.afterCommit)return void e.afterCommit.push(()=>He({...e,afterCommit:void 0},t,i));let n=I(c(e.config.agent_dir,t),i);try{O(n),e.stats.marker_unlinks++}catch(e){if(!(e instanceof Error&&"code"in e&&"ENOENT"===e.code))throw e}}function We(e,t){try{return S(c(e.config.agent_dir,t)).filter(e=>!e.startsWith("."))}catch(e){if(e instanceof Error&&"code"in e&&"ENOENT"===e.code)return[];throw e}}function Xe(e,t){let i=e.sql.one(["next_seq"],"SELECT next_seq FROM session_meta WHERE durable_id = ?",[t]),n=Number(void 0===i?e.sql.one(["m"],"SELECT COALESCE(MAX(seq), 0) + 1 AS m FROM deliveries WHERE target_durable_id = ?",[t])?.m??1:i.next_seq);return De(e,"INSERT INTO session_meta (durable_id, next_seq) VALUES (?, ?) ON CONFLICT(durable_id) DO UPDATE SET next_seq = excluded.next_seq",[t,n+1]),n}function Fe(e,t){De(e,`INSERT INTO deliveries (${Le.join(", ")}) VALUES (${Le.map(()=>"?").join(", ")})`,[t.delivery_id,t.target_durable_id,t.seq,t.sender,t.sender_turn,JSON.stringify(t.envelope),t.body,t.bytes,t.mode_requested,t.mode_effective,t.expected_turn_id,t.state,t.reason,null===t.admitted_by?null:JSON.stringify(t.admitted_by),t.claimed_at,t.attempt,t.admission_kind,t.turn_epoch,t.root_id,t.hop,t.created_at,t.updated_at,t.expires_at,t.binding_id,t.binding_revision,t.actor_user_id])}function Pe(e){return T("sha256").update(JSON.stringify(e)).digest("hex")}function je(e){let t=Number(e.sql.one(["user_version"],"SELECT user_version FROM pragma_user_version()")?.user_version??0);if(t>ke.length)throw new Ne(t,ke.length);return t}function Be(e,t,i){let n=e.sql.one(["args_hash","status","delivery_id","owner_instance","result","expires_at"],"SELECT args_hash, status, delivery_id, owner_instance, result, expires_at FROM receipts WHERE principal = ? AND operation = 'deliver' AND idempotency_key = ?",[t,i]);if(void 0!==n)return{args_hash:String(n.args_hash),status:n.status,delivery_id:null===n.delivery_id?null:String(n.delivery_id),owner_instance:String(n.owner_instance),result:null===n.result?null:String(n.result),expires_at:Number(n.expires_at)}}function Ge(e,t,i){if(i.args_hash!==t.receipt.args_hash)return Se("idempotency_conflict","The idempotency key was already used with different arguments.");if("completed"===i.status&&null!==i.result)return{kind:"replay",result:JSON.parse(i.result)};let n=null===i.delivery_id?void 0:qe(e,i.delivery_id),r=void 0!==n&&("admitted"===n.state||"applied"===n.state||"refused"===n.state);if("prepared"===i.status&&!r&&i.owner_instance===e.config.instance_id)return Se("idempotency_in_progress","The same delivery is already in progress.");if("prepared"===i.status&&r){let i={...Te(n,Ie(e,n),t.endpoint_kind,!0,!1)};return De(e,"UPDATE receipts SET status = 'completed', result = ?, updated_at = ? WHERE principal = ? AND operation = 'deliver' AND idempotency_key = ?",[JSON.stringify(i),t.now,t.sender_principal,t.receipt.idempotency_key]),{kind:"replay",result:i}}return"prepared"===i.status&&De(e,"UPDATE receipts SET status = 'uncertain', error_note = ?, updated_at = ? WHERE principal = ? AND operation = 'deliver' AND idempotency_key = ?",["the sender lost the acknowledgement before the target admitted the delivery",t.now,t.sender_principal,t.receipt.idempotency_key]),Se("idempotency_uncertain","The earlier delivery may or may not reach the target; it is never sent twice.",{delivery_id:i.delivery_id,state:n?.state??null})}async function Je(e,t){if(!Re.test(t.target_durable_id)||!Re.test(t.delivery_id))return Se("invalid_arguments","The target session id is not a durable session id.");if(!await Ce(e,"enqueue",!1))return{kind:"busy"};let i=null,n=!1,r=e.afterCommit?.length??0,s=void 0===e.afterCommit?"COMMIT":"RELEASE gateway_enqueue";try{let r=Ee(e,{principal:t.sender_principal,operation:"deliver",idempotency_key:t.receipt.idempotency_key},t.now),a=Be(e,t.sender_principal,t.receipt.idempotency_key);if(void 0!==a){let i=Ge(e,t,a);return e.sql.exec(s),n=!0,i}let o=function(e,t){if(null===t.binding)return{expires_at:null};let i=e.sql.one(["revision","status","session_durable_id","direction_inbound","expires_at"],"SELECT revision, status, session_durable_id, direction_inbound, expires_at FROM bindings WHERE binding_id = ?",[t.binding.binding_id]),n=null==i?.expires_at?null:Date.parse(String(i.expires_at));return void 0===i||"active"!==i.status||Number(i.revision)!==t.binding.revision||String(i.session_durable_id)!==t.target_durable_id||1!==Number(i.direction_inbound)||null!==n&&n<=t.now?Se("invalid_arguments","The binding is not active for this session at this revision.",{binding:t.binding.binding_id}):{expires_at:n}}(e,t);if("kind"in o)return Ue(e),o;let d=e.sql.one(["n","b"],`SELECT COUNT(*) AS n, COALESCE(SUM(bytes), 0) AS b FROM deliveries WHERE target_durable_id = ? AND state IN ${xe}`,[t.target_durable_id]),u=Buffer.byteLength(t.body);if(Number(d?.n??0)>=128||Number(d?.b??0)+u>H)return Ue(e),Se("queue_full","The target's delivery backlog is full.",{max_messages:128,max_bytes:H});let _=function(e,t){let i;if(null!==t.cause_delivery_id){let n=qe(e,t.cause_delivery_id);if(void 0===n||n.target_durable_id!==t.sender_node||"admitting"!==n.state&&"admitted"!==n.state&&"applied"!==n.state)return Se("invalid_arguments","The delivery this send continues is not one the sender received.",{guard:"unknown_cause"});i={root_id:n.root_id,hop:n.hop+1,via:[...n.envelope.via,t.sender_node],new_root:!1}}else i={root_id:`root-${N()}`,hop:1,via:[t.sender_node],new_root:!0};if(null!==t.claimed_root_id&&t.claimed_root_id!==i.root_id)return Se("invalid_arguments","The causal root is derived by the gateway and cannot be chosen by the caller.",{guard:"forged_root"});if(!i.new_root){let n=e.sql.one(["expires_at"],"SELECT expires_at FROM causal_roots WHERE root_id = ?",[i.root_id]);if(void 0===n||Number(n.expires_at)<=t.now)return Se("loop_detected","This causal chain is older than its lifetime.",{guard:"root_expired",root_id:i.root_id})}if(t.target_durable_id===t.sender_node)return Se("loop_detected","A session cannot deliver to itself through the gateway.",{guard:"self_send"});if(i.hop>4)return Se("loop_detected",`This delivery would be hop ${i.hop}; at most 4 are allowed.`,{guard:"hop_limit",hop:i.hop});let n=Number(e.sql.one(["n"],"SELECT COUNT(*) AS n FROM deliveries WHERE root_id = ? AND state != 'refused'",[i.root_id])?.n??0);return n>=64?Se("loop_detected",`This causal chain already carried ${n} deliveries.`,{guard:"causal_budget",root_id:i.root_id}):C(e.sql.all(["from_durable_id","to_durable_id"],"SELECT from_durable_id, to_durable_id FROM causal_edges WHERE root_id = ?",[i.root_id]).map(e=>({from:String(e.from_durable_id),to:String(e.to_durable_id)})),t.sender_node,t.target_durable_id)?Se("loop_detected","The target already leads back to the sender in this causal chain.",{guard:"cycle",root_id:i.root_id}):i}(e,t);if("kind"in _)return Ue(e),_;let l=function(e,t){if(null===t.sender_turn)return;let i=new Set(e.sql.all(["t"],"SELECT DISTINCT target_durable_id AS t FROM deliveries WHERE sender = ? AND sender_turn = ? AND state != 'refused'",[t.sender_principal,t.sender_turn]).map(e=>String(e.t)));return i.has(t.target_durable_id)||i.size<16?void 0:Se("overloaded","One turn may reach at most 16 sessions.",{budget:"fanout"})}(e,t)??function(e,t){let i=t.rate_principal??t.sender_principal,n=e.sql.one(["tokens","updated_at"],"SELECT tokens, updated_at FROM rate_buckets WHERE sender = ? AND target_durable_id = ?",[i,t.target_durable_id]),r=void 0===n?8:Math.min(8,Number(n.tokens)+Math.max(0,t.now-Number(n.updated_at))/U);if(r<1)return Se("overloaded","Too many deliveries to this session; wait before sending again.",{budget:"pair_rate",retry_after_ms:Math.ceil((1-r)*U)});De(e,"INSERT INTO rate_buckets (sender, target_durable_id, tokens, updated_at) VALUES (?, ?, ?, ?) ON CONFLICT(sender, target_durable_id) DO UPDATE SET tokens = excluded.tokens, updated_at = excluded.updated_at",[i,t.target_durable_id,r-1,t.now])}(e,t);if(void 0!==l)return Ue(e),l;_.new_root&&De(e,"INSERT INTO causal_roots (root_id, origin_principal, created_at, expires_at) VALUES (?, ?, ?, ?)",[_.root_id,t.sender_principal,t.now,t.now+$]),De(e,"INSERT OR IGNORE INTO causal_edges (root_id, from_durable_id, to_durable_id, delivery_id, created_at) VALUES (?, ?, ?, ?, ?)",[_.root_id,t.sender_node,t.target_durable_id,t.delivery_id,t.now]);let c={delivery_id:t.delivery_id,target_durable_id:t.target_durable_id,seq:Xe(e,t.target_durable_id),sender:t.sender_principal,sender_turn:t.sender_turn,envelope:{origin:t.origin,actor:t.actor,via:_.via,root_id:_.root_id,hop:_.hop,delivery_id:t.delivery_id},body:t.body,bytes:u,mode_requested:t.mode,mode_effective:null,expected_turn_id:t.expected_turn_id,state:"queued",reason:null,admitted_by:null,claimed_at:null,attempt:0,admission_kind:null,turn_epoch:null,root_id:_.root_id,hop:_.hop,created_at:t.now,updated_at:t.now,expires_at:Math.min(t.now+M,o.expires_at??Number.POSITIVE_INFINITY),binding_id:t.binding?.binding_id??null,binding_revision:t.binding?.revision??null,actor_user_id:"external"in t.origin?t.origin.external.author?.user_id??null:null};Fe(e,c),De(e,"INSERT INTO receipts (principal, operation, idempotency_key, args_hash, status, delivery_id, owner_instance, created_at, updated_at, expires_at) VALUES (?, 'deliver', ?, ?, 'prepared', ?, ?, ?, ?, ?)",[t.sender_principal,t.receipt.idempotency_key,t.receipt.args_hash,c.delivery_id,e.config.instance_id,t.now,t.now,t.now+W]),i=$e(e,c.target_durable_id,c.delivery_id,!1);let p=Ie(e,c);return he(e,t.now,r),void 0===e.afterCommit&&await e.hook("beforeDbCommit"),e.sql.exec(s),n=!0,void 0===e.afterCommit&&await e.hook("afterDbCommit"),{kind:"inserted",row:c,queue_position:p}}catch(t){throw n||(Ue(e),void 0!==e.afterCommit&&(e.afterCommit.length=r),null!==i&&O(i,{force:!0})),t}}function Ke(e,t){if(null===e)return"";let i=t.get(e);if(void 0===i){try{i=A(e,"utf8")}catch(e){if(!(e instanceof Error&&"code"in e&&"ENOENT"===e.code))throw e;i=""}t.set(e,i)}return i}function Ye(e,t,i){if(null===e.runtime_instance||null===t)return!1;let n=i().get(e.runtime_instance);return void 0!==n&&t<=n}function Ve(e,t,i){for(let n of Ke(e,i).split("\n")){if(!n.includes(t))continue;let e;try{e=JSON.parse(n)}catch{continue}if("object"!=typeof e||null===e)continue;let i=e;if("custom_message"===i.type&&"session_control_delivery"===i.customType&&i.details?.delivery_id===t)return!0}return!1}function ze(e){return`${JSON.stringify(e.admitted_by)}#${e.attempt}`}function Qe(e,t,i,n,r={}){"queued"!==i?"refused"!==i?(De(e,"UPDATE deliveries SET state = ?, updated_at = ? WHERE delivery_id = ?",[i,n,t.delivery_id]),"applied"===i&&De(e,"UPDATE session_meta SET applied_seq = MAX(applied_seq, ?) WHERE durable_id = ?",[t.seq,t.target_durable_id])):De(e,"UPDATE deliveries SET state = 'refused', reason = ?, updated_at = ? WHERE delivery_id = ?",[r.reason??null,n,t.delivery_id]):De(e,"UPDATE deliveries SET state = 'queued', admitted_by = NULL, claimed_at = NULL, mode_effective = NULL, admission_kind = NULL, turn_epoch = NULL, updated_at = ? WHERE delivery_id = ?",[n,t.delivery_id])}async function Ze(e,t){let i,n=t.target_durable_id,r=new Map,s=new Map,a=new Map,o=()=>(i??=function(e,t){let i=new Map;for(let n of Ke(e,t).split("\n")){if(!n.includes(P))continue;let e;try{e=JSON.parse(n)}catch{continue}let t=e;if("custom"!==t.type||t.customType!==P)continue;let r=t.data?.host_instance,s="string"==typeof t.data?.released_at?Date.parse(t.data.released_at):Number.NaN;"string"==typeof r&&0!==r.length&&Number.isFinite(s)&&i.set(r,Math.max(s,i.get(r)??s))}return i}(t.session_path,s),i);for(let i of Oe(e,"target_durable_id = ? AND state IN ('admitting', 'admitted')",[n])){if(null===i.admitted_by||E(i.admitted_by,t.self))continue;let e=JSON.stringify(i.admitted_by),n=a.get(e);void 0===n&&(n=await f(i.admitted_by),a.set(e,n));let d=n||Ye(i.admitted_by,i.claimed_at,o)?Ve(t.session_path,i.delivery_id,s)?"applied":"queued":"dual";r.set(i.delivery_id,{fingerprint:ze(i),to:d})}return!0===e.config.test_hooks.announceBarrier&&e.emit({kind:"barrier",op:"reconcile"}),await Me(e,"reconcile",()=>{let i=new Set(t.ledger.pending),s=new Set(t.ledger.emitted),a=[],o=[];for(let d of Oe(e,`target_durable_id = ? AND state IN ${xe}`,[n],"seq")){let n=d.state;if("queued"!==d.state){if(null!==d.admitted_by&&E(d.admitted_by,t.self))n=s.has(d.delivery_id)?"applied":i.has(d.delivery_id)?"admitted":"queued";else if(null===d.admitted_by)n="queued";else{let e=r.get(d.delivery_id);if(void 0===e||e.fingerprint!==ze(d)||"dual"===e.to){o.push(d.delivery_id);continue}n=e.to}n!==d.state&&(Qe(e,d,n,t.now),a.push({delivery_id:d.delivery_id,from:d.state,to:n}))}else d.expires_at<=t.now&&(Qe(e,d,"refused",t.now,{reason:"expired"}),a.push({delivery_id:d.delivery_id,from:d.state,to:"refused"}))}for(let t of We(e,n))"queued"!==e.sql.one(["state"],"SELECT state FROM deliveries WHERE delivery_id = ?",[t])?.state&&He(e,n,t);return{queued:Oe(e,"target_durable_id = ? AND state = 'queued'",[n],"seq"),transitions:a,dual_runtime:o}})}async function et(e,t){return await Me(e,"complete_receipt",()=>1===De(e,"UPDATE receipts SET status = 'completed', result = ?, updated_at = ? WHERE principal = ? AND operation = 'deliver' AND idempotency_key = ? AND status = 'prepared' AND owner_instance = ?",[JSON.stringify(t.result),t.now,t.principal,t.idempotency_key,e.config.instance_id]))}async function tt(e,t){return await Me(e,"abandon_receipt",()=>1===De(e,"UPDATE receipts SET status = 'uncertain', error_note = ?, updated_at = ? WHERE principal = ? AND operation = 'deliver' AND idempotency_key = ? AND status = 'prepared' AND owner_instance = ?",[t.error_note,t.now,t.principal,t.idempotency_key,e.config.instance_id]))}function it(e,t){let i=Be(e,t.principal,t.idempotency_key);if(void 0===i||i.expires_at<=t.now||null===i.delivery_id)return null;let n=qe(e,i.delivery_id);if(void 0===n)return null;let r="completed"===i.status&&null!==i.result;return{args_hash:i.args_hash,completed:r,result:r?JSON.parse(i.result):null,target_durable_id:n.target_durable_id,binding_revision:n.binding_revision}}async function nt(e,t){return await Me(e,"recover_delivery",()=>{let i=Be(e,t.principal,t.idempotency_key);return void 0===i||i.expires_at<=t.now?null:Ge(e,{now:t.now,sender_principal:t.principal,endpoint_kind:null,receipt:{idempotency_key:t.idempotency_key,args_hash:t.args_hash}},i)})}function rt(e,t){let i=qe(e,t);return void 0===i?null:{row:i,queue_position:Ie(e,i)}}function st(){try{return D().username}catch{return"unknown"}}import{randomUUID as at}from"node:crypto";import{renameSync as ot,writeFileSync as dt}from"node:fs";var ut=["question","select","confirm","input","editor"];var _t=new Map([["yes",!0],["y",!0],["true",!0],["no",!1],["n",!1],["false",!1]]);function lt(e){return""===e.replace(/[\s\p{Cf}]/gu,"")}function ct(e){let t=_t.get(e.trim().toLowerCase());return void 0===t?{value:e,answers:{},comment:e}:{value:e,answers:{},comment:e,confirmed:t}}function pt(e,t){switch(e){case null:return lt(t)?{ok:!1,reason:"The question declared no request kind, so the answer needs text; this one is blank. An input or editor that takes an empty answer must be reported with its request kind."}:{ok:!0,fields:ct(t)};case"input":case"editor":return{ok:!0,fields:{value:t}};case"select":return lt(t)?{ok:!1,reason:"A select answer names one of its options; the text is blank."}:{ok:!0,fields:{value:t}};case"question":return lt(t)?{ok:!1,reason:"A question answer needs text; this one is blank."}:{ok:!0,fields:{answers:{},comment:t}};case"confirm":{let e=_t.get(t.trim().toLowerCase());return void 0===e?{ok:!1,reason:"A confirm answer is yes or no (also y/n, true/false; any case, surrounding spaces ignored)."}:{ok:!0,fields:{confirmed:e}}}default:return function(e){throw Error(`unknown extension UI request kind: ${String(e)}`)}(e)}}var gt=["binding_id","schema_version","revision","status","platform","account_id","chat_id","thread_id","root_message_id","progress_message_id","session_realm_id","session_durable_id","direction_inbound","direction_outbound","inbound_mode","outbound_events","policy_id","created_at","updated_at","lease_started_at","ttl_seconds","expires_at"],mt=["cursor","binding_id","revision","event_kind","payload","state","provider_message_id","created_at","reply_token","question_state","outcome","answered_by","answer_state"];function bt(e,t,i){return{kind:"refused",code:e,message:t,...void 0===i?{}:{details:i}}}function ft(e){return null==e?null:String(e)}function Et(e){return null==e?null:JSON.stringify(e)}function ht(e){return null==e?null:JSON.parse(String(e))}function yt(e,t,i,n){if(void 0!==e.afterCommit)return void e.afterCommit.push(()=>yt({...e,afterCommit:void 0},t,i,n));let r=(a=e.config.agent_dir,_(l(a),"outbox.marker")),s=`${r}.${process.pid}.${at()}.tmp`;var a;dt(s,JSON.stringify({binding_id:t,cursor:i,written_at:oe(n)}),{mode:384}),ot(s,r)}function vt(e){return{schema_version:1,binding_id:String(e.binding_id),revision:Number(e.revision),status:e.status,platform:e.platform,account_id:String(e.account_id),chat_id:String(e.chat_id),thread_id:String(e.thread_id),root_message_id:ft(e.root_message_id),progress_message_id:ft(e.progress_message_id),session_realm_id:String(e.session_realm_id),session_durable_id:String(e.session_durable_id),direction:{inbound:1===Number(e.direction_inbound),outbound:1===Number(e.direction_outbound)},inbound_mode:e.inbound_mode,outbound_events:JSON.parse(String(e.outbound_events)),policy_id:String(e.policy_id),created_at:String(e.created_at),updated_at:String(e.updated_at),lease_started_at:String(e.lease_started_at),ttl_seconds:null===e.ttl_seconds||void 0===e.ttl_seconds?null:Number(e.ttl_seconds),expires_at:ft(e.expires_at)}}function wt(e,t,i,n){let r=`SELECT ${gt.join(", ")} FROM bindings WHERE ${t}${void 0===n?"":` ORDER BY ${n.orderBy} LIMIT ?`}`;return e.sql.all(gt,r,void 0===n?i:[...i,n.limit],n?.orderBy).map(vt)}function Tt(e,t){return wt(e,"binding_id = ?",[t])[0]}function Nt(e,t){let i=e.sql.one(["value"],"SELECT value FROM gateway_meta WHERE key = ?",[t]);if(void 0===i)throw Error(`gateway_meta ${t} is missing`);return String(i.value)}function kt(e,t){let i=oe(t);De(e,"UPDATE bindings SET status = 'expired', updated_at = ? WHERE status = 'active' AND expires_at IS NOT NULL AND expires_at <= ?",[i,i])}function Lt(e,t){De(e,"DELETE FROM outbox WHERE state = 'acked' AND acked_at IS NOT NULL AND acked_at <= ?",[t-ae]),De(e,"DELETE FROM outbox WHERE state = 'pending' AND binding_id IN (SELECT binding_id FROM bindings WHERE status != 'active' AND updated_at <= ?)",[oe(t-ae)])}function xt(e,t){let i=e.sql.one(["args_hash","status","owner_instance","result"],"SELECT args_hash, status, owner_instance, result FROM receipts WHERE principal = ? AND operation = ? AND idempotency_key = ?",[t.principal,t.operation,t.idempotency_key]);if(void 0!==i)return{args_hash:String(i.args_hash),status:String(i.status),owner_instance:String(i.owner_instance),result:ft(i.result)}}async function Rt(e,t,i,n,r){return await Me(e,t,()=>{kt(e,i);let t=null===n?0:Ee(e,n,i),s=function(e,t){if(null===t)return;let i=xt(e,t);return void 0!==i?i.args_hash!==t.args_hash?bt("idempotency_conflict","The idempotency key was already used with different arguments."):"completed"===i.status&&null!==i.result?{...JSON.parse(i.result),kind:"ok",deduplicated:!0}:bt("idempotency_uncertain","An earlier call under this key did not record its outcome."):void 0}(e,n);if(void 0!==s)return s;let a=r();return"ok"===a.kind&&function(e,t,i,n){null!==t&&De(e,"INSERT INTO receipts (principal, operation, idempotency_key, args_hash, status, delivery_id, owner_instance, result, created_at, updated_at, expires_at) VALUES (?, ?, ?, ?, 'completed', NULL, ?, ?, ?, ?, ?)",[t.principal,t.operation,t.idempotency_key,t.args_hash,e.config.instance_id,JSON.stringify(n),i,i,i+W])}(e,n,i,{...a,deduplicated:!1}),he(e,i,t),"ok"===a.kind?{...a,deduplicated:!1}:a})}async function St(e,t){return await Me(e,"tool_receipt_begin",()=>{let i=Ee(e,t,t.now),n=function(e,t){let i=xt(e,t);if(void 0===i)return De(e,"INSERT INTO receipts (principal, operation, idempotency_key, args_hash, status, delivery_id, owner_instance, created_at, updated_at, expires_at) VALUES (?, ?, ?, ?, 'prepared', NULL, ?, ?, ?, ?)",[t.principal,t.operation,t.idempotency_key,t.args_hash,e.config.instance_id,t.now,t.now,t.now+W]),{kind:"accepted"};if(i.args_hash!==t.args_hash)return{kind:"conflict"};if("completed"===i.status)return{kind:"replay",result:null===i.result?null:JSON.parse(i.result)};if("prepared"===i.status&&i.owner_instance===e.config.instance_id)return{kind:"in_progress"};"prepared"===i.status&&De(e,"UPDATE receipts SET status = 'uncertain', error_note = ?, updated_at = ? WHERE principal = ? AND operation = ? AND idempotency_key = ?",["the process that began this call ended before recording its outcome",t.now,t.principal,t.operation,t.idempotency_key]);let n=e.sql.one(["error_note"],"SELECT error_note FROM receipts WHERE principal = ? AND operation = ? AND idempotency_key = ?",[t.principal,t.operation,t.idempotency_key]);return{kind:"uncertain",error_note:ft(n?.error_note)}}(e,t);return he(e,t.now,i),n})}async function At(e,t){let i=t.binding;return await Rt(e,"bind",t.now,t.receipt,()=>{let n=wt(e,"platform = ? AND account_id = ? AND chat_id = ? AND thread_id = ? AND status = 'active'",[i.platform,i.account_id,i.chat_id,i.thread_id])[0];if(void 0!==n){return bt("binding_conflict",n.session_durable_id===i.session_durable_id?"This thread is already bound to that session.":"This thread is bound to another session; rebind it explicitly to move it.",{binding_id:n.binding_id,revision:n.revision,session:n.session_durable_id})}let r=oe(t.now),s={schema_version:1,binding_id:`bnd-${ee()}`,revision:1,status:"active",platform:i.platform,account_id:i.account_id,chat_id:i.chat_id,thread_id:i.thread_id,root_message_id:i.root_message_id,progress_message_id:i.progress_message_id,session_realm_id:Nt(e,"realm_id"),session_durable_id:i.session_durable_id,direction:i.direction,inbound_mode:i.inbound_mode,outbound_events:i.outbound_events,policy_id:i.policy_id,created_at:r,updated_at:r,lease_started_at:r,ttl_seconds:i.ttl_seconds,expires_at:null===i.ttl_seconds?null:oe(t.now+1e3*i.ttl_seconds)};return De(e,`INSERT INTO bindings (${gt.join(", ")}) VALUES (${gt.map(()=>"?").join(", ")})`,[s.binding_id,s.schema_version,s.revision,s.status,s.platform,s.account_id,s.chat_id,s.thread_id,s.root_message_id,s.progress_message_id,s.session_realm_id,s.session_durable_id,s.direction.inbound?1:0,s.direction.outbound?1:0,s.inbound_mode,JSON.stringify(s.outbound_events),s.policy_id,s.created_at,s.updated_at,s.lease_started_at,s.ttl_seconds,s.expires_at]),{kind:"ok",binding:s}})}function Ot(e,t){return e.sql.all(["delivery_id"],`SELECT delivery_id, seq FROM deliveries WHERE binding_id = ? AND state IN ${xe}`,[t],"seq").map(e=>String(e.delivery_id))}async function qt(e,t){return await Rt(e,"unbind",t.now,t.receipt,()=>{let i=Tt(e,t.binding_id);if(void 0===i)return bt("not_found","No binding has this id.",{binding_id:t.binding_id});if("active"!==i.status)return{kind:"ok",binding:i,already_closed:!0,in_flight:Ot(e,i.binding_id)};if(i.revision!==t.expected_revision)return bt("stale_revision","The binding changed since that revision.",{binding_id:i.binding_id,revision:i.revision});let n=oe(t.now);return De(e,"UPDATE bindings SET status = 'detached', revision = revision + 1, updated_at = ? WHERE binding_id = ? AND revision = ?",[n,i.binding_id,i.revision]),De(e,"DELETE FROM completion_arms WHERE binding_id = ?",[i.binding_id]),{kind:"ok",binding:Tt(e,i.binding_id),already_closed:!1,in_flight:Ot(e,i.binding_id)}})}async function Dt(e,t){return await Rt(e,"rebind",t.now,t.receipt,()=>{let i=Tt(e,t.binding_id);if(void 0===i)return bt("not_found","No binding has this id.",{binding_id:t.binding_id});if("active"!==i.status)return bt("binding_inactive",`The binding is ${i.status}.`,{binding_id:i.binding_id,status:i.status});if(i.revision!==t.expected_revision)return bt("stale_revision","The binding changed since that revision.",{binding_id:i.binding_id,revision:i.revision});if(i.session_durable_id===t.session_durable_id)return bt("invalid_arguments","The binding is already attached to that session.",{binding_id:i.binding_id});let n=oe(t.now),r=e.sql.all(["delivery_id","target"],"SELECT delivery_id, target_durable_id AS target, seq FROM deliveries WHERE binding_id = ? AND binding_revision = ? AND state = 'queued'",[i.binding_id,i.revision],"seq").map(e=>({delivery_id:String(e.delivery_id),target:String(e.target)}));for(let i of r)De(e,"UPDATE deliveries SET state = 'refused', reason = 'binding_closed', updated_at = ? WHERE delivery_id = ? AND state = 'queued'",[t.now,i.delivery_id]),He(e,i.target,i.delivery_id);return De(e,"UPDATE bindings SET session_durable_id = ?, revision = revision + 1, lease_started_at = ?, updated_at = ? WHERE binding_id = ? AND revision = ?",[t.session_durable_id,n,n,i.binding_id,i.revision]),De(e,"DELETE FROM completion_arms WHERE binding_id = ?",[i.binding_id]),{kind:"ok",binding:Tt(e,i.binding_id),closed:r.map(e=>e.delivery_id)}})}async function It(e,t){let i=void 0===t.cursor?null:function(e){try{let t=JSON.parse(Buffer.from(e,"base64url").toString("utf8"));if(1!==t.v||"number"!=typeof t.as_of||!Number.isInteger(t.as_of))return null;let i=t.after;return null===i||Array.isArray(i)&&2===i.length&&i.every(e=>"string"==typeof e)?{v:1,as_of:t.as_of,after:i}:null}catch{return null}}(t.cursor);if(void 0!==t.cursor&&null===i)return bt("cursor_invalid","The bindings cursor is not one this gateway issued.");let n=Math.min(Math.max(t.limit??50,1),200);return await Me(e,"list_bindings",()=>{kt(e,t.now);let r=i?.as_of??Number(e.sql.one(["m"],"SELECT COALESCE(MAX(rowid), 0) AS m FROM bindings")?.m??0),s=["rowid <= ?"],a=[r],o=[["session_durable_id","session_durable_id"],["platform","platform"],["account_id","account_id"],["chat_id","chat_id"],["thread_id","thread_id"],["status","status"]];for(let[e,i]of o){let n=t.filter[e];void 0!==n&&(s.push(`${i} = ?`),a.push(n))}null!=i?.after&&(s.push("(created_at > ? OR (created_at = ? AND binding_id > ?))"),a.push(i.after[0],i.after[0],i.after[1]));let d=wt(e,s.join(" AND "),a,{orderBy:"created_at, binding_id",limit:n+1}),u=d.slice(0,n),_=u.at(-1);return{kind:"ok",bindings:u,next_cursor:d.length>n&&void 0!==_?ge(r,[_.created_at,_.binding_id]):null}})}async function Ct(e,t){return await Me(e,"binding_view",()=>(kt(e,t.now),Tt(e,t.binding_id)??null))}function Ut(e,t){return ft(e.sql.one(["incarnation"],"SELECT incarnation FROM session_meta WHERE durable_id = ?",[t])?.incarnation)}function Mt(e,t){De(e,"INSERT INTO outbox (binding_id, revision, event_kind, payload, state, provider_message_id, created_at, acked_at, session_durable_id, reply_token, ui_request_id, ui_request_kind, incarnation, question_state, answer, answered_at, outcome) VALUES (?, ?, ?, ?, 'pending', NULL, ?, NULL, ?, ?, ?, ?, ?, ?, NULL, NULL, ?)",[t.binding.binding_id,t.binding.revision,t.event,JSON.stringify({text:t.text}),t.now,t.binding.session_durable_id,t.reply_token??null,t.ui_request_id??null,t.ui_request_kind??null,t.incarnation??null,void 0===t.reply_token?null:"pending",t.outcome??null]);let i=Number(e.sql.one(["c"],"SELECT last_insert_rowid() AS c")?.c);return yt(e,t.binding.binding_id,i,t.now),i}async function $t(e,t){return await Rt(e,"report",t.now,t.receipt,()=>{let i=null===t.binding_id?function(e,t,i,n){let r=[...new Set(i.flatMap(i=>{let n=e.sql.one(["binding_id"],"SELECT binding_id FROM deliveries WHERE delivery_id = ? AND target_durable_id = ?",[i,t]),r=ft(n?.binding_id);return null===r?[]:[r]}))].sort(),s=e.sql.all(["binding_id"],"SELECT binding_id FROM bindings WHERE session_durable_id = ? AND status = 'active' AND direction_outbound = 1",[t],"binding_id").map(e=>String(e.binding_id)),[a,...o]=r;if(void 0!==a&&o.length>0)return bt("invalid_arguments",`This session's current run answers messages from ${r.length} bound threads; name binding_id.`,{binding_ids:r});if(void 0!==a&&n&&s.some(e=>e!==a))return bt("invalid_arguments","This session's current run answers a bound thread's message and a user message (typed in its terminal or sent by an extension) together; name binding_id.",{binding_ids:s});if(void 0!==a)return{binding_id:a};let[d,...u]=s;return void 0!==d&&0===u.length?{binding_id:d}:void 0===d?bt("invalid_arguments","This session has no active outbound binding and its current run answers no bound message; name binding_id."):bt("invalid_arguments",`This session has ${s.length} active outbound bindings and its current run answers no bound message; name binding_id.`,{binding_ids:s})}(e,t.session_durable_id,t.origin_delivery_ids,!0===t.origin_local_input):{binding_id:t.binding_id};if("kind"in i)return i;let n=i.binding_id,r=Tt(e,n);if(void 0===r)return bt("not_found","No binding has this id.",{binding_id:n});if(r.session_durable_id!==t.session_durable_id)return bt("scope_denied","The binding is attached to another session.",{binding_id:n});if("active"!==r.status)return bt("binding_inactive",`The binding is ${r.status}.`,{binding_id:n,status:r.status});if(!r.direction.outbound)return bt("unsupported","The binding carries no outbound direction.",{binding_id:n,direction:r.direction});if(!r.outbound_events.includes(t.event))return bt("unsupported",`The binding is not subscribed to ${t.event} events.`,{binding_id:n,outbound_events:r.outbound_events});if(null!==t.ui_request_kind&&"question"!==t.event)return bt("invalid_arguments","Only a question names a request kind.");let s={binding_id:n,revision:r.revision,event:t.event};if("completion"===t.event){De(e,"INSERT INTO completion_arms (session_durable_id, binding_id, revision, text, armed_at) VALUES (?, ?, ?, ?, ?)",[t.session_durable_id,n,r.revision,t.text,t.now]);let i=Number(e.sql.one(["s"],"SELECT last_insert_rowid() AS s")?.s);return{kind:"ok",...s,cursor:null,reply_token:null,armed:!0,arm_seq:i}}if("question"===t.event){if(null===t.ui_request_id)return bt("invalid_arguments","A question names the session's pending extension UI request (request_id).");let i=Ut(e,t.session_durable_id),a=function(e,t){let i={b:t.binding_id,r:t.revision,s:t.session_durable_id,i:t.incarnation,q:t.ui_request_id,n:ee()},n=pe(JSON.stringify(i));return`${me}.${n}.${be(e,n)}`}(Nt(e,"token_secret"),{binding_id:n,revision:r.revision,session_durable_id:t.session_durable_id,incarnation:i,ui_request_id:t.ui_request_id}),o=Mt(e,{binding:r,event:"question",text:t.text,now:t.now,reply_token:a,ui_request_id:t.ui_request_id,...null===t.ui_request_kind?{}:{ui_request_kind:t.ui_request_kind},incarnation:i});return Lt(e,t.now),{kind:"ok",...s,cursor:o,reply_token:a,armed:!1,arm_seq:null}}let a=Mt(e,{binding:r,event:t.event,text:t.text,now:t.now});return Lt(e,t.now),{kind:"ok",...s,cursor:a,reply_token:null,armed:!1,arm_seq:null}})}async function Ht(e,t){return await Me(e,"emit_completions",()=>{kt(e,t.now);let i=["arm_seq","binding_id","revision","text"],n=void 0===t.through_arm_seq?e.sql.all(i,"SELECT arm_seq, binding_id, revision, text FROM completion_arms WHERE session_durable_id = ?",[t.session_durable_id],"arm_seq"):e.sql.all(i,"SELECT arm_seq, binding_id, revision, text FROM completion_arms WHERE session_durable_id = ? AND arm_seq <= ?",[t.session_durable_id,t.through_arm_seq],"arm_seq"),r=new Map;for(let t of n)De(e,"DELETE FROM completion_arms WHERE arm_seq = ?",[Number(t.arm_seq)]),r.set(String(t.binding_id),t);let s=[];for(let i of[...r.values()].toSorted((e,t)=>String(e.binding_id)<String(t.binding_id)?-1:1)){let n=Tt(e,String(i.binding_id));void 0!==n&&"active"===n.status&&n.revision===Number(i.revision)&&n.session_durable_id===t.session_durable_id&&(n.direction.outbound&&n.outbound_events.includes("completion")&&s.push({binding_id:n.binding_id,cursor:Mt(e,{binding:n,event:"completion",text:String(i.text),now:t.now,outcome:t.outcome})}))}return s}).then(i=>(e.emit({kind:"completions_emitted",session_durable_id:t.session_durable_id,cursors:i.map(e=>e.cursor)}),i))}function Wt(e,t){return Number(e.sql.one(["acked_cursor"],"SELECT acked_cursor FROM outbox_cursors WHERE binding_id = ?",[t])?.acked_cursor??0)}async function Xt(e,t){let i=Math.min(Math.max(t.limit??100,1),500);return await Me(e,"read_outbox",()=>{kt(e,t.now),Lt(e,t.now);let n=Tt(e,t.binding_id);if(void 0===n)return bt("not_found","No binding has this id.",{binding_id:t.binding_id});let r=Wt(e,n.binding_id),s=t.after_cursor??r,a=e.sql.all(mt,`SELECT ${mt.join(", ")} FROM outbox WHERE binding_id = ? AND cursor > ?${t.pendingOnly?" AND state = 'pending'":""} ORDER BY cursor LIMIT ?`,[n.binding_id,s,i],"cursor").map(e=>function(e,t){let i=e.event_kind;return{cursor:Number(e.cursor),binding_id:String(e.binding_id),revision:Number(e.revision),event:i,text:String(JSON.parse(String(e.payload)).text??""),state:e.state,created_at:oe(Number(e.created_at)),edit_message_id:"milestone"===i?t.progress_message_id:null,provider_message_id:ft(e.provider_message_id),reply_token:ft(e.reply_token),question_state:e.question_state??null,outcome:e.outcome??null,answered_by:ht(e.answered_by),answer_state:e.answer_state??null}}(e,n));return he(e,t.now),{kind:"ok",binding_id:n.binding_id,revision:n.revision,status:n.status,rows:a,next_cursor:a.at(-1)?.cursor??s,acked_cursor:r}})}async function Ft(e,t){return await Me(e,"ack_outbox",()=>{kt(e,t.now);let i=Tt(e,t.binding_id);if(void 0===i)return bt("not_found","No binding has this id.",{binding_id:t.binding_id});let n=Wt(e,i.binding_id);if(t.cursor<=n)return{kind:"ok",binding_id:i.binding_id,acked_cursor:n,changed:!1};if(void 0===e.sql.one(["cursor"],"SELECT cursor FROM outbox WHERE binding_id = ? AND cursor = ?",[i.binding_id,t.cursor])){let n=Number(e.sql.one(["m"],"SELECT COALESCE(MAX(cursor), 0) AS m FROM outbox WHERE binding_id = ?",[i.binding_id])?.m??0);return bt("cursor_invalid",t.cursor>n?"The cursor is past the newest outbox row of this binding.":"The cursor names no outbox row of this binding.",{newest:n})}return De(e,"UPDATE outbox SET state = 'acked', acked_at = ? WHERE binding_id = ? AND cursor <= ? AND state = 'pending'",[t.now,i.binding_id,t.cursor]),De(e,"INSERT INTO outbox_cursors (binding_id, acked_cursor, updated_at) VALUES (?, ?, ?) ON CONFLICT(binding_id) DO UPDATE SET acked_cursor = excluded.acked_cursor, updated_at = excluded.updated_at",[i.binding_id,t.cursor,t.now]),void 0!==t.provider_message_id&&(De(e,"UPDATE outbox SET provider_message_id = ? WHERE binding_id = ? AND cursor = ?",[t.provider_message_id,i.binding_id,t.cursor]),"milestone"===e.sql.one(["event_kind"],"SELECT event_kind FROM outbox WHERE binding_id = ? AND cursor = ?",[i.binding_id,t.cursor])?.event_kind&&null===i.progress_message_id&&De(e,"UPDATE bindings SET progress_message_id = ?, updated_at = ? WHERE binding_id = ?",[t.provider_message_id,oe(t.now),i.binding_id])),{kind:"ok",binding_id:i.binding_id,acked_cursor:t.cursor,changed:!0}})}var Pt="The session no longer waits for this question (answered or closed elsewhere)";async function jt(e,t){return await Me(e,"claim_answer",()=>{kt(e,t.now);let i=function(e,t){let i=t.split(".");if(3!==i.length||i[0]!==me)return null;let n=Buffer.from(be(e,i[1])),r=Buffer.from(i[2]);if(n.length!==r.length||!te(n,r))return null;try{let e=JSON.parse(Buffer.from(i[1],"base64url").toString("utf8"));return"string"!=typeof e.b||"number"!=typeof e.r||"string"!=typeof e.s||"string"!=typeof e.q||null!==e.i&&"string"!=typeof e.i?null:{binding_id:e.b,revision:e.r,session_durable_id:e.s,incarnation:e.i??null,ui_request_id:e.q}}catch{return null}}(Nt(e,"token_secret"),t.reply_token);if(null===i)return bt("invalid_arguments","This is not a reply token this gateway issued.");if(i.binding_id!==t.binding_id)return bt("binding_mismatch","The answer arrived through a different binding than the one that asked the question.",{binding_id:t.binding_id});let n=e.sql.one(["cursor","question_state","answer_state","answer","answered_at","answered_by","ui_request_id","ui_request_kind","session"],"SELECT cursor, question_state, answer_state, answer, answered_at, answered_by, ui_request_id, ui_request_kind, session_durable_id AS session FROM outbox WHERE reply_token = ? AND binding_id = ?",[t.reply_token,i.binding_id]);if(void 0===n)return bt("not_found","The question this token belongs to is no longer in the outbox.");let r="answered"===n.question_state&&"delivered"!==n.answer_state,s=r&&Number(n.answered_at)+12e4<=t.now;if(r&&!s)return bt("answer_in_progress","Another answer to this question is still being handed to the session.",{cursor:Number(n.cursor)});if("answered"===n.question_state&&!s)return bt("already_answered",null===n.answer&&"delivered"===n.answer_state?`${Pt}.`:"This question was already answered.",{cursor:Number(n.cursor)});let a="string"==typeof(d=n.ui_request_kind)&&ut.includes(d)?n.ui_request_kind:null,o=pt(a,t.answer);var d;if(!o.ok)return bt("invalid_arguments",o.reason,{ui_request_kind:a});let u=Tt(e,i.binding_id);return void 0===u||"active"!==u.status||u.revision!==i.revision||u.session_durable_id!==i.session_durable_id||Ut(e,i.session_durable_id)!==i.incarnation||ft(n.ui_request_id)!==i.ui_request_id?bt("stale_token","The binding or the session changed since the question was asked.",{binding_id:i.binding_id}):(De(e,"UPDATE outbox SET question_state = 'answered', answer_state = 'in_flight', answer = ?, answered_at = ?, answered_by = ? WHERE reply_token = ?",[t.answer,t.now,Et(t.answered_by),t.reply_token]),{kind:"ok",session_durable_id:i.session_durable_id,ui_request_id:i.ui_request_id,ui_request_kind:a,cursor:Number(n.cursor),claimed_at:t.now,taken_over:s?{answer:ft(n.answer),answered_at:null===n.answered_at||void 0===n.answered_at?null:Number(n.answered_at),answered_by:ht(n.answered_by)}:null})})}function Bt(e,t,i){let n=e.sql.one(["cursor","binding_id"],"SELECT cursor, binding_id FROM outbox WHERE reply_token = ?",[t]);void 0!==n&&yt(e,String(n.binding_id),Number(n.cursor),i)}async function Gt(e,t){return await Me(e,"release_answer",()=>{let i=1===De(e,"UPDATE outbox SET question_state = 'pending', answer_state = NULL, answer = NULL, answered_at = NULL, answered_by = NULL WHERE reply_token = ? AND question_state = 'answered' AND answer_state = 'in_flight' AND answered_at = ?",[t.reply_token,t.claimed_at]);return i&&Bt(e,t.reply_token,t.claimed_at),i})}async function Jt(e,t){return await Me(e,"mark_prior_delivered",()=>{let i=1===De(e,"UPDATE outbox SET answer_state = 'delivered', answer = ?, answered_at = ?, answered_by = ? WHERE reply_token = ? AND question_state = 'answered' AND answer_state = 'in_flight' AND answered_at = ?",[t.prior.answer,t.prior.answered_at,Et(t.prior.answered_by),t.reply_token,t.claimed_at]);return i&&Bt(e,t.reply_token,t.claimed_at),i})}async function Kt(e,t){return await Me(e,"confirm_answer",()=>{let i=1===De(e,"UPDATE outbox SET question_state = 'answered', answer_state = 'delivered', answer = ?, answered_at = ?, answered_by = ? WHERE reply_token = ? AND (answer_state IS NOT 'delivered' OR answer IS NULL)",[t.answer,t.claimed_at,Et(t.answered_by),t.reply_token]);return i&&Bt(e,t.reply_token,t.claimed_at),i})}import{extname as Yt}from"node:path";var Vt=0,zt=1,Qt=1,Zt=2,ei=9,ti=10,ii=11,ni=18,ri=20,si=21,ai=23,oi=26,di=27,ui=31,_i=33;class li extends Error{code="extension_schema_violation"}var ci=["type","name","tbl_name","sql"],pi=e=>e.replace(/[A-Z]/g,e=>e.toLowerCase()),gi=e=>`${String(e.type)}:${pi(String(e.name))}`;function mi(e){return{objects:e.all(ci,"SELECT type, name, tbl_name, sql FROM sqlite_schema",[],"type, name"),owners:new Map(e.all(["type","name","owner"],"SELECT type, name, owner FROM extension_objects").map(e=>[gi(e),null===e.owner?null:String(e.owner)]))}}function bi(e,t,i,n){let r=new Map(i.objects.map(e=>[gi(e),e])),s=new Map(n.objects.map(e=>[gi(e),e])),a=[...new Set([...r.keys(),...s.keys()])].filter(e=>JSON.stringify(r.get(e))!==JSON.stringify(s.get(e)));for(let e of a){let o=r.get(e),d=s.get(e);if(void 0!==o&&i.owners.get(e)!==t)throw new li(`Extension ${t} changed an object it does not own: ${String(o.name)}.`);if(void 0===d)continue;if("trigger"===d.type||"view"===d.type)throw new li("Store extensions cannot create triggers or views.");let u=pi(String(d.name));if(("index"!==d.type||null!==d.sql||!u.startsWith(`sqlite_autoindex_${pi(String(d.tbl_name))}_`))&&!u.startsWith(`${t}_`)||i.owners.has(e)&&i.owners.get(e)!==t)throw new li(`Extension ${t} created an object outside its namespace: ${String(d.name)}.`);if("index"===d.type){let e=`table:${pi(String(d.tbl_name))}`,o=!r.has(e)&&s.has(e)&&a.includes(e);if(i.owners.get(e)!==t&&n.owners.get(e)!==t&&!o)throw new li(`Extension ${t} indexed a table it does not own: ${String(d.tbl_name)}.`)}}for(let i of a){let n=r.get(i),a=s.get(i);void 0!==n&&e.run("DELETE FROM extension_objects WHERE type = ? AND name = ? COLLATE NOCASE AND owner = ?",[String(n.type),String(n.name),t]),void 0!==a&&e.run("INSERT INTO extension_objects (type, name, owner) VALUES (?, ?, ?) ON CONFLICT(type, name) DO UPDATE SET owner = excluded.owner",[String(a.type),pi(String(a.name)),t])}}function fi(e,t,i){let n,r,s=mi(e),a=new Map(s.owners),o=new Set(s.objects.filter(e=>"trigger"===e.type||"view"===e.type).map(e=>pi(String(e.name)))),d=(e,i)=>null!==i&&a.get(`${e}:${i}`)===t,u=(e,i,n=!1)=>!(null===i||!n&&!i.startsWith(`${t}_`)||a.has(`${e}:${i}`))&&(a.set(`${e}:${i}`,t),!0),_=!1,l=Vt,c=e=>(r=`Extension ${t} does not own ${e??"this SQLite operation"}.`,zt);try{return e.authorized((e,t,i,r,s)=>{let a=null===t?null:pi(t),p=null===i?null:pi(i),g=null===r?null:pi(r),m=null===s?null:pi(s);if(null!==m&&o.has(m))return c(m);switch(e){case Zt:return n="create","main"===g&&u("table",a)?l:c(a);case Qt:return n="create","main"===g&&d("table",p)&&u("index",a,!0===a?.startsWith(`sqlite_autoindex_${p}_`))?l:c(a);case ii:return n="drop","main"===g&&d("table",a)?l:c(a);case ti:return n="drop","main"===g&&d("index",a)&&d("table",p)?l:c(a);case oi:return n="alter","main"===a&&d("table",p)?l:c(p);case di:return"main"===g&&d("index",a)?l:c(a);case ri:case ni:case ai:case ei:return"sqlite_master"===a||"sqlite_temp_master"===a?(e===ai&&"sql"===p&&(_=!0),e!==ri||"alter"===n||"drop"===n||"create"===n&&_&&"rowid"===p?l:c(a)):"alter"!==n||"sqlite_sequence"!==a||"name"!==p||e!==ri&&e!==ai?("main"===g||null===g&&e===ri&&""===p)&&d("table",a)?l:c(a):l;case si:case _i:return l;case ui:return"load_extension"===p?c(p):l;default:return c(a)}},i)}catch(e){if(void 0!==r)throw new li(r);throw e}}import{createHash as Ei,randomUUID as hi}from"node:crypto";var yi={loop_detected:"Stop relaying here: a direct reply to the session that messaged you is a cycle. That session reads your answer with thread_read; a bound external thread gets it through thread_report, and its questions come back through thread_answer.",overloaded:"Wait before sending to this session again.",queue_full:"Wait for the target to take its queued messages, then send again.",idempotency_conflict:"Retry with a new idempotency_key.",idempotency_in_progress:"Wait for the earlier call to settle, then retry.",idempotency_uncertain:"Read the target transcript before deciding whether to send again; the gateway never resends.",invalid_arguments:"Fix the arguments and send again."};function vi(e,t,i){return{kind:"error",error:ve(e,t,yi[e]??"Call thread_list and retry after checking the target.",i)}}function wi(e){return t={target:e.target,text:e.text,mode:e.mode,expected_turn_id:e.expected_turn_id,binding:e.binding,author:e.author},Ei("sha256").update(JSON.stringify(t)).digest("hex");var t}function Ti(e){let t=!1;for(let i of h(e))if("space"!==i.kind&&"comment"!==i.kind){if(t)throw new li("An extension SQL call must contain one statement.");"semicolon"===i.kind&&(t=!0)}}var Ni=/[\u0000-\u001f\u007f-\u009f\u2028\u2029]/;function ki(e){return{kind:"refused",code:"invalid_arguments",message:e}}function Li(e,t,i){return"string"!=typeof t||0===t.trim().length?ki(`author.${e} must be a non-empty string.`):t.length>i?ki(`author.${e} is longer than ${i} characters.`):Ni.test(t)?ki(`author.${e} carries a control character or line break.`):t.trim()}var xi={binding_conflict:"Call thread_bindings to find the binding that holds this thread, then thread_rebind it with its revision, or thread_unbind it first.",binding_mismatch:"Answer through the binding that asked the question; the question stays pending.",binding_inactive:"Bind the thread again with thread_bind.",stale_revision:"Call thread_bindings for the current revision and retry with it.",stale_token:"The question was asked under an earlier binding revision or session runtime; wait for the session to ask again.",already_answered:"Nothing to do: the question has its answer.",answer_in_progress:"Retry after a moment: another answer is still being handed to the session, and the question goes back to pending if that fails.",idempotency_conflict:"Retry with a new idempotency_key.",idempotency_uncertain:"Call thread_bindings or thread_outbox to see the current state before retrying with a new key.",scope_denied:"Report through a binding attached to this session; thread_bindings lists them.",unsupported:"Report only the events the binding subscribes to, through a binding with an outbound direction.",not_found:"Call thread_bindings for the binding ids that exist.",cursor_invalid:"Read thread_outbox again and ack a cursor it returned.",host_unavailable:"Retry when the session is running; the question stays pending.",invalid_arguments:"Fix the arguments and call again."},Ri=new Set(["question_already_resolved","unknown_extension_ui_request","unknown_request"]);function Si(e,t,i,n){return{kind:"error",error:ve(e,t,n??xi[e]??"Call thread_bindings and retry after checking the binding.",i)}}function Ai(e){return"refused"===e.kind?Si(e.code,e.message,e.details):e}function Oi(e){if(void 0===e)return;let t=function(e){let t=Li("platform_user_id",e.platform_user_id,256);if("string"!=typeof t)return t;let i=Li("display",e.display,256);if("string"!=typeof i)return i;if(void 0===e.user_id)return{platform_user_id:t,display:i};let n=Li("user_id",e.user_id,256);return"string"!=typeof n?n:{platform_user_id:t,display:i,user_id:n}}(e);return"kind"in t?Si("invalid_arguments",t.message):t}function qi(e){let t=Buffer.byteLength(e);return t>32768?Si("message_too_large",`The text is ${t} bytes, above the 32768-byte limit.`):void 0}function Di(e,t,i){return void 0===e.idempotency_key?null:{principal:e.principal,operation:t,idempotency_key:e.idempotency_key,args_hash:(n=i,Q("sha256").update(ce(n)).digest("hex"))};var n}function Ii(e){let t=e.store,i=e.now??t.now,n=new Set,r=!1;async function s(e){await a(()=>t.releaseAnswer(e))}async function a(e){try{await e()}catch(i){if(!u(i)||r)throw i;let s=function(e,t,i){let n,r=!1,s=()=>{n=setTimeout(()=>{n=void 0,r||e().catch(e=>{r||(u(e)?s():i(e))})},t()),n.unref?.()};return s(),{cancel:()=>{r=!0,clearTimeout(n)}}}(()=>e().then(()=>{n.delete(s)}),()=>t.busyTimeoutMs,()=>{n.delete(s)});n.add(s)}}return{bind:async e=>{let n=function(e){if(!ie.includes(e.platform))return de(`platform must be one of ${ie.join(", ")}.`);let t={account_id:ue("account_id",e.account_id),chat_id:ue("chat_id",e.chat_id),thread_id:ue("thread_id",e.thread_id??"@chat"),root_message_id:_e("root_message_id",e.root_message_id),progress_message_id:_e("progress_message_id",e.progress_message_id),session_durable_id:ue("session",e.session_durable_id),policy_id:ue("policy_id",e.policy_id??"default")};for(let e of Object.values(t))if(le(e))return e;let i=e.direction??{inbound:!0,outbound:!0};if(!0!==i.inbound&&!0!==i.outbound)return de("A binding needs at least one direction: inbound, outbound, or both.");let n=e.inbound_mode??"auto";if(!re.includes(n))return de(`inbound_mode must be one of ${re.join(", ")}.`);let r=e.outbound_events??(i.outbound?ne:[]);if(r.some(e=>!ne.includes(e)))return de(`outbound_events may only name ${ne.join(", ")}.`);if(new Set(r).size!==r.length)return de("outbound_events must not repeat an event.");if(i.outbound&&0===r.length)return de("An outbound binding needs at least one outbound event.");let s=void 0===e.ttl_seconds?604800:e.ttl_seconds;return null!==s&&(!Number.isInteger(s)||s<1||s>se)?de("ttl_seconds must be an integer from 1 to 31622400, or null for a binding that never expires."):{platform:e.platform,account_id:t.account_id,chat_id:t.chat_id,thread_id:t.thread_id,root_message_id:t.root_message_id,progress_message_id:t.progress_message_id,session_durable_id:t.session_durable_id,direction:{inbound:!0===i.inbound,outbound:!0===i.outbound},inbound_mode:n,outbound_events:ne.filter(e=>r.includes(e)),policy_id:t.policy_id,ttl_seconds:s}}(e.binding);return Ai("kind"in n?n:await t.bind({now:i(),receipt:Di(e,"thread_bind",n),binding:n}))},unbind:async e=>{let n={binding_id:e.binding_id,expected_revision:e.expected_revision};return Ai(await t.unbind({now:i(),receipt:Di(e,"thread_unbind",n),...n}))},rebind:async e=>{let n={binding_id:e.binding_id,expected_revision:e.expected_revision,session_durable_id:e.session_durable_id};return Ai(await t.rebind({now:i(),receipt:Di(e,"thread_rebind",n),...n}))},bindings:async e=>Ai(await t.listBindings({now:i(),...e})),report:async e=>{let n=qi(e.text);if(void 0!==n)return n;let r={session_durable_id:e.session_durable_id,binding_id:e.binding_id??null,origin_delivery_ids:e.origin_delivery_ids??[],origin_local_input:!0===e.origin_local_input,event:e.event,text:e.text,ui_request_id:e.request_id??null,ui_request_kind:e.request_kind??null};return Ai(await t.report({now:i(),receipt:Di(e,"thread_report",r),...r}))},outbox:async e=>Ai(await t.readOutbox({now:i(),...e})),ack:async e=>Ai(await t.ackOutbox({now:i(),...e})),answer:async n=>{let r=qi(n.answer);if(void 0!==r)return r;let o=Oi(n.author);if(void 0!==o&&"kind"in o)return o;let d=o??null,u=await t.claimAnswer({now:i(),binding_id:n.binding_id,reply_token:n.reply_token,answer:n.answer,answered_by:d});if("ok"!==u.kind)return Ai(u);let _={reply_token:n.reply_token,claimed_at:u.claimed_at},l=e.endpoints.respondUi,c=null,p="";if(void 0!==l)try{c=await e.locate(u.session_durable_id)}catch(e){p=`: ${e instanceof Error?e.message:String(e)}`}if(void 0===l||null===c)return await s(_),Si(void 0===l?"unsupported":"host_unavailable",`The session that asked is not reachable to take the answer${p}.`,{session:u.session_durable_id});let g,m=pt(u.ui_request_kind,n.answer);if(!m.ok)return await s(_),Si("invalid_arguments",m.reason,{session:u.session_durable_id,ui_request_kind:u.ui_request_kind});try{g=await l(c,{ui_request_id:u.ui_request_id,fields:m.fields})}catch(e){return await s(_),Si("host_unavailable",`The answer could not be handed to the session: ${e instanceof Error?e.message:String(e)}`,{session:u.session_durable_id})}if(!g.delivered){let e=u.taken_over;if(null!==e&&Ri.has(g.error))return"question_already_resolved"===g.error?(await a(()=>t.markPriorDelivered({..._,prior:e})),Si("already_answered",`The session already took an earlier answer to this question (${g.error}).`,{session:u.session_durable_id,reason:g.error})):(await a(()=>t.markPriorDelivered({..._,prior:{answer:null,answered_at:_.claimed_at}})),Si("already_answered",`${Pt} (${g.error}).`,{session:u.session_durable_id,reason:g.error},"Nothing to do: the session no longer waits for this question."));await s(_);let i="invalid_response"===g.error||"question_incomplete"===g.error;return Si(i?"invalid_arguments":"stale_token",`The session refused the answer: ${g.error}`,{session:u.session_durable_id,reason:g.error},i?`The session could not read this answer (${g.error}); answer again with text it can take. The question stays pending.`:`The session refused the answer (${g.error}): it no longer waits on this question. Read thread_outbox for a newer question and answer that one.`)}return await async function(e){await a(()=>t.confirmAnswer(e))}({..._,answer:n.answer,answered_by:d}),{kind:"ok",binding_id:n.binding_id,cursor:u.cursor,session_durable_id:u.session_durable_id,answered_by:d}},inbound:async n=>{if(void 0!==n.mode&&!re.includes(n.mode))return Si("invalid_arguments",`A binding message is delivered as ${re.join(" or ")}, never ${String(n.mode)}.`,{mode:n.mode},"Send with mode auto or follow_up, or omit it for the binding's inbound_mode.");let r=Oi(n.author);if(void 0!==r&&"kind"in r)return r;let s=await t.bindingView({now:i(),binding_id:n.binding_id});if(null===s)return Si("not_found","No binding has this id.",{binding_id:n.binding_id});let a={principal:`binding:${s.binding_id}`,idempotency_key:`event:${n.event_id}`},o=await t.deliveryReceipt({now:i(),...a});if(null!==o&&null!==o.binding_revision&&o.args_hash===wi({target:o.target_durable_id,text:n.text,mode:n.mode??s.inbound_mode,expected_turn_id:null,binding:{binding_id:s.binding_id,revision:o.binding_revision},author:r})){let e=o.completed?{kind:"replay",result:o.result}:await t.recoverDelivery({now:i(),...a,args_hash:o.args_hash});if("replay"===e?.kind){let t=e.result;return"ok"===t.kind?{...t,deduplicated:!0}:t}if("refused"===e?.kind)return Si(e.code,e.message,e.details)}if("active"!==s.status)return Si("binding_inactive",`The binding is ${s.status}.`,{binding_id:s.binding_id,status:s.status});if(!s.direction.inbound)return Si("unsupported","The binding carries no inbound direction.",{binding_id:s.binding_id});let d=n.mode??s.inbound_mode;return"auto"===d&&"follow_up"===s.inbound_mode?Si("invalid_arguments","The binding delivers at most follow_up; a message cannot ask for more than its binding's inbound_mode.",{binding_id:s.binding_id,mode:d,inbound_mode:s.inbound_mode},"Send with mode follow_up (or omit it), or rebind the thread with inbound_mode auto."):await e.engine.deliver({sender:{kind:"external",origin:{platform:s.platform,account_id:s.account_id,chat_id:s.chat_id,thread_id:s.thread_id,message_id:n.event_id,...void 0===r?{}:{author:r}},binding_id:s.binding_id,binding_revision:s.revision},target:s.session_durable_id,text:n.text,mode:d,all_scope:!0,idempotency_key:`event:${n.event_id}`})},settle:e=>t.emitCompletions({now:i(),...e}),dispose:()=>{r=!0;for(let e of n)e.cancel();n.clear()}}}class Ci extends Error{extension;code="extension_operation_failed";constructor(e){super(`The ${e} extension transaction has ended.`),this.extension=e}}function Ui(e,t,i,n){let r,s=!0,a=!1,o=Promise.resolve();function d(e){if(a)throw new Ci(t);if(void 0!==r)throw r;return e()}function u(e){let i=s?o.then(()=>d(e)):Promise.reject(new Ci(t));return o=i.then(()=>{},e=>{r=e}),i}function _(i,n){(()=>{if(!s)throw new Ci(t);if(void 0!==r)throw r})();let a=mi(e.sql);try{Ti(i);let r=fi(e.sql,t,n);return bi(e.sql,t,a,mi(e.sql)),r}catch(e){throw r=e,e}}let l={now:()=>i,busyTimeoutMs:e.config.busy_timeout_ms,enqueue:t=>d(()=>Je(e,t)),completeReceipt:t=>d(()=>et(e,t)),abandonReceipt:t=>d(()=>tt(e,t)),deliveryView:async t=>d(()=>rt(e,t)),deliveryReceipt:async t=>d(()=>it(e,t)),recoverDelivery:t=>d(()=>nt(e,t)),bind:t=>d(()=>At(e,t)),unbind:t=>d(()=>qt(e,t)),rebind:t=>d(()=>Dt(e,t)),listBindings:t=>d(()=>It(e,t)),bindingView:t=>d(()=>Ct(e,t)),report:t=>d(()=>$t(e,t)),readOutbox:t=>d(()=>Xt(e,{...t,pendingOnly:!0})),ackOutbox:t=>d(()=>Ft(e,t)),claimAnswer:t=>d(()=>jt(e,t)),releaseAnswer:t=>d(()=>Gt(e,t)),confirmAnswer:t=>d(()=>Kt(e,t)),markPriorDelivered:t=>d(()=>Jt(e,t)),emitCompletions:t=>d(()=>Ht(e,t))},c={wake:async()=>{throw Error("An extension enqueue cannot contact a live endpoint.")}},p=function(e){let t=e.store,i=e.now??t.now;return{deliver:async function(n){let r=n.mode??"auto";if("steer"===r&&void 0===n.expected_turn_id)return vi("invalid_arguments","A steer needs expected_turn_id (the target's current turn_epoch).");let s=Buffer.byteLength(n.text);if(s>H)return vi("message_too_large",`The message is ${s} bytes, above the 1048576-byte limit.`);let a=await e.resolve(n.target,{all_scope:n.all_scope});if("error"===a.kind)return a;let o=a.target,d="routable"===o.liveness?o.endpoint:null;if(null===d&&"refuse"===function(e,t,i,n){return"offline"===e?"steer"===t?{kind:"refuse",reason:"turn_conflict"}:{kind:"queued_offline"}:"steer"===t?"mid_turn"!==e?{kind:"refuse",reason:"not_steerable"}:null===i||null===n||i!==n?{kind:"refuse",reason:"turn_conflict"}:{kind:"admit",deliverAs:"steer",expected_turn_id:i,expect:"steered"}:{kind:"admit",deliverAs:"followUp",expect:"idle"===e?"started":"queued"}}("offline",r,n.expected_turn_id??null,null).kind)return vi("turn_conflict","The target has no live turn to steer.",{target:o.durable_id});let u=function(e){if("session"===e.kind)return{principal:`session:${e.durable_id}`,rate_principal:`session:${e.durable_id}`,node:e.durable_id,turn:e.turn_id??null,cause:e.cause_delivery_id??null,actor:e.name??e.durable_id,origin:()=>({session:e.durable_id}),binding:null};if("cli"===e.kind){let t=`cli:${e.uid}`;return{principal:t,rate_principal:t,node:t,turn:null,cause:null,actor:e.user,origin:t=>({external:{platform:"cli",account_id:e.user,chat_id:"@cli",thread_id:"@chat",message_id:t}}),binding:null}}let t=`binding:${e.binding_id}`,i=e.origin.author;return{principal:t,rate_principal:void 0===i?t:`${t}#author:${i.platform_user_id}`,node:t,turn:null,cause:null,actor:e.origin.account_id,origin:()=>({external:e.origin}),binding:{binding_id:e.binding_id,revision:e.binding_revision}}}(n.sender),_=hi(),l=n.idempotency_key??`auto:${_}`,c=await t.enqueue({now:i(),delivery_id:_,target_durable_id:o.durable_id,sender_principal:u.principal,rate_principal:u.rate_principal,sender_node:u.node,sender_turn:u.turn,cause_delivery_id:u.cause,claimed_root_id:n.root_id??null,origin:u.origin(_),actor:u.actor,body:n.text,mode:r,expected_turn_id:n.expected_turn_id??null,binding:u.binding,receipt:{idempotency_key:l,args_hash:wi({target:o.durable_id,text:n.text,mode:r,expected_turn_id:n.expected_turn_id??null,binding:u.binding,author:"external"===n.sender.kind?n.sender.origin.author:void 0})},endpoint_kind:d?.kind??null});if("busy"===c.kind)return vi("overloaded","The gateway store is locked by a suspended writer; nothing was sent.",{budget:"store_lock"});if("refused"===c.kind)return vi(c.code,c.message,c.details);if("replay"===c.kind){let e=c.result;return"ok"===e.kind?{...e,deduplicated:!0}:e}let p=async e=>(await t.completeReceipt({now:i(),principal:u.principal,idempotency_key:l,result:e}),e);try{if(null===d)return await p(Te(c.row,c.queue_position,null,!1,!0));let i=!0;try{await e.endpoints.wake(d,[_])}catch{i=!1}let n=await t.deliveryView(_);if(null===n)throw Error(`delivery ${_} vanished after commit`);return await p(Te(n.row,n.queue_position,d.kind,!1,!i))}catch(e){throw await t.abandonReceipt({now:i(),principal:u.principal,idempotency_key:l,error_note:e instanceof Error?e.message:String(e)}).catch(()=>!1),e}}}}({store:l,endpoints:c,resolve:async(e,t)=>{let i=await n(e,t);return"error"===i.kind?i:{kind:"ok",target:{...i.target,endpoint:null,liveness:"dead"}}}}),g=Ii({store:l,engine:p,endpoints:c,locate:async()=>null});return{tx:{all:(t,i,n,r)=>_(i,()=>{for(let e of t)Ti(e);return void 0!==r&&Ti(r),e.sql.all(t,i,n,r)}),one:(t,i,n)=>_(i,()=>{for(let e of t)Ti(e);return e.sql.one(t,i,n)}),exec:(t,i)=>_(t,()=>e.sql.run(t,i)),enqueue:e=>u(()=>g.inbound(e)),outboxAck:e=>u(()=>g.ack(e)),bind:e=>u(()=>g.bind(e)),unbind:e=>u(()=>g.unbind(e)),rebind:e=>u(()=>g.rebind(e)),bindingFor:t=>u(()=>async function(e,t){return await Me(e,"binding_for",()=>(kt(e,t.now),wt(e,"platform = ? AND account_id = ? AND chat_id = ? AND thread_id = ? AND status = 'active'",[t.platform,t.account_id,t.chat_id,t.thread_id])[0]??null))}(e,{...t,now:i})),outboxPending:e=>u(()=>g.outbox(e))},cancel:()=>{s=!1,a=!0,g.dispose()},finish:async()=>{if(s=!1,await o,g.dispose(),void 0!==r)throw r}}}function Mi(e,t){return{kind:"refused",code:e,message:t}}function $i(e){let t=e instanceof Error?e.message:String(e);return e instanceof li||e instanceof Ne?Mi(e.code,t):u(e)?Mi("gateway_lock_wait_exceeded",t):Mi("extension_operation_failed",t)}class Hi{ctx;resolveTarget;registered=new Map;constructor(e,t){this.ctx=e,this.resolveTarget=t}async register(e,t){if(!/^[a-z][a-z0-9_]{1,31}$/.test(e.name)||!Array.isArray(e.migrations)||!e.migrations.every(e=>Array.isArray(e)&&e.every(e=>"string"==typeof e)))return Mi("invalid_arguments","An extension needs a valid namespace and an array of SQL migration steps.");try{!function(e,t){let i=e.all(["name"],"SELECT name FROM extension_objects WHERE owner IS NULL");if(["gateway","thread","sqlite"].includes(t)||i.some(e=>pi(String(e.name)).startsWith(t)))throw new li(`Extension name ${t} collides with a core namespace.`)}(this.ctx.sql,e.name)}catch(e){return $i(e)}let i;try{let t=new URL(e.moduleUrl);if("file:"!==t.protocol||![".js",".mjs",".cjs"].includes(Yt(t.pathname)))return Mi("extension_import_failed","moduleUrl must name a compiled JavaScript file URL.");i=await(import(e.moduleUrl))}catch(t){return Mi("extension_import_failed",`Cannot import extension ${e.name}: ${t instanceof Error?t.message:String(t)}`)}try{let n=await this.ensure(e,t);return this.registered.set(e.name,{descriptor:e,module:i}),{kind:"ok",value:{version:n}}}catch(t){return t instanceof Ne||this.registered.set(e.name,{descriptor:e,module:i}),$i(t)}}holds(e){return this.registered.get(e.name)?.descriptor===e}async ensure(e,t){let{name:i,migrations:n}=e;for(;;){let e=await Me(this.ctx,"extension_migrate",()=>{let e=this.ctx.sql.one(["version"],"SELECT version FROM extension_schema WHERE name = ?",[i]),r=Number(e?.version??0);if(r>n.length)throw new Ne(r,n.length,`Extension ${i}`);let s=mi(this.ctx.sql);if(void 0===e&&s.objects.some(e=>pi(String(e.name)).startsWith(`${i}_`)&&null==s.owners.get(`${String(e.type)}:${pi(String(e.name))}`)))throw new li(`Namespace ${i} already contains unowned objects.`);if(r===n.length)return void 0===e&&this.ctx.sql.run("INSERT INTO extension_schema (name, version, updated_at) VALUES (?, 0, ?)",[i,t]),{version:r,applied:!1};for(let e of n[r]){Ti(e);let t=mi(this.ctx.sql);fi(this.ctx.sql,i,()=>this.ctx.sql.exec(e)),bi(this.ctx.sql,i,t,mi(this.ctx.sql))}return bi(this.ctx.sql,i,s,mi(this.ctx.sql)),this.ctx.sql.run("INSERT INTO extension_schema (name, version, updated_at) VALUES (?, ?, ?) ON CONFLICT(name) DO UPDATE SET version = excluded.version, updated_at = excluded.updated_at",[i,r+1,t]),{version:r+1,applied:!0}});if(!e.applied)return e.version}}async call(e,t,i,n){let r=this.registered.get(e);if(void 0===r)return Mi("extension_unknown_name",`No store extension is registered as ${e}.`);let s=Object.hasOwn(r.module,t)?r.module[t]:void 0;if("function"!=typeof s)return Mi("extension_unknown_op",`Extension ${e} exports no operation ${t}.`);let a,o=[],d=[];try{await this.ensure(r.descriptor,n),a=await Me(this.ctx,"extension_call",async()=>{let r,a=mi(this.ctx.sql),u=Ui({...this.ctx,afterCommit:o,afterRollback:d},e,n,this.resolveTarget);try{let n=async()=>{try{return await s(u.tx,i)}finally{await u.finish()}},o=new Promise((i,n)=>{r=setTimeout(()=>{u.cancel(),n(Error(`Extension ${e}.${t} exceeded its ${this.ctx.config.lock_wait_max_ms} ms operation budget.`))},this.ctx.config.lock_wait_max_ms)}),d=await Promise.race([n(),o]);return bi(this.ctx.sql,e,a,mi(this.ctx.sql)),structuredClone(d)}finally{clearTimeout(r),u.cancel()}})}catch(t){for(let t of d)try{t()}catch(t){this.ctx.emit({kind:"extension_error",extension:e,phase:"after_rollback",error:t instanceof Error?t.message:String(t)})}return $i(t)}await this.ctx.hook("afterDbCommit");for(let t of o)try{t()}catch(t){this.ctx.emit({kind:"extension_error",extension:e,phase:"after_commit",error:t instanceof Error?t.message:String(t)})}return{kind:"ok",value:a}}}var Wi=o;if(null===Wi)throw Error("the gateway store worker must run as a worker thread");var Xi,Fi,Pi,ji,Bi=[],Gi=new Map,Ji=!1,Ki=1,Yi=new Map,Vi=(e,t)=>new Promise((i,n)=>{let r=Ki++;Yi.set(r,{resolve:i,reject:n}),Wi.postMessage({type:"resolve",id:r,address:e,request:t})});function zi(e){Qi(e instanceof Ci?{kind:"extension_error",extension:e.extension,phase:"stale_transaction",error:e.message}:{kind:"extension_error",extension:ji??"worker",phase:"async",error:e instanceof Error?e.message:String(e)})}function Qi(e){Wi?.postMessage({type:"event",event:e})}async function Zi(o,u){if("init"===o)return await async function(o){let{config:u}=o,c=l(u.agent_dir);n(s(c,"inbox"),{recursive:!0,mode:448}),e(c,448);let p=(g=u.agent_dir,_(l(g),"gateway.sqlite"));var g;t(r(p,"a",384)),e(p,384);let m=await(import("node:sqlite"));Fi=new m.DatabaseSync(p,{timeout:u.busy_timeout_ms});let f=new y(Fi);f.exec(`PRAGMA busy_timeout = ${Math.trunc(u.busy_timeout_ms)}`);let E=Date.now();for(;;)try{f.exec("PRAGMA journal_mode = WAL");break}catch(e){if(!w(e))throw e;let t=Date.now()-E;if(t+10>u.lock_wait_max_ms)throw Qi({kind:"lock_wait_exceeded",op:"open",waited_ms:t}),d("open",t,u.lock_wait_max_ms);await a(10)}f.exec("PRAGMA synchronous = FULL");for(let t of["-wal","-shm"])i(`${p}${t}`)&&e(`${p}${t}`,384);let h={pid:process.pid,process_start_time:await b(process.pid),instance_id:u.instance_id,runtime_instance:u.runtime_instance};Xi={sql:f,config:u,self:h,stats:{writes:0,marker_unlinks:0,transactions:0},emit:Qi,hook:en,delay:e=>a(e)},await async function(e){if(!(je(e)>=ke.length))for(;;)if(!await Me(e,"migrate",()=>{let t=je(e);if(t>=ke.length)return!1;for(let i of ke[t])e.sql.exec(i);return e.sql.exec(`PRAGMA user_version = ${t+1}`),!0}))return}(Xi),Pi=new Hi(Xi,Vi);let v=await async function(e,t){let i=0;for(let n of e.config.legacy_mailbox_directories){let r,s=`legacy_mailbox:${n}`;if(void 0!==e.sql.one(["value"],"SELECT value FROM gateway_meta WHERE key = ?",[s]))continue;try{r=J(n)}catch(t){e.emit({kind:"legacy_mailbox_invalid",directory:n,error:t instanceof Error?t.message:String(t)});continue}if(null===r)continue;let a=st(),o=r.filter(e=>!Re.test(e.target)).map(e=>({message_seq:e.message_seq,target:e.target,reason:"invalid_target"})),d=r.filter(e=>Re.test(e.target));i+=await Me(e,"migrate_legacy",()=>{let i=0;for(let r of d){let s=`legacy-${Pe([n,r.message_seq]).slice(0,32)}`;if(void 0!==qe(e,s))continue;let o=`root-${N()}`,d=`legacy:${n}`;De(e,"INSERT INTO causal_roots (root_id, origin_principal, created_at, expires_at) VALUES (?, ?, ?, ?)",[o,d,t,t+$]);let u=Date.parse(r.accepted_at);Fe(e,{delivery_id:s,target_durable_id:r.target,seq:Xe(e,r.target),sender:d,sender_turn:null,envelope:{origin:{external:{platform:"legacy_mailbox",account_id:a,chat_id:n,thread_id:"@chat",message_id:r.operation_id}},actor:"legacy thread mailbox",via:[d],root_id:o,hop:1,delivery_id:s},body:r.message,bytes:Buffer.byteLength(r.message),mode_requested:r.delivery,mode_effective:null,expected_turn_id:r.expected_turn_id,state:"queued",reason:null,admitted_by:null,claimed_at:null,attempt:0,admission_kind:null,turn_epoch:null,root_id:o,hop:1,created_at:Number.isFinite(u)?u:t,updated_at:t,expires_at:t+M,binding_id:null,binding_revision:null,actor_user_id:null}),$e(e,r.target,s,!0),i++}return De(e,"INSERT INTO gateway_meta (key, value) VALUES (?, ?)",[s,JSON.stringify({migrated_at:t,count:i,skipped:o})]),i}),o.length>0&&e.emit({kind:"legacy_mailbox_skipped",directory:n,items:o})}return i}(Xi,o.now);return Xi.stats.writes=0,Xi.stats.transactions=0,Xi.stats.marker_unlinks=0,{self:h,legacy_migrated:v}}(u);if("close"===o)return Fi?.close(),Fi=void 0,Xi=void 0,Pi=void 0,null;let c=function(){if(void 0===Xi)throw Error("the gateway store is not open");return Xi}();switch(o){case"extension_register":{let e=u;return ji=e.extension.name,{result:await(Pi?.register(e.extension,e.now)),retained:!0===Pi?.holds(e.extension)}}case"extension_call":{let e=u;ji=e.name;try{return await(Pi?.call(e.name,e.op,e.args,e.now))}finally{for(let t of Yi.values())t.reject(new Ci(e.name));Yi.clear()}}case"enqueue":return await Je(c,u);case"reconcile":return await Ze(c,u);case"claim":return await async function(e,t){return await Me(e,"claim",()=>{let i=qe(e,t.delivery_id);return void 0===i||"queued"!==i.state?{kind:"lost",state:i?.state??null}:i.expires_at<=t.now?(Qe(e,i,"refused",t.now,{reason:"expired"}),He(e,i.target_durable_id,i.delivery_id),{kind:"lost",state:"refused"}):(De(e,"UPDATE deliveries SET state = 'admitting', admitted_by = ?, claimed_at = ?, attempt = attempt + 1, mode_effective = ?, updated_at = ? WHERE delivery_id = ? AND state = 'queued'",[JSON.stringify(t.self),t.now,t.lane,t.now,t.delivery_id]),He(e,i.target_durable_id,i.delivery_id),{kind:"claimed",row:qe(e,t.delivery_id)})})}(c,u);case"record_outcome":return await async function(e,t){return await Me(e,"record_outcome",()=>{let i=qe(e,t.delivery_id);if(void 0===i||"admitting"!==i.state&&"admitted"!==i.state||null===i.admitted_by||!E(i.admitted_by,t.self))return{kind:"lost",state:i?.state??null};let n=t.outcome;return"requeue"===n.kind?Qe(e,i,"queued",t.now):"refused"===n.kind?Qe(e,i,"refused",t.now,{reason:n.reason}):(De(e,"UPDATE deliveries SET admission_kind = ?, turn_epoch = ?, updated_at = ? WHERE delivery_id = ?",[n.admission_kind,n.turn_epoch,t.now,i.delivery_id]),i.state!==n.kind&&Qe(e,i,n.kind,t.now)),{kind:"claimed",row:qe(e,t.delivery_id)}})}(c,u);case"refuse_queued":return await async function(e,t){return await Me(e,"refuse",()=>{let i=qe(e,t.delivery_id);return void 0!==i&&"queued"===i.state&&(Qe(e,i,"refused",t.now,{reason:t.reason}),He(e,i.target_durable_id,i.delivery_id),!0)})}(c,u);case"complete_receipt":return await et(c,u);case"abandon_receipt":return await tt(c,u);case"delivery_view":return rt(c,u);case"delivery_receipt":return it(c,u);case"recover_delivery":return await nt(c,u);case"list":return function(e,t){return void 0!==t.target_durable_id?Oe(e,"target_durable_id = ?",[t.target_durable_id],"seq"):void 0!==t.root_id?Oe(e,"root_id = ?",[t.root_id],"created_at, seq"):Oe(e,"1 = 1",[],"created_at, seq")}(c,u);case"is_referenced":return function(e,t){return Number(e.sql.one(["n"],`SELECT COUNT(*) AS n FROM deliveries WHERE target_durable_id = ? AND state IN ${xe}`,[t])?.n??0)>0||Number(e.sql.one(["n"],"SELECT COUNT(*) AS n FROM bindings WHERE session_durable_id = ? AND status = 'active'",[t])?.n??0)>0||We(e,t).length>0}(c,u);case"journal_mode":return function(e){return String(e.sql.one(["journal_mode"],"SELECT journal_mode FROM pragma_journal_mode()")?.journal_mode??"")}(c);case"stats":return function(e){return{...e.stats}}(c);case"tool_receipt_begin":return await St(c,u);case"tool_receipt_settle":return await async function(e,t){return await Me(e,"tool_receipt_settle",()=>{let i="result"in t;return 1===De(e,`UPDATE receipts SET status = ?, ${i?"result":"error_note"} = ?, updated_at = ? WHERE principal = ? AND operation = ? AND idempotency_key = ? AND status = 'prepared' AND owner_instance = ?`,[i?"completed":"uncertain",i?JSON.stringify(t.result):t.error_note,t.now,t.principal,t.operation,t.idempotency_key,e.config.instance_id])})}(c,u);case"bind":return await At(c,u);case"unbind":return await qt(c,u);case"rebind":return await Dt(c,u);case"list_bindings":return await It(c,u);case"binding_view":return await Ct(c,u);case"register_incarnation":return await async function(e,t){await Me(e,"register_incarnation",()=>{De(e,"INSERT INTO session_meta (durable_id, next_seq, incarnation, endpoint_socket, endpoint_kind)\n VALUES (?, (SELECT COALESCE(MAX(seq), 0) + 1 FROM deliveries WHERE target_durable_id = ?), ?, ?, ?)\n ON CONFLICT(durable_id) DO UPDATE SET incarnation = excluded.incarnation,\n endpoint_socket = excluded.endpoint_socket, endpoint_kind = excluded.endpoint_kind",[t.durable_id,t.durable_id,t.incarnation,t.endpoint?.socket??null,t.endpoint?.kind??null])})}(c,u);case"clear_endpoint":return await async function(e,t){await Me(e,"clear_endpoint",()=>{De(e,"UPDATE session_meta SET endpoint_socket = NULL, endpoint_kind = NULL WHERE durable_id = ? AND incarnation = ?",[t.durable_id,t.incarnation])})}(c,u);case"session_owner":return function(e,t){let i=e.sql.one(["incarnation","endpoint_socket","endpoint_kind"],"SELECT incarnation, endpoint_socket, endpoint_kind FROM session_meta WHERE durable_id = ?",[t]);return void 0===i||"string"!=typeof i.incarnation?null:{incarnation:i.incarnation,endpoint:"string"!=typeof i.endpoint_socket||"tui"!==i.endpoint_kind&&"rpc_host"!==i.endpoint_kind?null:{socket:i.endpoint_socket,kind:i.endpoint_kind}}}(c,u);case"report":return await $t(c,u);case"emit_completions":return await Ht(c,u);case"pending_completion_arms":return function(e,t){return Number(e.sql.one(["n"],"SELECT COUNT(*) AS n FROM completion_arms WHERE session_durable_id = ?",[t])?.n??0)}(c,u);case"latest_completion_arm":return function(e,t){let i=e.sql.one(["s"],"SELECT MAX(arm_seq) AS s FROM completion_arms WHERE session_durable_id = ?",[t])?.s;return null==i?null:Number(i)}(c,u);case"read_outbox":return await Xt(c,u);case"ack_outbox":return await Ft(c,u);case"claim_answer":return await jt(c,u);case"release_answer":return await Gt(c,u);case"confirm_answer":return await Kt(c,u);case"mark_prior_delivered":return await Jt(c,u);case"close_question":return await async function(e,t){return await Me(e,"close_question",()=>{let i=e.sql.all(["cursor","binding_id"],"SELECT cursor, binding_id FROM outbox WHERE event_kind = 'question' AND session_durable_id = ? AND ui_request_id = ? AND (question_state = 'pending' OR (question_state = 'answered' AND answer_state = 'in_flight'))",[t.session_durable_id,t.ui_request_id],"cursor");for(let n of i)De(e,"UPDATE outbox SET question_state = 'answered', answer_state = 'delivered', answer = NULL, answered_at = ?, answered_by = NULL WHERE cursor = ? AND (question_state = 'pending' OR (question_state = 'answered' AND answer_state = 'in_flight'))",[t.now,Number(n.cursor)]),yt(e,String(n.binding_id),Number(n.cursor),t.now);return i.length})}(c,u);default:throw Error(`unknown gateway store op: ${o}`)}}async function en(e){let t=Xi?.config.test_hooks[e];if(void 0===t)return;if("throw"===t)throw Error(`gateway test hook ${e}`);"sigkill"===t&&(process.kill(process.pid,"SIGKILL"),await new Promise(()=>{}));let i=new Promise(t=>Gi.set(e,t));Qi({kind:"paused",hook:e}),await i}process.on("uncaughtException",zi),process.on("unhandledRejection",zi),Wi.on("message",e=>{if("resolution"===e.type){let t=Yi.get(e.id);return Yi.delete(e.id),void(e.ok?t?.resolve(e.value):t?.reject(Error(e.error)))}if("resume"===e.type)return Gi.get(e.hook)?.(),void Gi.delete(e.hook);Bi.push(e),async function(){if(Ji)return;Ji=!0;try{for(let e=Bi.shift();void 0!==e;e=Bi.shift())try{let t=await Zi(e.op,e.args);Wi?.postMessage({type:"response",id:e.id,ok:!0,value:t})}catch(t){Wi?.postMessage({type:"response",id:e.id,ok:!1,error:{message:t instanceof Error?t.message:String(t),stack:t instanceof Error?t.stack:void 0,code:"string"==typeof t?.code?t.code:void 0}})}}finally{Ji=!1}}()});