@north-light/cli 0.3.524 → 0.3.526
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/command-manifest/result.d.ts +4 -2
- package/dist/api/command-manifest/result.js +1 -1
- package/dist/api/command-manifest/schema.js +1 -1
- package/dist/api/plugin-manifest-schema.d.ts +3 -0
- package/dist/builtin-memory/crouter-plugin/deploying.md +2 -2
- package/dist/builtin-memory/crouter-plugin/output.md +3 -1
- package/dist/clients/attach/chrome/roster.d.ts +1 -1
- package/dist/clients/attach/chrome/roster.js +4 -4
- package/dist/clients/attach/render/chat-view.d.ts +9 -0
- package/dist/clients/attach/render/chat-view.js +3 -3
- package/dist/clients/attach/render/page-block.d.ts +2 -0
- package/dist/clients/attach/render/page-block.js +1 -1
- package/dist/clients/attach/session/connection.d.ts +1 -1
- package/dist/clients/attach/session/context.d.ts +1 -1
- package/dist/clients/attach/session/profile-files.d.ts +3 -3
- package/dist/clients/attach/session/profile-files.js +1 -1
- package/dist/clients/attach/viewer.js +633 -756
- package/dist/commands/pkg/browse/command-view.js +1 -1
- package/dist/core/canvas/db.d.ts +28 -2
- package/dist/core/canvas/db.js +2 -2
- package/dist/core/canvas/migrations.js +53 -53
- package/dist/core/canvas/nav-model.js +1 -1
- package/dist/core/canvas/recovery.d.ts +13 -0
- package/dist/core/canvas/recovery.js +2 -2
- package/dist/core/conversation-store/client.d.ts +2 -2
- package/dist/core/conversation-store/index.d.ts +30 -2
- package/dist/core/conversation-store/index.js +1 -1
- package/dist/core/conversation-store/patch.js +1 -1
- package/dist/core/graph/watches.d.ts +2 -0
- package/dist/core/graph/watches.js +9 -9
- package/dist/core/help.js +7 -7
- package/dist/core/llm/run.js +2 -2
- package/dist/core/runtime/broker/fault-retry.d.ts +9 -3
- package/dist/core/runtime/broker/fault-retry.js +1 -1
- package/dist/core/runtime/broker/rebind.d.ts +4 -0
- package/dist/core/runtime/broker/rebind.js +1 -1
- package/dist/core/runtime/broker/run-turn-queue.d.ts +2 -0
- package/dist/core/runtime/broker/run-turn-queue.js +1 -1
- package/dist/core/runtime/broker-persona-guidance.d.ts +1 -1
- package/dist/core/runtime/broker-persona-guidance.js +3 -3
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/close.d.ts +2 -2
- package/dist/core/runtime/close.js +1 -1
- package/dist/daemon/crtrd.js +8 -8
- package/dist/daemon/reconcilers/broker-supervision.d.ts +6 -2
- package/dist/daemon/reconcilers/broker-supervision.js +4 -4
- package/dist/daemon/runs/observer.js +2 -2
- package/docs/plugin/deploying.md +2 -2
- package/docs/plugin/output.md +3 -1
- package/package.json +2 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +12 -12
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var ie=Object.defineProperty;var o=(e,n)=>ie(e,"name",{value:n,configurable:!0});import{prepared as s}from"../sqlite-statements.js";import{randomUUID as F}from"node:crypto";import{existsSync as f,readdirSync as oe,readFileSync as se,realpathSync as de,statSync as ae}from"node:fs";import{join as N,resolve as ue}from"node:path";import{openDb as E,prepared as ce,withCanvasWrite as l}from"./db.js";import{jobDir as _e,nodesRoot as C}from"./paths.js";import{errorClassFromFault as $}from"../fault-classifier.js";import{parseProviderRateLimit as le}from"../provider-failure.js";import{emitEvent as j}from"../events/emit.js";import{operationIdContext as B,validateOperationId as J}from"../events/operation-id.js";const Me=5*6e4,pe=500,K=["pi\u2192provider","viewer\u2194broker","relay\u2194broker","viewer\u2194crtrd","daemon\u2192node","crtr\u2192pi"],Ee=[...K,"broker\u2194crtrd"],fe=["rate-limit","overloaded","connection","auth","protocol","context-overflow","other","wedged","model-not-found"],ye=["auto","manual","fatal"],Te=["sdk","daemon","client"],Ne=["pending","admitted","invalidated"];function c(){return new Date().toISOString()}o(c,"now");function b(e,n){return new Set(e.prepare(`PRAGMA table_info(${n})`).all().map(({name:t})=>t))}o(b,"tableColumns");function ge(e){const n=b(e,"executions"),t=[["turn_open_at","TEXT"],["turn_progress_at","TEXT"],["turn_closed_at","TEXT"],["turn_end_reason","TEXT CHECK (turn_end_reason IS NULL OR turn_end_reason IN ('settled', 'teardown-aborted'))"],["exit_diagnostic_json","TEXT"]];for(const[r,i]of t)n.has(r)||e.exec(`ALTER TABLE executions ADD COLUMN ${r} ${i}`)}o(ge,"addExecutionColumns");function Le(e){e.exec(`
|
|
2
2
|
CREATE TABLE IF NOT EXISTS node_faults (
|
|
3
3
|
fault_id TEXT PRIMARY KEY,
|
|
4
4
|
node_id TEXT NOT NULL REFERENCES nodes(node_id) ON DELETE CASCADE,
|
|
@@ -23,4 +23,4 @@ CREATE TABLE IF NOT EXISTS node_faults (
|
|
|
23
23
|
);
|
|
24
24
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_node_faults_active ON node_faults(node_id) WHERE active = 1;
|
|
25
25
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_node_faults_episode ON node_faults(node_id) WHERE episode_state IS NOT NULL;
|
|
26
|
-
`)}o(ge,"createFaultTable");function g(e,n){return typeof n=="string"&&e.includes(n)}o(g,"contains");function F(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}o(F,"isRecord");function K(e){if(!F(e)||typeof e.provider!="string"||e.provider===""||typeof e.model!="string"||e.model==="")return;const n=typeof e.status=="number"&&Number.isFinite(e.status)?e.status:void 0,t=typeof e.code=="string"||typeof e.code=="number"?e.code:void 0,r=typeof e.errno=="string"?e.errno:void 0,i=typeof e.body=="string"?e.body:void 0,d=_e(e.ratelimit),a=Array.isArray(e.causes)?e.causes.flatMap(u=>{if(!F(u))return[];const f={...typeof u.message=="string"?{message:u.message}:{},...typeof u.status=="number"&&Number.isFinite(u.status)?{status:u.status}:{},...typeof u.code=="string"||typeof u.code=="number"?{code:u.code}:{},...typeof u.errno=="string"?{errno:u.errno}:{},...typeof u.body=="string"?{body:u.body}:{}};return Object.keys(f).length===0?[]:[f]}):void 0;return{provider:e.provider,model:e.model,...n===void 0?{}:{status:n},...t===void 0?{}:{code:t},...r===void 0?{}:{errno:r},...i===void 0?{}:{body:i},...a===void 0||a.length===0?{}:{causes:a},...d===void 0?{}:{ratelimit:d}}}o(K,"parseProviderError");function Y(e){try{const n=JSON.parse(e);if(!g(pe,n.link)||typeof n.op!="string"||n.op===""||!g(Ee,n.kind)||typeof n.message!="string"||typeof n.since!="string")return null;const t=j(n.operation_id);if(!F(n.retry)||!g(fe,n.retry.disposition)||n.retry.by!==void 0&&!g(ye,n.retry.by)||n.retry.attempt!==void 0&&typeof n.retry.attempt!="number"||n.retry.max!==void 0&&typeof n.retry.max!="number"||n.retry.nextAt!==void 0&&typeof n.retry.nextAt!="string"||n.anchorEntryId!==void 0&&(typeof n.anchorEntryId!="string"||n.anchorEntryId===""))return null;const r=n.providerError===void 0?void 0:K(n.providerError);return n.providerError!==void 0&&r===void 0?null:{link:n.link,op:n.op,kind:n.kind,retry:{disposition:n.retry.disposition,...n.retry.by===void 0?{}:{by:n.retry.by},...n.retry.attempt===void 0?{}:{attempt:n.retry.attempt},...n.retry.max===void 0?{}:{max:n.retry.max},...n.retry.nextAt===void 0?{}:{nextAt:n.retry.nextAt}},message:n.message,since:n.since,operation_id:t,...n.anchorEntryId===void 0?{}:{anchorEntryId:n.anchorEntryId},...r===void 0?{}:{providerError:r}}}catch{return null}}o(Y,"parseLegacyFault");function Le(e){const n=ae(e);try{return se(n)}catch{return n}}o(Le,"canonicalPath");function me(e){try{const n=JSON.parse(e);if(!g(Te,n.state)||typeof n.sessionFile!="string"||n.sessionFile==="")return null;const t=JSON.stringify(n.fault),r=Y(t);if(r===null||r.link!=="pi\u2192provider"||r.retry.disposition!=="auto"||r.retry.by!=="daemon")return null;const i=n.anchorEntryId;return i!==null&&typeof i!="string"||(r.anchorEntryId??null)!==i?null:{state:n.state,sessionFile:Le(n.sessionFile),fault:r}}catch{return null}}o(me,"parseLegacyEpisode");function G(e){return e!==void 0?j(e):$.current()??$.fresh(t=>t)}o(G,"resolveOperationId");function Se(e){return e.slice(0,le)}o(Se,"clampMessage");function R(e){return e.link==="pi\u2192provider"&&e.retry.disposition==="auto"&&e.retry.by==="daemon"?3:e.retry.disposition==="fatal"?2:1}o(R,"faultPriority");function V(e){return{link:e.link,op:e.op,kind:e.kind,message:e.message,since:e.since,operationId:e.operation_id,anchorEntryId:e.anchorEntryId??null,retryDisposition:e.retry.disposition,retryBy:e.retry.by??null,retryAttempt:e.retry.attempt??null,retryMax:e.retry.max??null,retryNextAt:e.retry.nextAt??null,providerError:e.providerError===void 0?null:JSON.stringify(e.providerError)}}o(V,"encodeFault");function H(e){const n=e.provider_error_json,t=typeof n=="string"?K(JSON.parse(n)):void 0;if(typeof n=="string"&&t===void 0)throw new Error(`invalid provider error on stored fault ${e.fault_id}`);const r={disposition:e.retry_disposition,...e.retry_by===null?{}:{by:e.retry_by},...e.retry_attempt===null?{}:{attempt:e.retry_attempt},...e.retry_max===null?{}:{max:e.retry_max},...e.retry_next_at===null?{}:{nextAt:e.retry_next_at}};return{faultId:e.fault_id,link:e.link,op:e.op,kind:e.kind,message:e.message,since:e.since,operation_id:e.operation_id,retry:r,...e.anchor_entry_id===null?{}:{anchorEntryId:e.anchor_entry_id},...t===void 0?{}:{providerError:t}}}o(H,"hydrateFault");function L(e,n){const t=ue(e,"SELECT * FROM node_faults WHERE node_id = ? AND active = 1").get(n);return t===void 0?null:H(t)}o(L,"activeFault");function Q(e){if(!g(B,e.link))throw new Error(`fault link is not durable: ${e.link}`);return{link:e.link,op:e.op,kind:e.kind,retry:e.retry,message:Se(e.message),since:e.since??c(),operation_id:G(e.operation_id),...typeof e.anchorEntryId=="string"&&e.anchorEntryId!==""?{anchorEntryId:e.anchorEntryId}:{},...e.providerError===void 0?{}:{providerError:e.providerError}}}o(Q,"storedFault");function q(e,n){X({level:n.retry.disposition==="fatal"?"error":"warn",event:"fault.recorded",operation_id:n.operation_id,node_id:e,error_class:w(n),fields:{link:n.link,op:n.op,kind:n.kind,retry:n.retry,message:n.message,...n.anchorEntryId===void 0?{}:{anchor_entry_id:n.anchorEntryId},...n.providerError===void 0?{}:{provider_error:n.providerError}}})}o(q,"emitRecordedFault");function W(e,n,t,r,i){const d=C(),a=V(t),u=c();return s(e,"INSERT INTO node_faults (fault_id, node_id, link, op, kind, message, since, operation_id, anchor_entry_id, retry_disposition, retry_by, retry_attempt, retry_max, retry_next_at, provider_error_json, active, episode_state, episode_binding_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").run(d,n,a.link,a.op,a.kind,a.message,a.since,a.operationId,a.anchorEntryId,a.retryDisposition,a.retryBy,a.retryAttempt,a.retryMax,a.retryNextAt,a.providerError,r?1:0,i?.state??null,i?.bindingId??null,u,u),{...t,faultId:d}}o(W,"insertFault");function z(e,n,t,r){const i=V(t);return s(e,"UPDATE node_faults SET link = ?, op = ?, kind = ?, message = ?, since = ?, operation_id = ?, anchor_entry_id = ?, retry_disposition = ?, retry_by = ?, retry_attempt = ?, retry_max = ?, retry_next_at = ?, provider_error_json = ?, episode_state = COALESCE(?, episode_state), episode_binding_id = COALESCE(?, episode_binding_id), updated_at = ? WHERE fault_id = ?").run(i.link,i.op,i.kind,i.message,i.since,i.operationId,i.anchorEntryId,i.retryDisposition,i.retryBy,i.retryAttempt,i.retryMax,i.retryNextAt,i.providerError,r?.state??null,r?.bindingId??null,c(),n),{...t,faultId:n}}o(z,"updateFault");function D(e,n){s(e,"DELETE FROM node_faults WHERE fault_id = ? AND active = 0 AND episode_state IS NULL").run(n)}o(D,"deleteIfUnretained");function Z(e,n,t,r){const i=L(e,n);if(i===null){const d=s(e,"SELECT fault_id, link, kind, since, operation_id FROM node_faults WHERE node_id = ? AND active = 0 AND episode_state IS NOT NULL").get(n);return d!==void 0&&d.link===t.link&&d.kind===t.kind&&d.since===t.since&&d.operation_id===t.operation_id?(s(e,"UPDATE node_faults SET active = 1, updated_at = ? WHERE fault_id = ?").run(c(),d.fault_id),z(e,d.fault_id,t)):W(e,n,t,!0,r)}if(i.link===t.link&&i.kind===t.kind){const d={...i.retry,...t.retry};return t.retry.disposition==="fatal"&&!("nextAt"in t.retry)&&delete d.nextAt,z(e,i.faultId,{...t,since:i.since,anchorEntryId:i.anchorEntryId??t.anchorEntryId,retry:d},r)}return R(i)>R(t)?null:(s(e,"UPDATE node_faults SET active = 0, updated_at = ? WHERE fault_id = ?").run(c(),i.faultId),D(e,i.faultId),W(e,n,t,!0,r))}o(Z,"replaceActiveFault");function m(e,n,t){return s(e,"SELECT binding_id FROM sessions WHERE node_id = ? AND session_id = ? AND unbound_at IS NULL").get(n,t)?.binding_id??null}o(m,"liveBinding");function Pe(e,n){return l(t=>{const r=c();return s(t,"UPDATE executions SET turn_progress_at = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(r,e).changes>0?!0:s(t,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = NULL, turn_end_reason = NULL WHERE execution_id = ? AND state != 'exited'").run(r,r,e).changes>0})}o(Pe,"openTurn");function Me(e){return l(n=>s(n,"UPDATE executions SET turn_progress_at = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(c(),e).changes>0)}o(Me,"recordTurnProgress");function we(e,n){return l(t=>{const r=c(),i=s(t,"UPDATE executions SET turn_closed_at = ?, turn_end_reason = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(r,n.endReason,e).changes>0;if(i&&n.endReason==="settled"){const d="(SELECT node_id FROM executions WHERE execution_id = ?)";n.viewerPresent===!0?s(t,`UPDATE nodes SET reply_at = ?, read_at = ? WHERE node_id = ${d}`).run(r,r,e):s(t,`UPDATE nodes SET reply_at = ? WHERE node_id = ${d}`).run(r,e)}return i})}o(we,"closeTurn");function Xe(e){return l(n=>s(n,"UPDATE nodes SET read_at = ? WHERE node_id = ?").run(c(),e).changes>0)}o(Xe,"markNodeRead");function $e(e,n){if(!Number.isInteger(n.consecutivePasses)||n.consecutivePasses<1||n.routes.length===0||!n.routes.every(t=>t!==""))throw new Error("invalid transport-poison verdict");return l(t=>s(t,"UPDATE executions SET exit_diagnostic_json = ? WHERE execution_id = ? AND state != 'exited'").run(JSON.stringify({schema:"crtr.execution-exit-diagnostic/v1",transport_poison:{consecutive_passes:n.consecutivePasses,routes:n.routes}}),e).changes>0)}o($e,"recordTransportPoisonVerdict");function je(e){const n=s(E(),"SELECT exit_diagnostic_json FROM executions WHERE node_id = ? ORDER BY rowid DESC LIMIT 1").get(e);if(n===void 0||n.exit_diagnostic_json===null)return null;try{const t=JSON.parse(n.exit_diagnostic_json),r=t.transport_poison;return t.schema!=="crtr.execution-exit-diagnostic/v1"||r===void 0||!Number.isInteger(r.consecutive_passes)||r.consecutive_passes<1||!Array.isArray(r.routes)||r.routes.length===0||!r.routes.every(i=>typeof i=="string"&&i!=="")?null:{consecutivePasses:r.consecutive_passes,routes:r.routes}}catch{return null}}o(je,"readTransportPoisonVerdict");function Be(e){const n=s(E(),"SELECT turn_open_at, turn_closed_at, turn_progress_at FROM executions WHERE node_id = ? AND state != 'exited'").get(e);return n===void 0?null:{busy:n.turn_open_at!==null&&n.turn_closed_at===null,progressAt:n.turn_progress_at}}o(Be,"readLiveTurn");function Je(e){const n=E(),t=s(n,"SELECT turn_closed_at, turn_progress_at FROM executions WHERE node_id = ? AND turn_open_at IS NOT NULL ORDER BY rowid DESC LIMIT 1").get(e);if(t===void 0)return null;const r=s(n,"SELECT turn_end_reason FROM executions WHERE node_id = ? ORDER BY rowid DESC LIMIT 1").get(e);return{interrupted:t.turn_closed_at===null||r?.turn_end_reason==="teardown-aborted",progressAt:t.turn_progress_at}}o(Je,"readInterruptedTurn");function Ke(e){return s(E(),"SELECT 1 FROM executions WHERE node_id = ? AND turn_open_at IS NOT NULL LIMIT 1").get(e)!==void 0}o(Ke,"hasAdmittedTurn");function Ye(e,n){const t=Q(n);return q(e,t),l(r=>Z(r,e,t))}o(Ye,"recordFault");function Ge(e,n){const t=L(E(),e);return t===null||n?.link!==void 0&&t.link!==n.link?!1:l(r=>{const i=L(r,e);if(i===null||n?.link!==void 0&&i.link!==n.link)return!1;const d=s(r,"SELECT episode_state FROM node_faults WHERE fault_id = ?").get(i.faultId);s(r,"UPDATE node_faults SET active = 0, updated_at = ? WHERE fault_id = ?").run(c(),i.faultId),d.episode_state==="pending"&&n?.preserveEpisode!==!0&&s(r,"UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE fault_id = ?").run(c(),i.faultId),D(r,i.faultId);const a=G();return X({level:"info",event:"fault.cleared",operation_id:a,node_id:e,error_class:w(i),fields:{cleared_fault_operation_id:i.operation_id,link:i.link,op:i.op,kind:i.kind,retry:i.retry,message:i.message,since:i.since,...i.anchorEntryId===void 0?{}:{anchor_entry_id:i.anchorEntryId}}}),!0})}o(Ge,"clearFault");function ee(e){return L(E(),e)}o(ee,"readFault");function Ve(e,n){const t=Q(n.input);if(t.link!=="pi\u2192provider"||t.retry.disposition!=="auto"||t.retry.by!=="daemon")throw new Error("provider retry episode requires an automatic daemon provider fault");return q(e,t),l(r=>{const i=m(r,e,n.sessionId);if(i===null)return null;const d=L(r,e);if(d!==null&&(d.link!==t.link||d.kind!==t.kind)&&R(d)>R(t))return null;const a=s(r,"SELECT fault_id FROM node_faults WHERE node_id = ? AND episode_state IS NOT NULL").all(e);s(r,"UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE node_id = ? AND episode_state IS NOT NULL").run(c(),e);for(const f of a)D(r,f.fault_id);const u=Z(r,e,t,{state:"pending",bindingId:i});return u===null?null:(s(r,"UPDATE node_faults SET episode_state = ?, episode_binding_id = ?, updated_at = ? WHERE fault_id = ?").run("pending",i,c(),u.faultId),u)})}o(Ve,"recordPendingEpisode");function Qe(e,n){return l(t=>{if(s(t,"SELECT 1 FROM nodes WHERE node_id = ? AND intent IS 'refresh'").get(e)!==void 0)return!1;const r=m(t,e,n.sessionId);return r===null?!1:s(t,"UPDATE node_faults SET episode_state = 'admitted', retry_disposition = ?, retry_by = ?, retry_attempt = ?, retry_max = ?, retry_next_at = ?, updated_at = ? WHERE node_id = ? AND fault_id = ? AND episode_state = 'pending' AND episode_binding_id = ?").run(n.retry.disposition,n.retry.by??null,n.retry.attempt??null,n.retry.max??null,n.retry.nextAt??null,c(),e,n.faultId,r).changes>0})}o(Qe,"admitEpisode");function qe(e,n){return l(t=>{const r=m(t,e,n.sessionId);return r===null?!1:s(t,"UPDATE node_faults SET episode_state = 'pending', updated_at = ? WHERE node_id = ? AND episode_state = 'admitted' AND episode_binding_id = ?").run(c(),e,r).changes>0})}o(qe,"reopenEpisode");function ze(e,n){return l(t=>{const r=m(t,e,n.sessionId);return r===null?!1:s(t,"UPDATE node_faults SET episode_state = 'invalidated', updated_at = ? WHERE node_id = ? AND episode_state != 'invalidated' AND episode_state IS NOT NULL AND episode_binding_id = ?").run(c(),e,r).changes>0})}o(ze,"invalidateEpisode");function Ze(e,n){return l(t=>{const r=m(t,e,n.sessionId);if(r===null)return!1;const i=s(t,"SELECT fault_id FROM node_faults WHERE node_id = ? AND episode_binding_id = ? AND episode_state IS NOT NULL").all(e,r);if(i.length===0)return!1;s(t,"UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE node_id = ? AND episode_binding_id = ? AND episode_state IS NOT NULL").run(c(),e,r);for(const d of i)D(t,d.fault_id);return!0})}o(Ze,"clearEpisode");function en(e){const n=s(E(),"SELECT f.*, s.session_id FROM node_faults f JOIN sessions s ON s.binding_id = f.episode_binding_id WHERE f.node_id = ? AND f.episode_state IS NOT NULL").get(e);return n===void 0?null:{state:n.episode_state,sessionId:n.session_id,fault:H(n)}}o(en,"readEpisode");function nn(){return s(E(),"SELECT f.*, s.session_id AS bound_session_id FROM node_faults f JOIN sessions s ON s.binding_id = f.episode_binding_id WHERE f.active = 1 AND f.episode_state = 'pending' AND s.unbound_at IS NULL AND s.session_id IS NOT NULL AND f.link = 'pi\u2192provider' AND f.retry_disposition = 'auto' AND f.retry_by = 'daemon' AND f.kind IN ('connection', 'rate-limit', 'overloaded')").all().map(n=>({nodeId:n.node_id,sessionId:n.bound_session_id,fault:H(n),updatedAt:n.updated_at}))}o(nn,"listPendingProviderRetries");function tn(e){const n=ee(e)===null;return{explanation(){if(!n)return null;const t=ee(e);if(t===null||t.link!=="crtr\u2192pi"||t.retry.disposition!=="fatal")return null;const r=t.op.trim(),i=t.message.trim();return r===""||i===""?null:`${r}: ${i}`}}}o(tn,"beginBootFaultAttempt");function ne(e,n){try{return de(e).mtime.toISOString()}catch{return n}}o(ne,"markerMtime");function P(e,n){if(!p(e))return null;try{return oe(e,"utf8")}catch(t){if(!n)return null;throw new Error(`cannot import recovery input ${e}: ${t.message}`)}}o(P,"legacyFile");function Ae(e,n){return s(e,"SELECT execution_id, started_at FROM executions WHERE node_id = ? ORDER BY rowid DESC LIMIT 1").get(n)??null}o(Ae,"latestExecution");function xe(e,n){const r=J(e,"nodes").has("launched_at")?s(e,"SELECT COALESCE(launched_at, created) AS started_at FROM nodes WHERE node_id = ?").get(n):s(e,"SELECT created AS started_at FROM nodes WHERE node_id = ?").get(n);if(r===void 0)throw new Error(`cannot import recovery witness for unknown node ${n}`);const i=C();return s(e,"INSERT INTO executions (execution_id, node_id, daemon_epoch, pid, process_identity, state, started_at, ended_at, exit_reason) VALUES (?, ?, NULL, NULL, NULL, 'exited', ?, ?, 'pre-consolidation')").run(i,n,r.started_at,r.started_at),{execution_id:i,started_at:r.started_at}}o(xe,"syntheticExecution");function te(e,n,t,r,i){return W(e,n,t,r,i)}o(te,"insertMigratedFault");function Ie(e,n,t,r){const i=s(e,"SELECT binding_id, node_id FROM sessions WHERE transcript_path = ? AND unbound_at IS NULL").get(t);if(i!==void 0){if(i.node_id!==n)throw new Error(`cannot import provider retry ${r}: transcript is live-owned by ${i.node_id}`);return i.binding_id}const d=s(e,"SELECT binding_id FROM sessions WHERE node_id = ? AND transcript_path = ? ORDER BY rowid DESC LIMIT 1").get(n,t);if(d!==void 0)return d.binding_id;const a=s(e,"SELECT created FROM nodes WHERE node_id = ?").get(n);if(a===void 0)throw new Error(`cannot import provider retry ${r}: unknown node ${n}`);const u=C();return s(e,"INSERT INTO sessions (binding_id, session_id, node_id, transcript_path, source_session_id, fork_entry_id, created_at, bound_at, unbound_at) VALUES (?, NULL, ?, ?, NULL, NULL, ?, ?, ?)").run(u,n,t,a.created,a.created,c()),u}o(Ie,"migrationBinding");function rn(e){if(Ne(e),ge(e),!p(b()))return;const n=ie(b(),{withFileTypes:!0}).filter(r=>r.isDirectory()).sort((r,i)=>r.name.localeCompare(i.name)),t=s(e,"SELECT 1 FROM nodes WHERE node_id = ?");for(const r of n){const i=r.name,d=ce(i),a=N(d,"busy"),u=N(d,"clean-abort"),f=N(d,"transport-poison.json"),h=N(d,"fault"),S=N(d,"provider-retry"),O=p(a),U=p(u);if(!O&&!U&&!p(f)&&!p(h)&&!p(S)||!p(N(b(),i,"meta.json"))&&t.get(i)===void 0)continue;const k=P(f,!1),A=P(h,!0),x=P(S,!0);if(!O&&!U&&k===null&&A===null&&x===null)continue;let y=Ae(e,i);if(y===null&&(y=xe(e,i)),O){const _=ne(a,y.started_at);s(e,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = NULL, turn_end_reason = NULL WHERE execution_id = ?").run(_,_,y.execution_id)}else if(U){const _=ne(u,y.started_at);s(e,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = ?, turn_end_reason = 'teardown-aborted' WHERE execution_id = ?").run(_,_,_,y.execution_id)}if(k!==null)try{const _=JSON.parse(k);Number.isInteger(_.consecutivePasses)&&_.consecutivePasses>=1&&Array.isArray(_.routes)&&_.routes.length>0&&_.routes.every(M=>typeof M=="string"&&M!=="")&&s(e,"UPDATE executions SET exit_diagnostic_json = ? WHERE execution_id = ?").run(JSON.stringify({schema:"crtr.execution-exit-diagnostic/v1",transport_poison:{consecutive_passes:_.consecutivePasses,routes:_.routes}}),y.execution_id)}catch{}const I=A===null?null:Y(A);if(A!==null&&I===null)throw new Error(`cannot import recovery fault ${h}`);const T=x===null?null:me(x);if(x!==null&&T===null)throw new Error(`cannot import provider retry ${S}`);let v=I===null||I.link==="broker\u2194crtrd"?null:te(e,i,I,!0);if(T!==null){const _=Ie(e,i,T.sessionFile,S);v!==null&&v.since===T.fault.since?s(e,"UPDATE node_faults SET episode_state = ?, episode_binding_id = ?, updated_at = ? WHERE fault_id = ?").run(T.state,_,c(),v.faultId):te(e,i,T.fault,!1,{state:T.state,bindingId:_})}}}o(rn,"migrateRecoveryWitnesses");export{We as FAULT_QUIET_MS,Qe as admitEpisode,tn as beginBootFaultAttempt,Ze as clearEpisode,Ge as clearFault,we as closeTurn,Ke as hasAdmittedTurn,H as hydrateFault,ze as invalidateEpisode,nn as listPendingProviderRetries,Xe as markNodeRead,rn as migrateRecoveryWitnesses,Pe as openTurn,K as parseProviderError,en as readEpisode,ee as readFault,Je as readInterruptedTurn,Be as readLiveTurn,je as readTransportPoisonVerdict,Ye as recordFault,Ve as recordPendingEpisode,$e as recordTransportPoisonVerdict,Me as recordTurnProgress,qe as reopenEpisode};
|
|
26
|
+
`)}o(Le,"createFaultTable");function g(e,n){return typeof n=="string"&&e.includes(n)}o(g,"contains");function H(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}o(H,"isRecord");function Y(e){if(!H(e)||typeof e.provider!="string"||e.provider===""||typeof e.model!="string"||e.model==="")return;const n=typeof e.status=="number"&&Number.isFinite(e.status)?e.status:void 0,t=typeof e.code=="string"||typeof e.code=="number"?e.code:void 0,r=typeof e.errno=="string"?e.errno:void 0,i=typeof e.body=="string"?e.body:void 0,d=le(e.ratelimit),a=Array.isArray(e.causes)?e.causes.flatMap(u=>{if(!H(u))return[];const p={...typeof u.message=="string"?{message:u.message}:{},...typeof u.status=="number"&&Number.isFinite(u.status)?{status:u.status}:{},...typeof u.code=="string"||typeof u.code=="number"?{code:u.code}:{},...typeof u.errno=="string"?{errno:u.errno}:{},...typeof u.body=="string"?{body:u.body}:{}};return Object.keys(p).length===0?[]:[p]}):void 0;return{provider:e.provider,model:e.model,...n===void 0?{}:{status:n},...t===void 0?{}:{code:t},...r===void 0?{}:{errno:r},...i===void 0?{}:{body:i},...a===void 0||a.length===0?{}:{causes:a},...d===void 0?{}:{ratelimit:d}}}o(Y,"parseProviderError");function G(e){try{const n=JSON.parse(e);if(!g(Ee,n.link)||typeof n.op!="string"||n.op===""||!g(fe,n.kind)||typeof n.message!="string"||typeof n.since!="string")return null;const t=J(n.operation_id);if(!H(n.retry)||!g(ye,n.retry.disposition)||n.retry.by!==void 0&&!g(Te,n.retry.by)||n.retry.attempt!==void 0&&typeof n.retry.attempt!="number"||n.retry.max!==void 0&&typeof n.retry.max!="number"||n.retry.nextAt!==void 0&&typeof n.retry.nextAt!="string"||n.anchorEntryId!==void 0&&(typeof n.anchorEntryId!="string"||n.anchorEntryId===""))return null;const r=n.providerError===void 0?void 0:Y(n.providerError);return n.providerError!==void 0&&r===void 0?null:{link:n.link,op:n.op,kind:n.kind,retry:{disposition:n.retry.disposition,...n.retry.by===void 0?{}:{by:n.retry.by},...n.retry.attempt===void 0?{}:{attempt:n.retry.attempt},...n.retry.max===void 0?{}:{max:n.retry.max},...n.retry.nextAt===void 0?{}:{nextAt:n.retry.nextAt}},message:n.message,since:n.since,operation_id:t,...n.anchorEntryId===void 0?{}:{anchorEntryId:n.anchorEntryId},...r===void 0?{}:{providerError:r}}}catch{return null}}o(G,"parseLegacyFault");function me(e){const n=ue(e);try{return de(n)}catch{return n}}o(me,"canonicalPath");function Ae(e){try{const n=JSON.parse(e);if(!g(Ne,n.state)||typeof n.sessionFile!="string"||n.sessionFile==="")return null;const t=JSON.stringify(n.fault),r=G(t);if(r===null||r.link!=="pi\u2192provider"||r.retry.disposition!=="auto"||r.retry.by!=="daemon")return null;const i=n.anchorEntryId;return i!==null&&typeof i!="string"||(r.anchorEntryId??null)!==i?null:{state:n.state,sessionFile:me(n.sessionFile),fault:r}}catch{return null}}o(Ae,"parseLegacyEpisode");function V(e){return e!==void 0?J(e):B.current()??B.fresh(t=>t)}o(V,"resolveOperationId");function Se(e){return e.slice(0,pe)}o(Se,"clampMessage");function I(e){return e.link==="pi\u2192provider"&&e.retry.disposition==="auto"&&e.retry.by==="daemon"?3:e.retry.disposition==="fatal"?2:1}o(I,"faultPriority");function Q(e){return{link:e.link,op:e.op,kind:e.kind,message:e.message,since:e.since,operationId:e.operation_id,anchorEntryId:e.anchorEntryId??null,retryDisposition:e.retry.disposition,retryBy:e.retry.by??null,retryAttempt:e.retry.attempt??null,retryMax:e.retry.max??null,retryNextAt:e.retry.nextAt??null,providerError:e.providerError===void 0?null:JSON.stringify(e.providerError)}}o(Q,"encodeFault");function W(e){const n=e.provider_error_json,t=typeof n=="string"?Y(JSON.parse(n)):void 0;if(typeof n=="string"&&t===void 0)throw new Error(`invalid provider error on stored fault ${e.fault_id}`);const r={disposition:e.retry_disposition,...e.retry_by===null?{}:{by:e.retry_by},...e.retry_attempt===null?{}:{attempt:e.retry_attempt},...e.retry_max===null?{}:{max:e.retry_max},...e.retry_next_at===null?{}:{nextAt:e.retry_next_at}};return{faultId:e.fault_id,link:e.link,op:e.op,kind:e.kind,message:e.message,since:e.since,operation_id:e.operation_id,retry:r,...e.anchor_entry_id===null?{}:{anchorEntryId:e.anchor_entry_id},...t===void 0?{}:{providerError:t},...typeof e.notified_since=="string"?{notifiedSince:e.notified_since}:{}}}o(W,"hydrateFault");function L(e,n){const t=ce(e,"SELECT * FROM node_faults WHERE node_id = ? AND active = 1").get(n);return t===void 0?null:W(t)}o(L,"activeFault");function q(e){if(!g(K,e.link))throw new Error(`fault link is not durable: ${e.link}`);return{link:e.link,op:e.op,kind:e.kind,retry:e.retry,message:Se(e.message),since:e.since??c(),operation_id:V(e.operation_id),...typeof e.anchorEntryId=="string"&&e.anchorEntryId!==""?{anchorEntryId:e.anchorEntryId}:{},...e.providerError===void 0?{}:{providerError:e.providerError}}}o(q,"storedFault");function z(e,n){j({level:n.retry.disposition==="fatal"?"error":"warn",event:"fault.recorded",operation_id:n.operation_id,node_id:e,error_class:$(n),fields:{link:n.link,op:n.op,kind:n.kind,retry:n.retry,message:n.message,...n.anchorEntryId===void 0?{}:{anchor_entry_id:n.anchorEntryId},...n.providerError===void 0?{}:{provider_error:n.providerError}}})}o(z,"emitRecordedFault");function P(e,n,t,r,i){const d=F(),a=Q(t),u=c();return s(e,"INSERT INTO node_faults (fault_id, node_id, link, op, kind, message, since, operation_id, anchor_entry_id, retry_disposition, retry_by, retry_attempt, retry_max, retry_next_at, provider_error_json, active, episode_state, episode_binding_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").run(d,n,a.link,a.op,a.kind,a.message,a.since,a.operationId,a.anchorEntryId,a.retryDisposition,a.retryBy,a.retryAttempt,a.retryMax,a.retryNextAt,a.providerError,r?1:0,i?.state??null,i?.bindingId??null,u,u),{...t,faultId:d}}o(P,"insertFault");function Z(e,n,t,r){const i=Q(t);return s(e,"UPDATE node_faults SET link = ?, op = ?, kind = ?, message = ?, since = ?, operation_id = ?, anchor_entry_id = ?, retry_disposition = ?, retry_by = ?, retry_attempt = ?, retry_max = ?, retry_next_at = ?, provider_error_json = ?, episode_state = COALESCE(?, episode_state), episode_binding_id = COALESCE(?, episode_binding_id), updated_at = ? WHERE fault_id = ?").run(i.link,i.op,i.kind,i.message,i.since,i.operationId,i.anchorEntryId,i.retryDisposition,i.retryBy,i.retryAttempt,i.retryMax,i.retryNextAt,i.providerError,r?.state??null,r?.bindingId??null,c(),n),{...t,faultId:n}}o(Z,"updateFault");function D(e,n){s(e,"DELETE FROM node_faults WHERE fault_id = ? AND active = 0 AND episode_state IS NULL").run(n)}o(D,"deleteIfUnretained");function ee(e,n,t,r){const i=L(e,n);if(i===null){const d=s(e,"SELECT fault_id, link, kind, since, operation_id FROM node_faults WHERE node_id = ? AND active = 0 AND episode_state IS NOT NULL").get(n);return d!==void 0&&d.link===t.link&&d.kind===t.kind&&d.since===t.since&&d.operation_id===t.operation_id?(s(e,"UPDATE node_faults SET active = 1, updated_at = ? WHERE fault_id = ?").run(c(),d.fault_id),Z(e,d.fault_id,t)):P(e,n,t,!0,r)}if(i.link===t.link&&i.kind===t.kind){const d=t.retry.disposition==="auto"?{...i.retry,...t.retry}:t.retry,a=i.retry.disposition===t.retry.disposition&&(t.retry.disposition!=="fatal"||i.message===t.message),u=a?i.since:t.since,p=Z(e,i.faultId,{...t,since:u,anchorEntryId:i.anchorEntryId??t.anchorEntryId,retry:d},r);return a||s(e,"UPDATE node_faults SET notified_since = NULL WHERE fault_id = ?").run(i.faultId),p}return i.link!==t.link&&I(i)>I(t)?null:(s(e,"UPDATE node_faults SET active = 0, updated_at = ? WHERE fault_id = ?").run(c(),i.faultId),D(e,i.faultId),P(e,n,t,!0,r))}o(ee,"replaceActiveFault");function m(e,n,t){return s(e,"SELECT binding_id FROM sessions WHERE node_id = ? AND session_id = ? AND unbound_at IS NULL").get(n,t)?.binding_id??null}o(m,"liveBinding");function we(e,n){return l(t=>{const r=c();return s(t,"UPDATE executions SET turn_progress_at = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(r,e).changes>0?!0:s(t,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = NULL, turn_end_reason = NULL WHERE execution_id = ? AND state != 'exited'").run(r,r,e).changes>0})}o(we,"openTurn");function Xe(e){return l(n=>s(n,"UPDATE executions SET turn_progress_at = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(c(),e).changes>0)}o(Xe,"recordTurnProgress");function $e(e,n){return l(t=>{const r=c(),i=s(t,"UPDATE executions SET turn_closed_at = ?, turn_end_reason = ? WHERE execution_id = ? AND state != 'exited' AND turn_open_at IS NOT NULL AND turn_closed_at IS NULL").run(r,n.endReason,e).changes>0;if(i&&n.endReason==="settled"){const d="(SELECT node_id FROM executions WHERE execution_id = ?)";n.viewerPresent===!0?s(t,`UPDATE nodes SET reply_at = ?, read_at = ? WHERE node_id = ${d}`).run(r,r,e):s(t,`UPDATE nodes SET reply_at = ? WHERE node_id = ${d}`).run(r,e)}return i})}o($e,"closeTurn");function je(e){return l(n=>s(n,"UPDATE nodes SET read_at = ? WHERE node_id = ?").run(c(),e).changes>0)}o(je,"markNodeRead");function Be(e,n){if(!Number.isInteger(n.consecutivePasses)||n.consecutivePasses<1||n.routes.length===0||!n.routes.every(t=>t!==""))throw new Error("invalid transport-poison verdict");return l(t=>s(t,"UPDATE executions SET exit_diagnostic_json = ? WHERE execution_id = ? AND state != 'exited'").run(JSON.stringify({schema:"crtr.execution-exit-diagnostic/v1",transport_poison:{consecutive_passes:n.consecutivePasses,routes:n.routes}}),e).changes>0)}o(Be,"recordTransportPoisonVerdict");function Je(e){const n=s(E(),"SELECT exit_diagnostic_json FROM executions WHERE node_id = ? ORDER BY rowid DESC LIMIT 1").get(e);if(n===void 0||n.exit_diagnostic_json===null)return null;try{const t=JSON.parse(n.exit_diagnostic_json),r=t.transport_poison;return t.schema!=="crtr.execution-exit-diagnostic/v1"||r===void 0||!Number.isInteger(r.consecutive_passes)||r.consecutive_passes<1||!Array.isArray(r.routes)||r.routes.length===0||!r.routes.every(i=>typeof i=="string"&&i!=="")?null:{consecutivePasses:r.consecutive_passes,routes:r.routes}}catch{return null}}o(Je,"readTransportPoisonVerdict");function Ke(e){const n=s(E(),"SELECT turn_open_at, turn_closed_at, turn_progress_at FROM executions WHERE node_id = ? AND state != 'exited'").get(e);return n===void 0?null:{busy:n.turn_open_at!==null&&n.turn_closed_at===null,progressAt:n.turn_progress_at}}o(Ke,"readLiveTurn");function Ye(e){const n=E(),t=s(n,"SELECT turn_closed_at, turn_progress_at FROM executions WHERE node_id = ? AND turn_open_at IS NOT NULL ORDER BY rowid DESC LIMIT 1").get(e);if(t===void 0)return null;const r=s(n,"SELECT turn_end_reason FROM executions WHERE node_id = ? ORDER BY rowid DESC LIMIT 1").get(e);return{interrupted:t.turn_closed_at===null||r?.turn_end_reason==="teardown-aborted",progressAt:t.turn_progress_at}}o(Ye,"readInterruptedTurn");function Ge(e){return s(E(),"SELECT 1 FROM executions WHERE node_id = ? AND turn_open_at IS NOT NULL LIMIT 1").get(e)!==void 0}o(Ge,"hasAdmittedTurn");function Ve(e,n){const t=q(n);return z(e,t),l(r=>ee(r,e,t))}o(Ve,"recordFault");function Qe(e){return l(n=>s(n,"UPDATE node_faults SET notified_since = since, updated_at = ? WHERE fault_id = ?").run(c(),e).changes>0)}o(Qe,"markFaultNotified");function xe(e){return e.link==="pi\u2192provider"&&e.retry.disposition==="fatal"&&e.notifiedSince!==e.since}o(xe,"isUnnotifiedFatalProviderFault");function qe(){return s(E(),"SELECT f.node_id FROM node_faults f JOIN nodes n ON n.node_id = f.node_id WHERE f.active = 1 AND f.link = 'pi\u2192provider' AND f.retry_disposition = 'fatal' AND (f.notified_since IS NULL OR f.notified_since != f.since) AND n.status IN ('active', 'idle')").all().map(e=>e.node_id)}o(qe,"listUnnotifiedFatalFaultNodes");let M=null;function ze(e){M=e}o(ze,"setFatalFaultAnnouncer");function Ze(e,n){const t=L(E(),e);return t===null||n?.link!==void 0&&t.link!==n.link?!1:l(r=>{const i=L(r,e);if(i===null||n?.link!==void 0&&i.link!==n.link)return!1;M!==null&&xe(i)&&M(e);const d=s(r,"SELECT episode_state FROM node_faults WHERE fault_id = ?").get(i.faultId);s(r,"UPDATE node_faults SET active = 0, updated_at = ? WHERE fault_id = ?").run(c(),i.faultId),d.episode_state==="pending"&&n?.preserveEpisode!==!0&&s(r,"UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE fault_id = ?").run(c(),i.faultId),D(r,i.faultId);const a=V();return j({level:"info",event:"fault.cleared",operation_id:a,node_id:e,error_class:$(i),fields:{cleared_fault_operation_id:i.operation_id,link:i.link,op:i.op,kind:i.kind,retry:i.retry,message:i.message,since:i.since,...i.anchorEntryId===void 0?{}:{anchor_entry_id:i.anchorEntryId}}}),!0})}o(Ze,"clearFault");function ne(e){return L(E(),e)}o(ne,"readFault");function en(e,n){const t=q(n.input);if(t.link!=="pi\u2192provider"||t.retry.disposition!=="auto"||t.retry.by!=="daemon")throw new Error("provider retry episode requires an automatic daemon provider fault");return z(e,t),l(r=>{const i=m(r,e,n.sessionId);if(i===null)return null;const d=L(r,e);if(d!==null&&(d.link!==t.link||d.kind!==t.kind)&&I(d)>I(t))return null;const a=s(r,"SELECT fault_id FROM node_faults WHERE node_id = ? AND episode_state IS NOT NULL").all(e);s(r,"UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE node_id = ? AND episode_state IS NOT NULL").run(c(),e);for(const p of a)D(r,p.fault_id);const u=ee(r,e,t,{state:"pending",bindingId:i});return u===null?null:(s(r,"UPDATE node_faults SET episode_state = ?, episode_binding_id = ?, updated_at = ? WHERE fault_id = ?").run("pending",i,c(),u.faultId),u)})}o(en,"recordPendingEpisode");function nn(e,n){return l(t=>{if(s(t,"SELECT 1 FROM nodes WHERE node_id = ? AND intent IS 'refresh'").get(e)!==void 0)return!1;const r=m(t,e,n.sessionId);return r===null?!1:s(t,"UPDATE node_faults SET episode_state = 'admitted', retry_disposition = ?, retry_by = ?, retry_attempt = ?, retry_max = ?, retry_next_at = ?, updated_at = ? WHERE node_id = ? AND fault_id = ? AND episode_state = 'pending' AND episode_binding_id = ?").run(n.retry.disposition,n.retry.by??null,n.retry.attempt??null,n.retry.max??null,n.retry.nextAt??null,c(),e,n.faultId,r).changes>0})}o(nn,"admitEpisode");function tn(e,n){return l(t=>{const r=m(t,e,n.sessionId);return r===null?!1:s(t,"UPDATE node_faults SET episode_state = 'pending', updated_at = ? WHERE node_id = ? AND episode_state = 'admitted' AND episode_binding_id = ?").run(c(),e,r).changes>0})}o(tn,"reopenEpisode");function rn(e,n){return l(t=>{const r=m(t,e,n.sessionId);return r===null?!1:s(t,"UPDATE node_faults SET episode_state = 'invalidated', updated_at = ? WHERE node_id = ? AND episode_state != 'invalidated' AND episode_state IS NOT NULL AND episode_binding_id = ?").run(c(),e,r).changes>0})}o(rn,"invalidateEpisode");function on(e,n){return l(t=>{const r=m(t,e,n.sessionId);if(r===null)return!1;const i=s(t,"SELECT fault_id FROM node_faults WHERE node_id = ? AND episode_binding_id = ? AND episode_state IS NOT NULL").all(e,r);if(i.length===0)return!1;s(t,"UPDATE node_faults SET episode_state = NULL, episode_binding_id = NULL, updated_at = ? WHERE node_id = ? AND episode_binding_id = ? AND episode_state IS NOT NULL").run(c(),e,r);for(const d of i)D(t,d.fault_id);return!0})}o(on,"clearEpisode");function sn(e){const n=s(E(),"SELECT f.*, s.session_id FROM node_faults f JOIN sessions s ON s.binding_id = f.episode_binding_id WHERE f.node_id = ? AND f.episode_state IS NOT NULL").get(e);return n===void 0?null:{state:n.episode_state,sessionId:n.session_id,fault:W(n)}}o(sn,"readEpisode");function dn(){return s(E(),"SELECT f.*, s.session_id AS bound_session_id FROM node_faults f JOIN sessions s ON s.binding_id = f.episode_binding_id WHERE f.active = 1 AND f.episode_state = 'pending' AND s.unbound_at IS NULL AND s.session_id IS NOT NULL AND f.link = 'pi\u2192provider' AND f.retry_disposition = 'auto' AND f.retry_by = 'daemon' AND f.kind IN ('connection', 'rate-limit', 'overloaded')").all().map(n=>({nodeId:n.node_id,sessionId:n.bound_session_id,fault:W(n),updatedAt:n.updated_at}))}o(dn,"listPendingProviderRetries");function an(e){const n=ne(e)===null;return{explanation(){if(!n)return null;const t=ne(e);if(t===null||t.link!=="crtr\u2192pi"||t.retry.disposition!=="fatal")return null;const r=t.op.trim(),i=t.message.trim();return r===""||i===""?null:`${r}: ${i}`}}}o(an,"beginBootFaultAttempt");function te(e,n){try{return ae(e).mtime.toISOString()}catch{return n}}o(te,"markerMtime");function w(e,n){if(!f(e))return null;try{return se(e,"utf8")}catch(t){if(!n)return null;throw new Error(`cannot import recovery input ${e}: ${t.message}`)}}o(w,"legacyFile");function Re(e,n){return s(e,"SELECT execution_id, started_at FROM executions WHERE node_id = ? ORDER BY rowid DESC LIMIT 1").get(n)??null}o(Re,"latestExecution");function Ie(e,n){const r=b(e,"nodes").has("launched_at")?s(e,"SELECT COALESCE(launched_at, created) AS started_at FROM nodes WHERE node_id = ?").get(n):s(e,"SELECT created AS started_at FROM nodes WHERE node_id = ?").get(n);if(r===void 0)throw new Error(`cannot import recovery witness for unknown node ${n}`);const i=F();return s(e,"INSERT INTO executions (execution_id, node_id, daemon_epoch, pid, process_identity, state, started_at, ended_at, exit_reason) VALUES (?, ?, NULL, NULL, NULL, 'exited', ?, ?, 'pre-consolidation')").run(i,n,r.started_at,r.started_at),{execution_id:i,started_at:r.started_at}}o(Ie,"syntheticExecution");function re(e,n,t,r,i){return P(e,n,t,r,i)}o(re,"insertMigratedFault");function De(e,n,t,r){const i=s(e,"SELECT binding_id, node_id FROM sessions WHERE transcript_path = ? AND unbound_at IS NULL").get(t);if(i!==void 0){if(i.node_id!==n)throw new Error(`cannot import provider retry ${r}: transcript is live-owned by ${i.node_id}`);return i.binding_id}const d=s(e,"SELECT binding_id FROM sessions WHERE node_id = ? AND transcript_path = ? ORDER BY rowid DESC LIMIT 1").get(n,t);if(d!==void 0)return d.binding_id;const a=s(e,"SELECT created FROM nodes WHERE node_id = ?").get(n);if(a===void 0)throw new Error(`cannot import provider retry ${r}: unknown node ${n}`);const u=F();return s(e,"INSERT INTO sessions (binding_id, session_id, node_id, transcript_path, source_session_id, fork_entry_id, created_at, bound_at, unbound_at) VALUES (?, NULL, ?, ?, NULL, NULL, ?, ?, ?)").run(u,n,t,a.created,a.created,c()),u}o(De,"migrationBinding");function un(e){e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'node_faults'").get()!==void 0&&(b(e,"node_faults").has("notified_since")||e.exec("ALTER TABLE node_faults ADD COLUMN notified_since TEXT"))}o(un,"addFaultNotifiedSince");function cn(e){if(ge(e),Le(e),!f(C()))return;const n=oe(C(),{withFileTypes:!0}).filter(r=>r.isDirectory()).sort((r,i)=>r.name.localeCompare(i.name)),t=s(e,"SELECT 1 FROM nodes WHERE node_id = ?");for(const r of n){const i=r.name,d=_e(i),a=N(d,"busy"),u=N(d,"clean-abort"),p=N(d,"transport-poison.json"),U=N(d,"fault"),A=N(d,"provider-retry"),O=f(a),h=f(u);if(!O&&!h&&!f(p)&&!f(U)&&!f(A)||!f(N(C(),i,"meta.json"))&&t.get(i)===void 0)continue;const k=w(p,!1),S=w(U,!0),x=w(A,!0);if(!O&&!h&&k===null&&S===null&&x===null)continue;let y=Re(e,i);if(y===null&&(y=Ie(e,i)),O){const _=te(a,y.started_at);s(e,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = NULL, turn_end_reason = NULL WHERE execution_id = ?").run(_,_,y.execution_id)}else if(h){const _=te(u,y.started_at);s(e,"UPDATE executions SET turn_open_at = ?, turn_progress_at = ?, turn_closed_at = ?, turn_end_reason = 'teardown-aborted' WHERE execution_id = ?").run(_,_,_,y.execution_id)}if(k!==null)try{const _=JSON.parse(k);Number.isInteger(_.consecutivePasses)&&_.consecutivePasses>=1&&Array.isArray(_.routes)&&_.routes.length>0&&_.routes.every(X=>typeof X=="string"&&X!=="")&&s(e,"UPDATE executions SET exit_diagnostic_json = ? WHERE execution_id = ?").run(JSON.stringify({schema:"crtr.execution-exit-diagnostic/v1",transport_poison:{consecutive_passes:_.consecutivePasses,routes:_.routes}}),y.execution_id)}catch{}const R=S===null?null:G(S);if(S!==null&&R===null)throw new Error(`cannot import recovery fault ${U}`);const T=x===null?null:Ae(x);if(x!==null&&T===null)throw new Error(`cannot import provider retry ${A}`);let v=R===null||R.link==="broker\u2194crtrd"?null:re(e,i,R,!0);if(T!==null){const _=De(e,i,T.sessionFile,A);v!==null&&v.since===T.fault.since?s(e,"UPDATE node_faults SET episode_state = ?, episode_binding_id = ?, updated_at = ? WHERE fault_id = ?").run(T.state,_,c(),v.faultId):re(e,i,T.fault,!1,{state:T.state,bindingId:_})}}}o(cn,"migrateRecoveryWitnesses");export{Me as FAULT_QUIET_MS,un as addFaultNotifiedSince,nn as admitEpisode,an as beginBootFaultAttempt,on as clearEpisode,Ze as clearFault,$e as closeTurn,Ge as hasAdmittedTurn,W as hydrateFault,rn as invalidateEpisode,dn as listPendingProviderRetries,qe as listUnnotifiedFatalFaultNodes,Qe as markFaultNotified,je as markNodeRead,cn as migrateRecoveryWitnesses,we as openTurn,Y as parseProviderError,sn as readEpisode,ne as readFault,Ye as readInterruptedTurn,Ke as readLiveTurn,Je as readTransportPoisonVerdict,Ve as recordFault,en as recordPendingEpisode,Be as recordTransportPoisonVerdict,Xe as recordTurnProgress,tn as reopenEpisode,ze as setFatalFaultAnnouncer};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function createStoreClient(address: string, token?: string):
|
|
1
|
+
import type { ConversationStoreClient } from './index.js';
|
|
2
|
+
export declare function createStoreClient(address: string, token?: string): ConversationStoreClient;
|
|
@@ -18,7 +18,10 @@ export interface ConversationWindow {
|
|
|
18
18
|
head: number;
|
|
19
19
|
tail: number;
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
/** The synchronous shape pi's `SessionManager` statics need (`patch.ts`). The broker's client
|
|
22
|
+
* (`client.ts`: an `Atomics.wait` worker, no db) implements it. It is declared apart from
|
|
23
|
+
* `ConversationStore` so a change to the daemon's store never changes pi's contract. */
|
|
24
|
+
export interface ConversationStoreClient {
|
|
22
25
|
create(nodeId: string, header: SessionHeader, entries: SessionEntry[], path?: string): string;
|
|
23
26
|
/** `dedupe` makes the append idempotent by entry id: an entry already in the file is skipped.
|
|
24
27
|
* A caller sets it when an earlier attempt failed ambiguously (the connection ended before a
|
|
@@ -38,7 +41,30 @@ export interface ConversationStore {
|
|
|
38
41
|
};
|
|
39
42
|
/** `read` without blocking the calling thread. Stores that read in-process may omit it;
|
|
40
43
|
* use `readConversationAsync`, which falls back to `read`. */
|
|
41
|
-
readAsync?(id: string, window?: ConversationWindow): Promise<ReturnType<
|
|
44
|
+
readAsync?(id: string, window?: ConversationWindow): Promise<ReturnType<ConversationStoreClient['read']>>;
|
|
45
|
+
header(id: string): {
|
|
46
|
+
header: SessionHeader;
|
|
47
|
+
mtime: number;
|
|
48
|
+
size: number;
|
|
49
|
+
path: string;
|
|
50
|
+
};
|
|
51
|
+
fork(id: string, nodeId?: string, leafId?: string, cwd?: string): string;
|
|
52
|
+
list(nodeId?: string): ConversationInfo[];
|
|
53
|
+
delete(id: string): void;
|
|
54
|
+
}
|
|
55
|
+
/** The daemon's file store (`createFileStore`, installed by `sessions.ts`). */
|
|
56
|
+
export interface ConversationStore {
|
|
57
|
+
create(nodeId: string, header: SessionHeader, entries: SessionEntry[], path?: string): string;
|
|
58
|
+
append(id: string, entries: SessionEntry[], options?: {
|
|
59
|
+
dedupe?: boolean;
|
|
60
|
+
}): void;
|
|
61
|
+
replace(id: string, header: SessionHeader, entries: SessionEntry[]): void;
|
|
62
|
+
read(id: string, window?: ConversationWindow): {
|
|
63
|
+
header: SessionHeader;
|
|
64
|
+
entries: SessionEntry[];
|
|
65
|
+
tail?: SessionEntry[];
|
|
66
|
+
path: string;
|
|
67
|
+
};
|
|
42
68
|
/** Stream a complete conversation without blocking the daemon on a full-file read. */
|
|
43
69
|
readLines?(id: string): {
|
|
44
70
|
path: string;
|
|
@@ -59,6 +85,8 @@ export declare function defaultConversationRoot(): string;
|
|
|
59
85
|
export declare function storeAddress(): string;
|
|
60
86
|
export declare function installConversationStore(store: ConversationStore | undefined): void;
|
|
61
87
|
export declare function conversationStore(): ConversationStore;
|
|
88
|
+
/** The synchronous store pi's `SessionManager` statics call: the installed store, else the client over the store socket. */
|
|
89
|
+
export declare function conversationClient(): ConversationStoreClient;
|
|
62
90
|
/** Read a conversation without parking the event loop on the store worker. */
|
|
63
91
|
export declare function readConversationAsync(id: string, window?: ConversationWindow): Promise<ReturnType<ConversationStore['read']>>;
|
|
64
92
|
export { createFileStore, sessionDirectory, type AppendSection, type ConversationCanvas, type ConversationWrite } from './file-store.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var a=Object.defineProperty;var r=(o,
|
|
1
|
+
var a=Object.defineProperty;var r=(o,t)=>a(o,"name",{value:t,configurable:!0});import{appsRoot as c,socketDir as u}from"../layout.js";import{join as f}from"node:path";import{createStoreClient as p}from"./client.js";import{currentNodeToken as d}from"../runtime/broker/node-token.js";class l extends Error{static{r(this,"ConversationNotFoundError")}code="not_found";constructor(t){super(`conversation not found: ${t}`)}}function R(o){return o instanceof l}r(R,"isConversationNotFound");function y(o){return/(?:^|\/)[^/]+_([0-9a-f-]{36})\.jsonl$/i.exec(o)?.[1]??null}r(y,"conversationIdFromPath");function A(){return c()}r(A,"defaultConversationRoot");function m(){return process.env.CRTR_STORE_ADDRESS||f(u(),"store.sock")}r(m,"storeAddress");let n,s;function F(o){n=o}r(F,"installConversationStore");function k(){return i()}r(k,"conversationStore");function i(){if(n)return n;const o=m();return s?.address!==o&&(s={address:o,store:p(o,d())}),s.store}r(i,"conversationClient");async function D(o,t){const e=i();return e.readAsync?e.readAsync(o,t):e.read(o,t)}r(D,"readConversationAsync");import{createFileStore as _,sessionDirectory as N}from"./file-store.js";import{installSessionManagerStorePatch as T}from"./patch.js";import{findOrphanedParents as $,relinkOrphanedParents as g,repairConversationFile as I}from"./repair.js";export{l as ConversationNotFoundError,i as conversationClient,y as conversationIdFromPath,k as conversationStore,_ as createFileStore,A as defaultConversationRoot,$ as findOrphanedParents,F as installConversationStore,T as installSessionManagerStorePatch,R as isConversationNotFound,D as readConversationAsync,g as relinkOrphanedParents,I as repairConversationFile,N as sessionDirectory,m as storeAddress};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var P=Object.defineProperty;var h=(a,c)=>P(a,"name",{value:c,configurable:!0});import{dirname as E,resolve as A}from"node:path";import{SessionManager as w}from"@earendil-works/pi-coding-agent";import{
|
|
1
|
+
var P=Object.defineProperty;var h=(a,c)=>P(a,"name",{value:c,configurable:!0});import{dirname as E,resolve as A}from"node:path";import{SessionManager as w}from"@earendil-works/pi-coding-agent";import{conversationClient as R,conversationIdFromPath as O}from"./index.js";import{findOrphanedParents as T}from"./repair.js";import{emitEvent as I}from"../events/emit.js";const f=new WeakMap;function k(a){a>0&&Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,a)}h(k,"sleep");function C(){const a=Number(process.env.CRTR_CONVERSATION_APPEND_RETRY_MS);return Number.isFinite(a)&&a>=0?a:500}h(C,"retryDelayMs");let x=!1;function z(a){if(x)return;const c=w.prototype,d=w;for(const e of["_setSessionFile","_rewriteFile","_persist","createBranchedSession","newSession"])if(typeof c[e]!="function")throw new Error(`pi SessionManager.${e} changed; store patch cannot start`);for(const e of["create","open","continueRecent","forkFrom","findById","list","listAll"])if(typeof d[e]!="function")throw new Error(`pi SessionManager.${e} changed; store patch cannot start`);const M=c.createBranchedSession,y=c.newSession,o=R();function N(e,s){const t=T(s);t.length!==0&&I({level:"error",event:"conversation.orphaned_parent",fields:{conversation_id:e,orphan_count:t.length,orphans:t.slice(0,20).map(i=>({entry_id:i.entryId,missing_parent_id:i.missingParentId}))}})}h(N,"reportOrphans");function _(e,s){const{header:t,entries:i,path:r}=o.read(e);N(t.id,i);const n=w.inMemory(s??t.cwd);n.sessionFile=r,n.sessionDir=E(r),n._loadEntries([t,...i]),n.persist=!0,n.flushed=!0;const u=n.fileEntries[0];return u?.type==="session"&&u.version!==t.version&&n._rewriteFile(),n}h(_,"fromStore");function m(e){const[s,...t]=e.fileEntries;if(!s||s.type!=="session")throw new Error("conversation has no session header");o.create(a,s,t),e.sessionFile=o.header(s.id).path,e.sessionDir=E(e.sessionFile),e.flushed=!0,f.delete(e)}h(m,"persistNew");function B(e,s){const t=f.get(e)??{entries:[],ambiguous:!1};t.entries.push(s),f.set(e,t);let i;for(let r=0;r<2;r++){r>0&&k(C());try{o.append(e.sessionId,t.entries,t.ambiguous?{dedupe:!0}:void 0),f.delete(e);return}catch(n){i=n,t.ambiguous=!0}}throw I({level:"error",event:"conversation.append_failed",error:i,fields:{conversation_id:e.sessionId,pending_entries:t.entries.length}}),i}h(B,"appendInOrder");function g(e){const s=O(e);if(!s)throw new Error(`invalid conversation path: ${e}`);return s}h(g,"idOf"),c._setSessionFile=function(e){const{header:s,entries:t}=o.read(g(e));this.sessionFile=o.header(s.id).path,this.sessionDir=E(this.sessionFile),N(s.id,t),this._loadEntries([s,...t]),this.flushed=!0,f.delete(this)},c._rewriteFile=function(){if(!this.persist||!this.sessionFile)return;const[e,...s]=this.fileEntries;if(!e||e.type!=="session")throw new Error("conversation has no session header");o.replace(e.id,e,s),f.delete(this)},c._persist=function(e){!this.persist||!this.sessionFile||(this.flushed?B(this,e):m(this))},c.newSession=function(e){if(!this.persist)return y.call(this,e);const s=this.flushed&&this.fileEntries.length===1&&this.sessionFile!==void 0?this.sessionId:void 0;if(s!==void 0&&(e?.id===void 0||e.id===s)){const t=this.sessionFile;y.call(this,{...e,id:s});const i=this.fileEntries[0];if(!i||i.type!=="session")throw new Error("conversation has no session header");return o.replace(s,i,[]),this.sessionFile=t,this.flushed=!0,t}return y.call(this,e),m(this),this.sessionFile},c.createBranchedSession=function(e){if(!this.persist)return M.call(this,e);const s=this.sessionFile;this.persist=!1;try{M.call(this,e)}finally{this.persist=!0}const t=this.fileEntries[0];if(!t||t.type!=="session")throw new Error("branch has no header");return this.fileEntries[0]={...t,parentSession:s},m(this),this.sessionFile},d.create=(e,s,t)=>{const i=w.inMemory(e,t);return i.persist=!0,m(i),i},d.open=(e,s,t)=>_(g(e),t),d.continueRecent=e=>{const s=o.list().find(t=>t.header.cwd===A(e));return s?_(s.conversation_id,e):d.create(e)},d.forkFrom=(e,s)=>_(o.fork(g(e),a,void 0,s)),d.findById=(e,s)=>o.list().find(t=>t.conversation_id===s&&t.header.cwd===A(e))?.path;function b(e){return o.list().filter(s=>e===void 0||s.header.cwd===A(e)).map(s=>{let t,i=0,r="",n;const u=[];for(const p of o.read(s.conversation_id).entries){if(p.type==="session_info"&&(t=p.name?.trim()||void 0),p.type!=="message")continue;i++;const l=p.message;if(l.role!=="user"&&l.role!=="assistant")continue;const D=typeof l.timestamp=="number"?l.timestamp:Date.parse(p.timestamp);Number.isNaN(D)||(n=Math.max(n??0,D));const F=typeof l.content=="string"?l.content:Array.isArray(l.content)?l.content.filter(S=>S.type==="text").map(S=>S.text??"").join(" "):"";F&&(u.push(F),!r&&l.role==="user"&&(r=F))}const v=new Date(s.header.timestamp);return{path:s.path,id:s.conversation_id,cwd:s.header.cwd,...t?{name:t}:{},...s.header.parentSession?{parentSessionPath:s.header.parentSession}:{},created:v,modified:n&&n>0?new Date(n):Number.isNaN(v.getTime())?new Date(s.mtime):v,messageCount:i,firstMessage:r||"(no messages)",allMessagesText:u.join(" ")}})}h(b,"sessionInfos"),d.list=async(e,s,t,i)=>{i?.throwIfAborted();const r=b(e);return t?.(r.length,r.length,r),r},d.listAll=async(...e)=>(e.find(t=>t instanceof AbortSignal)?.throwIfAborted(),b()),x=!0}h(z,"installSessionManagerStorePatch");export{z as installSessionManagerStorePatch};
|
|
@@ -55,6 +55,8 @@ export declare function endMessageSubscriptions(db: DatabaseSync, object: Object
|
|
|
55
55
|
export declare function watchesOf(db: DatabaseSync, reader: Reader, watcher: ObjectRow): Watch[];
|
|
56
56
|
/** The watches held on `object` that the reader may see (both ends readable). */
|
|
57
57
|
export declare function watchersOf(db: DatabaseSync, reader: Reader, object: ObjectRow): Watch[];
|
|
58
|
+
/** The ids of every object that watches `object`, whatever started the watch. */
|
|
59
|
+
export declare function watcherIdsOf(db: DatabaseSync, object: ObjectRow): string[];
|
|
58
60
|
/** Every node below `root` in the tree (in-tree watches, watcher → object), each once. */
|
|
59
61
|
export declare function descendants(db: DatabaseSync, root: ObjectRow): ObjectRow[];
|
|
60
62
|
/** Every node above `leaf` in the tree (in-tree watches, object → watcher), each once. */
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
var D=Object.defineProperty;var c=(e,t)=>D(e,"name",{value:t,configurable:!0});import{prepared as i}from"../sqlite-statements.js";import{canRead as
|
|
1
|
+
var D=Object.defineProperty;var c=(e,t)=>D(e,"name",{value:t,configurable:!0});import{prepared as i}from"../sqlite-statements.js";import{canRead as p}from"./access.js";import{receiverForObject as j}from"./receivers.js";import{getByRowid as S}from"./objects.js";const O=["spawn","job-start","ask"],y=["report.final","report.result","notice.>"];function N(e){return JSON.stringify(Object.fromEntries(e.map(t=>[String(t.threshold),t.delivery])))}c(N,"configToJson");function I(e){const t=JSON.parse(e);return Object.entries(t).map(([r,o])=>({threshold:Number(r),delivery:o})).sort((r,o)=>o.threshold-r.threshold)}c(I,"configFromJson");function h(e,t,r){return i(e,"SELECT * FROM watches WHERE watcher = ? AND object = ?").get(t.rowid,r.rowid)}c(h,"watchRow");function d(e,t){return i(e,"SELECT * FROM watch_subscriptions WHERE watch = ? ORDER BY rowid").all(t)}c(d,"subsOf");function _(e,t){const r=d(e,t);if(r.length===0){i(e,"DELETE FROM watches WHERE rowid = ?").run(t);return}const o=r.some(n=>O.includes(n.started_by))?1:0;i(e,"UPDATE watches SET in_tree = ? WHERE rowid = ? AND in_tree != ?").run(o,t,o)}c(_,"settle");function C(e,t){return e==="message"?y:t.patterns?.length?t.patterns:[">"]}c(C,"defaultPatterns");function F(e,t,r,o,n={}){if(o==="fork")throw new Error("recordWatch: fork watches are made by copyWatchesForFork");if(t.type.includes(".")&&!j(e,t))throw new Error(`custom object ${t.id} has no receiver`);const a=new Date().toISOString();i(e,`INSERT INTO watches (watcher, object, in_tree, read_heads_key, created_at, link_app) VALUES (?, ?, 0, ?, ?, ?)
|
|
2
2
|
ON CONFLICT (watcher, object) DO UPDATE SET read_heads_key = COALESCE(excluded.read_heads_key, read_heads_key),
|
|
3
|
-
link_app = COALESCE(excluded.link_app, link_app)`).run(t.rowid,
|
|
4
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)`);for(const R of
|
|
3
|
+
link_app = COALESCE(excluded.link_app, link_app)`).run(t.rowid,r.rowid,n.readHeadsKey??null,a,n.linkApp?.rowid??null);const s=h(e,t,r),E=o==="message"?n.endsOn??"final":null,f=O.includes(o),w=d(e,s.rowid),u=i(e,`INSERT INTO watch_subscriptions (watch, pattern, filter_json, config_json, started_by, ends_on, created_at)
|
|
4
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`);for(const R of C(o,n))w.some(l=>l.pattern===R&&(l.ends_on===null||l.ends_on===E)&&(!f||O.includes(l.started_by)))||u.run(s.rowid,R,n.filter===void 0?null:JSON.stringify(n.filter),n.config?N(n.config):null,o,E,a);_(e,s.rowid)}c(F,"recordWatch");function H(e,t,r,o){i(e,"UPDATE watches SET link_app = ? WHERE watcher = ? AND object = ?").run(o.rowid,t.rowid,r.rowid)}c(H,"markLinkWatch");function M(e,t,r,o){const n=h(e,t,r);n&&(o===void 0?i(e,"DELETE FROM watch_subscriptions WHERE watch = ?").run(n.rowid):typeof o=="string"?i(e,"DELETE FROM watch_subscriptions WHERE watch = ? AND pattern = ?").run(n.rowid,o):i(e,"DELETE FROM watch_subscriptions WHERE watch = ? AND started_by = ?").run(n.rowid,o.startedBy),_(e,n.rowid))}c(M,"unwatch");function x(e,t,r,o,n){const a=h(e,t,r),s=a?i(e,"UPDATE watch_subscriptions SET config_json = ? WHERE watch = ? AND pattern = ?").run(n?N(n):null,a.rowid,o).changes:0;if(Number(s)===0)throw new Error(`${t.id} has no subscription ${o} on ${r.id}`)}c(x,"setSubscriptionConfig");function U(e,t,r){const o=typeof r=="string"?i(e,`DELETE FROM watch_subscriptions WHERE started_by = 'message'
|
|
5
5
|
AND watch IN (SELECT rowid FROM watches WHERE object = ?) RETURNING watch`).all(t.rowid):i(e,`DELETE FROM watch_subscriptions WHERE started_by = 'message' AND ends_on = ?
|
|
6
|
-
AND watch IN (SELECT rowid FROM watches WHERE object = ?) RETURNING watch`).all(`result:${
|
|
6
|
+
AND watch IN (SELECT rowid FROM watches WHERE object = ?) RETURNING watch`).all(`result:${r.result}`,t.rowid);for(const n of new Set(o.map(a=>a.watch)))_(e,n)}c(U,"endMessageSubscriptions");function g(e,t){const r=S(e,t.watcher),o=S(e,t.object);return!r||!o?null:{rowid:t.rowid,watcher:r,object:o,in_tree:t.in_tree===1,read_heads_key:t.read_heads_key,created_at:t.created_at,subscriptions:d(e,t.rowid).map(n=>({rowid:n.rowid,pattern:n.pattern,started_by:n.started_by,ends_on:n.ends_on,created_at:n.created_at,filter:n.filter_json===null?null:JSON.parse(n.filter_json),config:n.config_json===null?null:I(n.config_json)}))}}c(g,"hydrate");function T(e,t,r){return r.map(o=>g(e,o)).filter(o=>o!==null&&p(e,t,o.watcher)&&p(e,t,o.object))}c(T,"visible");function J(e,t,r){return T(e,t,i(e,"SELECT * FROM watches WHERE watcher = ? ORDER BY rowid").all(r.rowid))}c(J,"watchesOf");function B(e,t,r){return T(e,t,i(e,"SELECT * FROM watches WHERE object = ? ORDER BY rowid").all(r.rowid))}c(B,"watchersOf");function Y(e,t){return i(e,"SELECT o.id FROM watches w JOIN objects o ON o.rowid = w.watcher WHERE w.object = ? ORDER BY w.rowid").all(t.rowid).map(r=>r.id)}c(Y,"watcherIdsOf");function v(e,t){return i(e,`WITH RECURSIVE walk(rowid) AS (
|
|
7
7
|
SELECT ?
|
|
8
8
|
UNION
|
|
9
9
|
SELECT w.object FROM walk CROSS JOIN watches w INDEXED BY watches_tree_down ON w.watcher = walk.rowid AND w.in_tree = 1
|
|
10
10
|
) SELECT o.* FROM walk CROSS JOIN objects o ON o.rowid = walk.rowid
|
|
11
|
-
WHERE o.type = 'node' AND o.rowid != ?`).all(t.rowid,t.rowid)}c(v,"descendants");function
|
|
11
|
+
WHERE o.type = 'node' AND o.rowid != ?`).all(t.rowid,t.rowid)}c(v,"descendants");function P(e,t){return i(e,`WITH RECURSIVE walk(rowid) AS (
|
|
12
12
|
SELECT ?
|
|
13
13
|
UNION
|
|
14
14
|
SELECT w.watcher FROM walk CROSS JOIN watches w INDEXED BY watches_tree_up ON w.object = walk.rowid AND w.in_tree = 1
|
|
15
15
|
) SELECT o.* FROM walk CROSS JOIN objects o ON o.rowid = walk.rowid
|
|
16
|
-
WHERE o.type = 'node' AND o.rowid != ?`).all(t.rowid,t.rowid)}c(
|
|
17
|
-
WHERE w.object = ? AND w.in_tree = 1 ORDER BY w.rowid`).all(t.rowid)}c(
|
|
18
|
-
VALUES (?, ?, ?, ?, 'fork', ?, ?)`);for(const s of n){if(s.object===
|
|
19
|
-
ON CONFLICT (watcher, object) DO NOTHING`).run(
|
|
16
|
+
WHERE o.type = 'node' AND o.rowid != ?`).all(t.rowid,t.rowid)}c(P,"ancestors");function V(e,t){return i(e,`SELECT o.* FROM watches w INDEXED BY watches_tree_up CROSS JOIN objects o ON o.rowid = w.watcher
|
|
17
|
+
WHERE w.object = ? AND w.in_tree = 1 ORDER BY w.rowid`).all(t.rowid)}c(V,"treeWatchersOf");function $(e,t,r){const o=new Date().toISOString(),n=i(e,"SELECT * FROM watches WHERE watcher = ?").all(t.rowid),a=i(e,`INSERT INTO watch_subscriptions (watch, pattern, filter_json, config_json, started_by, ends_on, created_at)
|
|
18
|
+
VALUES (?, ?, ?, ?, 'fork', ?, ?)`);for(const s of n){if(s.object===r.rowid)continue;i(e,`INSERT INTO watches (watcher, object, in_tree, read_heads_key, created_at) VALUES (?, ?, 0, ?, ?)
|
|
19
|
+
ON CONFLICT (watcher, object) DO NOTHING`).run(r.rowid,s.object,s.read_heads_key,o);const E=h(e,r,{rowid:s.object}),f=d(e,E.rowid);for(const w of d(e,s.rowid))f.some(u=>u.pattern===w.pattern&&u.ends_on===w.ends_on)||a.run(E.rowid,w.pattern,w.filter_json,w.config_json,w.ends_on,o);_(e,E.rowid)}}c($,"copyWatchesForFork");export{P as ancestors,I as configFromJson,N as configToJson,$ as copyWatchesForFork,v as descendants,U as endMessageSubscriptions,H as markLinkWatch,F as recordWatch,x as setSubscriptionConfig,V as treeWatchersOf,M as unwatch,Y as watcherIdsOf,B as watchersOf,J as watchesOf};
|
package/dist/core/help.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
var
|
|
1
|
+
var N=Object.defineProperty;var u=(e,n)=>N(e,"name",{value:n,configurable:!0});import{outputBaseType as y}from"../api/command-manifest/schema.js";async function A(e,n,t){const o=u(async s=>{try{const i=await s();return()=>i}catch{return()=>null}},"read"),r=t===void 0?void 0:n.flags?.[t],a=new Map(r===void 0?[]:[[t,await o(r)]]);return{...e,...t===void 0&&n.leaf!==void 0?{dynamicState:await o(n.leaf)}:{},params:e.params?.map(s=>{const i=s.kind==="flag"?a.get(s.name):void 0;return s.kind==="flag"&&s.focusedHelp!==void 0&&i!==void 0?{...s,focusedHelp:{...s.focusedHelp,dynamicState:i}}:s})}}u(A,"withAsyncHelpState");function B(e,n,t){const o=Object.entries(n).map(([r,a])=>` ${r}="${a}"`).join("");return`<${e}${o}>
|
|
2
2
|
${t}
|
|
3
|
-
</${e}>`}u(
|
|
3
|
+
</${e}>`}u(B,"stateBlock");function h(e){if(e===void 0)return null;try{const n=e();return n!==null&&n!==""?n:null}catch{return null}}u(h,"evalDynamic");function $(e){let n=0;for(const t of e)t.length>n&&(n=t.length);return n}u($,"maxLen");function g(e,n){return e+" ".repeat(Math.max(0,n-e.length))}u(g,"pad");const I=`I/O contract: flags and positional args on input; stdout is agent-ready markdown/XML you
|
|
4
4
|
act on directly \u2014 read it as a continuation of your prompt, don't parse it as data.
|
|
5
|
-
Exit 0 on success, non-zero on failure. Schemas appear at leaf -h; a leaf may route an uncommon flag to focused --flag -h guidance.`,
|
|
6
|
-
`)}u(
|
|
7
|
-
`)}u(P,"renderBranch");function
|
|
8
|
-
`)}if(e.guide!==void 0&&(t.push(""),t.push(e.guide)),t.push(""),
|
|
9
|
-
`)}u(
|
|
5
|
+
Exit 0 on success, non-zero on failure. Schemas appear at leaf -h; a leaf may route an uncommon flag to focused --flag -h guidance.`,j="Before running a crtr command that changes state \u2014 creates, mutates, or deletes anything \u2014 whose exact contract (args, flags, effects) you haven't verified this session, run `-h` on it and read the schema first \u2014 a reliable read beats a guess that wastes a turn or triggers an unintended effect. When a leaf routes a flag to focused help, read that focused help before using the flag; the compact row is discovery, not its invocation contract. Same when the user names a capability you don't fully recognize: `-h` it before acting.";function C(e){const n=e.subcommands??[],t=e.otherSubcommandCount??0;if(n.length===0&&t===0)return[];const o=[];if(n.length>0){const r=$(n.map(a=>a.path));for(const a of n)o.push(a.desc!==void 0&&a.desc!==""?` ${g(a.path,r)} ${a.desc}`:` ${a.path}`)}if(t>0){const r=n.length>0?"other subcommand":"subcommand";o.push(` [+${t} ${r}${t===1?"":"s"} \u2014 \`crtr ${e.name} -h\`]`)}return o}u(C,"rootSubcommandLines");function R(e){const n=[];n.push(`${e.tagline}`),n.push("");for(const t of e.commands){n.push(`<command name="${t.name}">`),n.push(t.concept),n.push(`use when ${t.useWhen}`);for(const r of C(t))n.push(r);const o=h(t.dynamicState);o!==null&&n.push(o),n.push("</command>"),n.push("")}if(e.globals.length>0){n.push("Globals");const t=$(e.globals.map(o=>o.name));for(const o of e.globals)n.push(` ${g(o.name,t)} ${o.desc}`);n.push("")}return n.push(I),n.push(""),n.push(j),n.join(`
|
|
6
|
+
`)}u(R,"renderRoot");function d(e){return e.replace(/"/g,"'")}u(d,"attr");const v=40;function O(e){if(e.length<=v)return{listed:[...e],unlisted:0};const n=e.filter(t=>t.tier==="common"||t.tier==="important");return n.length===0?{listed:[...e],unlisted:0}:{listed:n,unlisted:e.length-n.length}}u(O,"collapseWideChildren");function D(e){const n=e.length>v;return e.filter(t=>(t.tier==="common"||t.tier==="important")&&(!n||t.kind==="leaf"))}u(D,"rootPromotedChildren");function P(e){const n=[];n.push(`<command name="${e.name}" description="${d(e.summary)}">`);const t=h(e.dynamicState);t!==null&&n.push(t),e.model!==void 0&&n.push(e.model);const{listed:o,unlisted:r}=O((e.listing??[]).filter(a=>a.tier!=="hidden"));for(const a of o){const s=a.plugin===void 0?"":` plugin="${d(a.plugin)}"`,i=a.subCount!==void 0&&a.subCount>0?` subcommands="${a.subCount}"`:"";n.length>1&&n.push(""),n.push(`<subcommand name="${a.name}" description="${d(a.description)}" whenToUse="${d(a.whenToUse)}"${s}${i}/>`)}return r>0&&(n.push(""),n.push(`<unlisted-subcommands count="${r}">${r} more subcommands are not listed here. Each one runs by name, and \`crtr ${e.name} <name> -h\` prints its help.</unlisted-subcommands>`)),e.extensionIssue!==void 0&&n.push(`<extension-issue fragment="${d(e.extensionIssue.fragment)}">This repository's contributed commands were rejected: ${e.extensionIssue.message}. Run \`crtr sys doctor\` for the full report.</extension-issue>`),n.push("</command>"),n.join(`
|
|
7
|
+
`)}u(P,"renderBranch");function T(e){if(e.kind==="positional")return`${e.name.toUpperCase()}${e.repeatable===!0?"...":""}`;if(e.kind==="stdin")return"stdin";if(e.kind==="context-file")return"--context-file PATH";const n=e;return n.type==="bool"?`--${n.name}`:`--${n.name} ${n.name.toUpperCase().replace(/-/g,"_")}`}u(T,"paramLabel");function w(e){return e===void 0?"":e==="base64"?" Local file path: the file is read and its raw bytes are base64-encoded into the request; the path itself is never sent.":" Local file path: the file is read as UTF-8 text and its content is sent as the value; the path itself is never sent."}u(w,"fileEncodingNote");function S(e){return e===void 0?"":` Defaults to $${e} when that is set and non-empty in the environment, and counts as supplied.`}u(S,"envDefaultNote");function k(e){return e==="file"?" A file: pass its path.":""}u(k,"fileParamNote");function H(e,n){return e.focusedHelp===void 0?"":` Before using this flag, run \`crtr ${n} --${e.name} -h\` and read its focused guidance.`}u(H,"focusedFlagHelpNote");function L(e,n){const t=e.required?"required":"optional";if(e.kind==="positional"){const c=e.repeatable===!0?" Repeatable \u2014 pass multiple values to accumulate in argv order.":"";return`positional, ${t}.${k(e.type)}${w(e.encoding)}${S(e.defaultFromEnv)} ${e.constraint}${c}`}if(e.kind==="stdin")return`${t}. ${e.constraint}`;if(e.kind==="context-file"){const c=e.shape!==void 0?` Shape: ${e.shape}`:"";return`${t}. Path to a JSON file.${c} ${e.constraint}`.trim()}const o=e,r=H(o,n);if(o.type==="bool")return`${t} boolean. Presence means true. ${o.constraint}${r}`.trim();const a=o.default!==void 0?` Default: ${String(o.default)}.`:"",s=o.type==="enum"&&o.choices!==void 0?` One of: ${o.choices.join(", ")}.`:"",i=o.repeatable===!0?" Repeatable \u2014 pass multiple times to accumulate.":"";return o.type==="json"?`json, ${t}. One JSON value: ${f(o.shape??{type:"unknown",constraint:""})}. ${o.constraint}${r}`.trim():`${o.type}, ${t}.${s}${a}${k(o.type)}${w(o.encoding)}${S(o.defaultFromEnv)} ${o.constraint}${i}${r}`.trim()}u(L,"paramDesc");function f(e){const n=/\|\s*null\s*$/i.test(e.type),t=y(e.type);return t==="union"&&e.variants!==void 0?`${e.variants.map(f).join(" | ")}${n?" | null":""}`:t==="map"&&e.items!==void 0?`{ [key: string]: ${f(e.items)} }${n?" | null":""}`:e.items===void 0?e.type:`array of ${f(e.items)}${n?", or null":""}`}u(f,"outputTypePhrase");function l(e){return e.values!==void 0?` One of: ${e.values.join(", ")}.`:""}u(l,"outputValuesNote");function b(e,n,t){const o=$(e.map(r=>r.name));for(const r of e){const a=r.constraint.length>0?` ${r.constraint}`:"";t.push(`${n}${g(r.name,o)} ${f(r)}.${l(r)}${a}`),p(r,`${n} `,t)}}u(b,"renderOutputFields");function x(e,n,t){const o=e.extra;o!==void 0&&(t.push(`${n}other members: ${f(o)}.${l(o)}${o.constraint.length>0?` ${o.constraint}`:""}`),p(o,`${n} `,t))}u(x,"renderExtraRow");function p(e,n,t){e.children!==void 0&&e.children.length>0&&b(e.children,n,t),x(e,n,t);for(const a of e.variants??[]){const s=l(a);t.push(`${n}variant: ${f(a)}.${s}${a.constraint.length>0?` ${a.constraint}`:""}`),p(a,`${n} `,t)}let o=e.items,r=y(e.type)==="map"?"each value":"each element";for(;o!==void 0;){const a=l(o);(o.constraint.length>0||a.length>0)&&t.push(`${n}${r}: ${f(o)}.${a}${o.constraint.length>0?` ${o.constraint}`:""}`);for(const s of o.variants??[])t.push(`${n}variant: ${f(s)}.${l(s)}${s.constraint.length>0?` ${s.constraint}`:""}`),p(s,`${n} `,t);if(o.children!==void 0&&o.children.length>0){b(o.children,n,t),x(o,n,t);return}if(o.extra!==void 0){x(o,n,t);return}r=y(o.type)==="map"?"each value":"each element",o=o.items}}u(p,"renderOutputShapeBody");function U(e,n){const t=[`${e.name}: ${e.summary}.`],o=(e.params??[]).filter(s=>!(s.kind==="flag"&&s.hidden===!0)),r=n===void 0?void 0:o.find(s=>s.kind==="flag"&&s.name===n&&s.focusedHelp!==void 0);if(r?.focusedHelp!==void 0){const s=r.focusedHelp;if(t.push(""),t.push(`<parameter name="${r.name}">`),t.push("When to use"),t.push(` ${s.whenToUse}`),t.push(""),t.push("Value"),t.push(` ${s.value}`),(s.effects??[]).length>0){t.push(""),t.push("Effects");for(const c of s.effects??[])t.push(` ${c}`)}const i=h(s.dynamicState);return i!==null&&(t.push(""),t.push(i)),t.push("</parameter>"),t.join(`
|
|
8
|
+
`)}if(e.guide!==void 0&&(t.push(""),t.push(e.guide)),t.push(""),o.length>0){t.push("Input");const s=o.map(T),i=$(s);for(let c=0;c<o.length;c++){t.push(` ${g(s[c],i)} ${L(o[c],e.name)}`);const m=o[c];m.kind==="flag"&&m.type==="json"&&m.shape!==void 0&&p(m.shape,` ${" ".repeat(i)} `,t)}}else t.push(e.inputNote!==void 0?e.inputNote:"No input parameters.");t.push(""),t.push("Output (fields carried in the rendered result)"),b(e.output," ",t),t.push(""),t.push("Effects");for(const s of e.effects)t.push(` ${s}`);const a=h(e.dynamicState);return a!==null&&(t.push(""),t.push(a)),t.join(`
|
|
9
|
+
`)}u(U,"renderLeafArgv");export{v as WIDE_BRANCH_LISTING_LIMIT,O as collapseWideChildren,P as renderBranch,U as renderLeafArgv,R as renderRoot,D as rootPromotedChildren,B as stateBlock,A as withAsyncHelpState};
|
package/dist/core/llm/run.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var be=Object.defineProperty;var u=(e,t)=>be(e,"name",{value:t,configurable:!0});import{randomUUID as ve}from"node:crypto";import{streamSimple as we}from"@earendil-works/pi-ai/compat";import{expandModelCandidates as ie,parseModelSpec as se,probeRouteAvailability as xe}from"../model-routes.js";import{readMergedLaunchConfig as ae}from"../config.js";import{openModelRegistry as ke}from"../runtime/model-registry.js";import{MAX_RATE_LIMIT_COOLDOWN_MS as de,coolingUntilFor as le,isManagedProvider as H,markSubscriptionRateLimited as je,markSubscriptionSuccess as Me,readSubscriptionPool as Ae,retryAfterMsFromHeaders as K,retryAfterMsFromError as qe,refreshSubscriptionCredential as $e,subscriptionNeedsSuccessWrite as Re}from"../subscription-state.js";import{classifyRateLimit as Ie,describeRateLimitScope as ce,rateLimitHeaders as Ce}from"../rate-limit-scope.js";import{RunError as i}from"../runs/operations.js";import{recognizeProviderError as Y}from"../provider-error-recognition.js";import{isSafetyRefusal as Se}from"./refusal.js";import{assertUnderCap as Oe,recordModelUsage as ue}from"../usage/ledger.js";import{outboundToken as Le}from"../providers/mint.js";import{discardFile as Ee}from"../providers/token-cache.js";import{ProviderError as Ne}from"../providers/errors.js";import{appCandidates as De}from"./app-rungs.js";function Fe(e){return typeof e=="string"||e===null||Array.isArray(e)&&e.every(t=>t&&typeof t=="object"&&(t.type==="text"&&typeof t.text=="string"||t.type==="image_url"&&typeof t.image_url?.url=="string"&&/^data:image\/(png|jpeg|gif|webp);base64,[A-Za-z0-9+/]+={0,2}$/.test(t.image_url.url)))}u(Fe,"validContent");function fe(e){return Array.isArray(e)?e.map(t=>{if(t.type==="text")return t;const[,n,r]=/^data:(image\/(?:png|jpeg|gif|webp));base64,(.*)$/.exec(t.image_url.url);return{type:"image",mimeType:n,data:r}}):e??""}u(fe,"imageContent");function Te(e,t){const n=(e instanceof Error?e.message:String(e)).split("; stack=",1)[0],r=Y({message:n}).kind;return r!=="connection"&&r!=="connection-only"?e:new i(503,"upstream_model_unavailable",n.slice(0,500),void 0,{served_model:t})}u(Te,"refreshFailure");function lt(e){if(!e||typeof e!="object"||Array.isArray(e))throw new i(400,"invalid_request","body must be an object");const t=e;if(!Array.isArray(t.messages)||!t.messages.every(n=>n&&typeof n=="object"&&["system","user","assistant","tool"].includes(n.role)&&Fe(n.content)))throw new i(400,"invalid_request","messages must be chat messages","messages");if(t.messages.some(n=>["system","assistant"].includes(n.role)&&typeof n.content!="string"&&n.content!==null))throw new i(400,"invalid_request","system and assistant content must be text","messages");if(t.model!==void 0&&typeof t.model!="string")throw new i(400,"invalid_request","model must be a string","model");if(t.model_policy!==void 0&&!["exact","substitute"].includes(t.model_policy))throw new i(400,"invalid_request","invalid model_policy","model_policy");if(t.payer!==void 0&&!["user","app"].includes(t.payer))throw new i(400,"invalid_request","invalid payer","payer");if(t.reasoning_effort!==void 0&&!["minimal","low","medium","high","xhigh","max"].includes(t.reasoning_effort))throw new i(400,"invalid_request","invalid reasoning_effort","reasoning_effort");if(t.stream!==void 0&&typeof t.stream!="boolean")throw new i(400,"invalid_request","stream must be boolean","stream");if(t.tools!==void 0&&(!Array.isArray(t.tools)||!t.tools.every(n=>n?.type==="function"&&typeof n.function?.name=="string"&&n.function.name.length>0&&(n.function.description===void 0||typeof n.function.description=="string")&&(n.function.parameters===void 0||n.function.parameters!==null&&typeof n.function.parameters=="object"&&!Array.isArray(n.function.parameters)&&n.function.parameters.type==="object"))))throw new i(400,"invalid_request","invalid tools","tools");if(t.tool_choice!==void 0&&t.tool_choice!=="auto"&&t.tool_choice!=="none"&&t.tool_choice!=="required"&&(typeof t.tool_choice!="object"||t.tool_choice===null||t.tool_choice.type!=="function"||typeof t.tool_choice.function?.name!="string"))throw new i(400,"invalid_request","invalid tool_choice","tool_choice");if(t.messages.some(n=>n.role==="assistant"&&n.tool_calls!==void 0&&(!Array.isArray(n.tool_calls)||!n.tool_calls.every(r=>r&&typeof r.id=="string"&&typeof r.function?.name=="string"&&typeof r.function.arguments=="string"&&Pe(r.function.arguments)))))throw new i(400,"invalid_request","invalid assistant tool_calls","messages");if(t.stop!==void 0&&!(typeof t.stop=="string"||Array.isArray(t.stop)&&t.stop.every(n=>typeof n=="string")))throw new i(400,"invalid_request","invalid stop","stop");if(t.seed!==void 0&&!Number.isSafeInteger(t.seed))throw new i(400,"invalid_request","invalid seed","seed");for(const[n,r]of[["temperature",t.temperature],["top_p",t.top_p],["max_tokens",t.max_tokens]])if(r!==void 0&&(typeof r!="number"||!Number.isFinite(r)||n==="temperature"&&(r<0||r>2)||n==="top_p"&&(r<0||r>1)||n==="max_tokens"&&(!Number.isSafeInteger(r)||r<1)))throw new i(400,"invalid_request",`invalid ${n}`,n);if(t.response_format!==void 0){const n=t.response_format;if(!n||typeof n!="object"||Array.isArray(n)||!["text","json_object","json_schema"].includes(n.type)||n.type==="json_schema"&&(typeof n.json_schema?.name!="string"||!n.json_schema.name||!n.json_schema.schema||typeof n.json_schema.schema!="object"||Array.isArray(n.json_schema.schema)))throw new i(400,"invalid_request","invalid response_format","response_format")}if(t.metadata!==void 0&&Buffer.byteLength(JSON.stringify(t.metadata)??"")>4096)throw new i(400,"invalid_request","metadata exceeds 4 KB","metadata");return t}u(lt,"parseLlmRequest");function Pe(e){try{const t=JSON.parse(e);return t!==null&&typeof t=="object"&&!Array.isArray(t)}catch{return!1}}u(Pe,"isJsonObject");function Ue(e){const t=Date.now(),n=e.messages.map(s=>s.role==="system"?{role:"system",content:s.content??"",timestamp:t}:s.role==="tool"?{role:"toolResult",toolCallId:s.tool_call_id??"",toolName:"",content:typeof s.content=="string"||s.content===null?[{type:"text",text:s.content??""}]:fe(s.content),isError:!1,timestamp:t}:s.role==="assistant"?{role:"assistant",content:[...s.content?[{type:"text",text:s.content}]:[],...(s.tool_calls??[]).map(g=>({type:"toolCall",id:g.id,name:g.function.name,arguments:JSON.parse(g.function.arguments)}))],api:"openai-completions",provider:"openai",model:e.model??"",usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"stop",timestamp:t}:{role:"user",content:fe(s.content),timestamp:t}),r=n.findIndex(s=>s.role!=="system"),w=n.slice(0,r<0?n.length:r).map(s=>s.content),y=w.join(`
|
|
2
2
|
|
|
3
|
-
`),l=e.tools?.map(({function:s})=>({name:s.name,description:s.description??"",parameters:s.parameters??{type:"object",properties:{}}}));return{...y?{systemPrompt:y}:{},messages:n.slice(w.length),...l?{tools:l}:{}}}u(Te,"contextOf");function me(e,t,n,r){if(!e){const y=se(n,r),l=Object.values({...y.modelRoutes??{},...y.legacyModelRoutes??{}}),s=l.length?[y.modelLadders.defaultProvider,...y.modelRouting?.familyOrder??[],...l.map(g=>g.family)].find(g=>l.some(E=>E.family===g)):y.modelLadders.defaultProvider??"anthropic";return{kind:"logical",family:s,strength:"strong",spec:`${s}/strong`}}const w=/^([^/]+)\/(ultra|strong|medium|light)$/.exec(e);return w?{kind:"logical",family:w[1],strength:w[2],spec:e}:{kind:t==="exact"?"exact":"concrete",spec:e}}u(me,"requestFor");function Pe(e,t){const{input:n,output:r,cacheRead:w,cacheWrite:y}=e.cost;return n===0&&r===0&&w===0&&y===0?null:Number.isFinite(t)&&t>=0?t:null}u(Pe,"usdEquivalent");function Ue(e,t){return e.compat?.allowedFallbackModels?.find(r=>r.provider===e.provider&&r.model===t)}u(Ue,"allowedFallback");function dt(e){return e?{payer:e.payer??"user",sub:e.sub,grantee:e.grantee,inference_endpoint:e.inference_endpoint??null}:void 0}u(dt,"llmCallerOf");function Je(e){return e instanceof Ee?e.code==="server_error"?new i(503,"upstream_model_unavailable",e.message):new i(404,"model_unavailable",e.message):e}u(Je,"mintFailure");const We=/\bmodel is not supported when using Codex with a ChatGPT account\b/i;function He(e,t,n){if(!(e!=="openai-codex"||t===void 0||!We.test(t)))return new i(404,"model_unavailable",t,void 0,{served_model:n})}u(He,"codexAccountModelRejection");async function lt(e,t,n,r,w,y){const l=y?.payer==="app"?y:void 0;if(e.payer==="app"&&!l)throw new i(403,"payer_not_app","this grant is not app-paid");if(e.payer==="user"&&l)throw new i(400,"invalid_request","this grant is app-paid; payer cannot be user","payer");if(l&&!l.inference_endpoint)throw new i(404,"model_unavailable",`${l.grantee} is app-paid but its grant carries no inference endpoint`);const s=l?.inference_endpoint??void 0;l||Oe(w);const g=await xe(),E=u(c=>c.routeId!=="concrete"&&c.routeId!=="exact","configured"),Y=u(c=>{const h=g.find(c.providerId,c.modelId);return h!==void 0&&(!e.reasoning_effort||h.reasoning)&&(e.seed===void 0&&e.response_format===void 0||h.api==="openai-completions")&&(e.stop===void 0||["openai-completions","anthropic-messages"].includes(h.api))},"matchesFeatures"),pe=u(()=>{const c=me(e.model,e.model_policy,r?.cwd,r?.profileId),h=re(c.kind==="exact"?{kind:"concrete",spec:c.spec}:c,r?.cwd,r?.profileId).filter(E);let a;if(c.kind==="logical")a=e.model_policy==="exact"?h.filter(m=>m.family===c.family&&m.strength===c.strength).slice(0,1):h;else{const m=ie(c.spec),q=h.filter(j=>j.providerId===m?.providerId&&j.modelId===m.modelId&&(e.model_policy!=="exact"||j.thinkingLevel===m.thinkingLevel)&&Y(j));if(e.model_policy==="exact")a=q.slice(0,1);else if(q.length)a=q;else{const j=se(r?.cwd,r?.profileId),x=[...Object.values(j.modelRoutes??{}).flatMap(v=>Object.entries(v.models)),...[j.modelLadders.anthropic,j.modelLadders.openai].flatMap(v=>Object.entries(v))].find(([,v])=>v===c.spec)?.[0],f=me(void 0,"substitute",r?.cwd,r?.profileId);a=x&&f.kind==="logical"?re({...f,strength:x,spec:c.spec},r?.cwd,r?.profileId).filter(v=>E(v)&&v.strength===x):[]}}return a},"ownerCandidates");let $;if(s?$=Ne(s,e.model,e.model_policy==="exact").flatMap((c,h)=>{const a=ie(c.model);return a?[{routeId:"app",credentialSource:"app",family:"app",strength:c.strength,...a,rank:h}]:[]}):$=pe(),$=$.filter(Y),$.length===0)throw e.model_policy==="exact"?new i(400,"substitution_refused","no eligible model route is configured"):new i(404,"model_unavailable","no eligible model route is configured");const ee=`chatcmpl-${be()}`;let I=1/0,b,z;for(const c of $){if(!l&&!we(c,g).authenticated)continue;const h=g.find(c.providerId,c.modelId);if(!h)continue;const a=s?{...h,baseUrl:`${s.base_url}/${h.provider}`}:h,m=c.providerId,q=!l&&H(m)?Me(m).filter(x=>!x.authFailure):[],j=q.filter(x=>de(x,a.id)<=Date.now());if(q.length&&!j.length){const x=Math.min(...q.map(f=>de(f,a.id)));x<I&&(I=x,z=`${a.provider}/${a.id}`);continue}const te=l?[void 0,void 0]:q.length?j:[void 0];for(const[x,f]of te.entries()){const v=Date.now();let oe=f?.access;if(f&&f.expires<=Date.now()&&H(m)){const o=g.getProvider(m)?.auth.oauth;if(!o)throw new i(503,"upstream_model_unavailable",`no OAuth refresh for ${m}`,void 0,{served_model:`${a.provider}/${a.id}`});oe=(await qe(m,f.label,async(k,ne)=>{const W=await o.refresh({type:"oauth",refresh:k,access:"",expires:0,...ne?{clientId:ne}:{}},t??new AbortController().signal),V=W.clientId;return{refresh:W.refresh,access:W.access,expires:W.expires,...typeof V=="string"&&V?{clientId:V}:{}}})).access}const he=Te(e);let N;if(l&&s)try{N=await Se({audience:s.base_url,sub:l.sub,grantee:l.grantee,initiating_app:l.grantee,scope:["crtr:llm"]},{signal:t})}catch(o){throw Je(o)}const C=f||l?void 0:await g.getApiKeyAndHeaders(a);if(C&&!C.ok)continue;const p=`${a.provider}/${a.id}`,O=e.model??p;let A=!1,L,M=3e4,R;const B=[],X=[],D=[];let d,F;const T=u((o,_=null)=>({id:ee,object:"chat.completion.chunk",created:Math.floor(v/1e3),model:p,served_model:p,requested_model:O,substituted:O!==p&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(O),choices:[{index:0,delta:o,finish_reason:_}]}),"chunk"),P=u(o=>{B.push(o),n?.(o)},"emit"),_e=ve(a,he,{apiKey:N?.access_token??oe??(C?.ok?C.apiKey:void 0),...C?.ok?{headers:C.headers}:{},signal:t,reasoning:e.reasoning_effort??c.thinkingLevel,...e.temperature!==void 0?{temperature:e.temperature}:{},...e.max_tokens!==void 0?{maxTokens:e.max_tokens}:{},...e.top_p!==void 0?{samplingParams:{top_p:e.top_p}}:{},...e.tool_choice==="none"?{toolChoice:"none"}:{},onPayload:u(o=>{if(!o||typeof o!="object")return;const _=e.tool_choice,k=_==="required"?a.api==="anthropic-messages"?{type:"any"}:"required":typeof _=="object"&&_!==null?a.api==="anthropic-messages"?{type:"tool",name:_.function.name}:_:void 0;return{...o,...k?{tool_choice:k}:{},...e.stop!==void 0?{[a.api==="anthropic-messages"?"stop_sequences":"stop"]:typeof e.stop=="string"?[e.stop]:e.stop}:{},...e.seed!==void 0?{seed:e.seed}:{},...e.response_format!==void 0?{response_format:e.response_format}:{}}},"onPayload"),fetch:u(async(o,_)=>{const k=await fetch(o,_);return L=k.status,k.status===429&&(A=!0,R=k.headers,M=K(k.headers)??15e3),k},"fetch"),onResponse:u(o=>{o.status===429&&(A=!0,R=o.headers,M=K(o.headers)??15e3)},"onResponse")});try{for await(const o of _e)o.type==="text_delta"&&(X.push(o.delta),P(T({content:o.delta}))),o.type==="thinking_delta"&&(D.push(o.delta),P(T({reasoning_content:o.delta}))),o.type==="done"&&(d=o.message),o.type==="error"&&(d=o.error)}catch(o){const _=Ae(o);R===void 0&&o&&typeof o=="object"&&"headers"in o&&Object.keys(Ie(o.headers)).length&&(R=o.headers);const k=ce({status:o&&typeof o=="object"&&"status"in o?o.status:void 0,message:o instanceof Error?o.message:String(o)});if(l)F=o;else{if(!A&&k.kind!=="rate-limit")throw B.length?new i(503,"upstream_model_unavailable",o instanceof Error?o.message:String(o),void 0,{served_model:p}):o;A=!0,M=_??M}}if(l){if(L===401){if(N&&Le(N.key),x===0)continue;throw new i(404,"model_unavailable",`${s.base_url} refuses this runtime's tokens`,void 0,{served_model:p})}if(A&&K(R)===void 0)throw new i(503,"upstream_model_unavailable",`${p} was rate-limited without a retry-after`,void 0,{served_model:p});if(!A&&(F!==void 0||L!==void 0&&L>=500))throw new i(503,"upstream_model_unavailable",F instanceof Error?F.message:d?.errorMessage??"inference endpoint failed",void 0,{served_model:p})}if(!A&&d?.stopReason==="error"&&ce({message:d.errorMessage}).kind==="rate-limit"&&(A=!0,M=15e3),A){const o=$e(R,a.id);if(K(R)===void 0&&o.resetAt!==void 0&&(M=Math.max(M,o.resetAt-Date.now())),b={provider:m,model:a.id,...f?{account:f.label}:{},observation:o},console.error(`[llm] 429 from ${p}${f?` account "${f.label}"`:""}: scope=${le(o.scope)} retry_after_ms=${M} headers=${JSON.stringify(o.headers)}`),f&&H(m)&&await ke(m,f.label,M,v,Date.now(),o.scope),Date.now()+Math.min(M,ae)<I&&(I=Date.now()+Math.min(M,ae),z=p),X.length||D.length)throw new i(503,"service_unavailable","vendor rate limit after output began",void 0,{served_model:p});if(l)break;continue}const U=Ce(d);if(L===400&&e.tool_choice!==void 0&&e.tool_choice!=="auto"&&e.tool_choice!=="none"&&/\btool[_ ]choice\b/i.test(d?.errorMessage??"")&&/not supported|does not support|unsupported|cannot|must be auto/i.test(d?.errorMessage??""))throw new i(400,"invalid_request",d.errorMessage,"tool_choice",{served_model:p});if(d?.stopReason==="error"){const o=He(a.provider,d.errorMessage,p);if(o)throw o}if(!d||d.stopReason==="error"&&!U||d.stopReason==="aborted")throw new i(503,"upstream_model_unavailable",d?.errorMessage??"model request failed",void 0,{served_model:p});f&&H(m)&&Re(f,a.id)&&await je(m,f.label,v,a.id);const G=d.content.filter(o=>o.type==="toolCall").map(o=>({id:o.id,type:"function",function:{name:o.name,arguments:JSON.stringify(o.arguments)}})),Z=U?"content_filter":d.stopReason==="toolUse"?"tool_calls":d.stopReason==="length"?"length":"stop",Q=d.responseModel?Ue(a,d.responseModel):void 0,S=Q?`${a.provider}/${Q.model}`:p,J={prompt_tokens:d.usage.input,completion_tokens:d.usage.output,total_tokens:d.usage.totalTokens,cache_read_tokens:d.usage.cacheRead,cache_write_tokens:d.usage.cacheWrite,usd_equivalent:Pe(Q??a,d.usage.cost.total),served_model:S};l?ue(l.grantee,"app",S,d.usage,J.usd_equivalent):w&&ue(w.grantee,"user",S,d.usage,J.usd_equivalent);const ye={id:ee,object:"chat.completion",created:Math.floor(v/1e3),model:S,served_model:S,requested_model:O,substituted:O!==S&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(O),choices:[{index:0,message:{role:"assistant",content:X.join("")||null,...D.length?{reasoning_content:D.join("")}:{},...G.length?{tool_calls:G}:{},...U?{refusal:d.errorMessage??"Content filtered"}:{}},finish_reason:Z}],usage:J,...e.metadata!==void 0?{metadata:e.metadata}:{}};for(const[o,_]of G.entries())P(T({tool_calls:[{index:o,..._}]}));return P({...T({},Z),...U?{choices:[{index:0,delta:{},finish_reason:Z,message:{refusal:d.errorMessage??"Content filtered"}}]}:{},usage:J}),{completion:ye,chunks:B}}}throw I!==1/0?new i(429,"all_routes_exhausted","all eligible model routes are rate-limited",void 0,{retry_after_s:Math.max(1,Math.ceil((I-Date.now())/1e3)),served_model:b?`${b.provider}/${b.model}`:z,...b?{rate_limit:{provider:b.provider,model:b.model,...b.account?{account:b.account}:{},scope:le(b.observation.scope),...b.observation.claim?{claim:b.observation.claim}:{},headers:b.observation.headers}}:{}},void 0,!0):e.model_policy==="exact"?new i(400,"substitution_refused","the requested model is unavailable"):new i(404,"model_unavailable","no usable model route is available")}u(lt,"runLlm");export{dt as llmCallerOf,at as parseLlmRequest,lt as runLlm};
|
|
3
|
+
`),l=e.tools?.map(({function:s})=>({name:s.name,description:s.description??"",parameters:s.parameters??{type:"object",properties:{}}}));return{...y?{systemPrompt:y}:{},messages:n.slice(w.length),...l?{tools:l}:{}}}u(Ue,"contextOf");function me(e,t,n,r){if(!e){const y=ae(n,r),l=Object.values({...y.modelRoutes??{},...y.legacyModelRoutes??{}}),s=l.length?[y.modelLadders.defaultProvider,...y.modelRouting?.familyOrder??[],...l.map(g=>g.family)].find(g=>l.some(E=>E.family===g)):y.modelLadders.defaultProvider??"anthropic";return{kind:"logical",family:s,strength:"strong",spec:`${s}/strong`}}const w=/^([^/]+)\/(ultra|strong|medium|light)$/.exec(e);return w?{kind:"logical",family:w[1],strength:w[2],spec:e}:{kind:t==="exact"?"exact":"concrete",spec:e}}u(me,"requestFor");function Je(e,t){const{input:n,output:r,cacheRead:w,cacheWrite:y}=e.cost;return n===0&&r===0&&w===0&&y===0?null:Number.isFinite(t)&&t>=0?t:null}u(Je,"usdEquivalent");function We(e,t){return e.compat?.allowedFallbackModels?.find(r=>r.provider===e.provider&&r.model===t)}u(We,"allowedFallback");function ct(e){return e?{payer:e.payer??"user",sub:e.sub,grantee:e.grantee,inference_endpoint:e.inference_endpoint??null}:void 0}u(ct,"llmCallerOf");function He(e){return e instanceof Ne?e.code==="server_error"?new i(503,"upstream_model_unavailable",e.message):new i(404,"model_unavailable",e.message):e}u(He,"mintFailure");const Ke=/\bmodel is not supported when using Codex with a ChatGPT account\b/i;function ze(e,t,n){if(!(e!=="openai-codex"||t===void 0||!Ke.test(t)))return new i(404,"model_unavailable",t,void 0,{served_model:n})}u(ze,"codexAccountModelRejection");async function ut(e,t,n,r,w,y){const l=y?.payer==="app"?y:void 0;if(e.payer==="app"&&!l)throw new i(403,"payer_not_app","this grant is not app-paid");if(e.payer==="user"&&l)throw new i(400,"invalid_request","this grant is app-paid; payer cannot be user","payer");if(l&&!l.inference_endpoint)throw new i(404,"model_unavailable",`${l.grantee} is app-paid but its grant carries no inference endpoint`);const s=l?.inference_endpoint??void 0;l||Oe(w);const g=await ke(),E=u(c=>c.routeId!=="concrete"&&c.routeId!=="exact","configured"),ee=u(c=>{const h=g.find(c.providerId,c.modelId);return h!==void 0&&(!e.reasoning_effort||h.reasoning)&&(e.seed===void 0&&e.response_format===void 0||h.api==="openai-completions")&&(e.stop===void 0||["openai-completions","anthropic-messages"].includes(h.api))},"matchesFeatures"),pe=u(()=>{const c=me(e.model,e.model_policy,r?.cwd,r?.profileId),h=ie(c.kind==="exact"?{kind:"concrete",spec:c.spec}:c,r?.cwd,r?.profileId).filter(E);let a;if(c.kind==="logical")a=e.model_policy==="exact"?h.filter(m=>m.family===c.family&&m.strength===c.strength).slice(0,1):h;else{const m=se(c.spec),q=h.filter(j=>j.providerId===m?.providerId&&j.modelId===m.modelId&&(e.model_policy!=="exact"||j.thinkingLevel===m.thinkingLevel)&&ee(j));if(e.model_policy==="exact")a=q.slice(0,1);else if(q.length)a=q;else{const j=ae(r?.cwd,r?.profileId),x=[...Object.values(j.modelRoutes??{}).flatMap(v=>Object.entries(v.models)),...[j.modelLadders.anthropic,j.modelLadders.openai].flatMap(v=>Object.entries(v))].find(([,v])=>v===c.spec)?.[0],f=me(void 0,"substitute",r?.cwd,r?.profileId);a=x&&f.kind==="logical"?ie({...f,strength:x,spec:c.spec},r?.cwd,r?.profileId).filter(v=>E(v)&&v.strength===x):[]}}return a},"ownerCandidates");let R;if(s?R=De(s,e.model,e.model_policy==="exact").flatMap((c,h)=>{const a=se(c.model);return a?[{routeId:"app",credentialSource:"app",family:"app",strength:c.strength,...a,rank:h}]:[]}):R=pe(),R=R.filter(ee),R.length===0)throw e.model_policy==="exact"?new i(400,"substitution_refused","no eligible model route is configured"):new i(404,"model_unavailable","no eligible model route is configured");const te=`chatcmpl-${ve()}`;let I=1/0,b,z;for(const c of R){if(!l&&!xe(c,g).authenticated)continue;const h=g.find(c.providerId,c.modelId);if(!h)continue;const a=s?{...h,baseUrl:`${s.base_url}/${h.provider}`}:h,m=c.providerId,q=!l&&H(m)?Ae(m).filter(x=>!x.authFailure):[],j=q.filter(x=>le(x,a.id)<=Date.now());if(q.length&&!j.length){const x=Math.min(...q.map(f=>le(f,a.id)));x<I&&(I=x,z=`${a.provider}/${a.id}`);continue}const oe=l?[void 0,void 0]:q.length?j:[void 0];for(const[x,f]of oe.entries()){const v=Date.now();let ne=f?.access;if(f&&f.expires<=Date.now()&&H(m)){const o=g.getProvider(m)?.auth.oauth;if(!o)throw new i(503,"upstream_model_unavailable",`no OAuth refresh for ${m}`,void 0,{served_model:`${a.provider}/${a.id}`});ne=(await $e(m,f.label,async(k,re)=>{const W=await o.refresh({type:"oauth",refresh:k,access:"",expires:0,...re?{clientId:re}:{}},t??new AbortController().signal).catch(ge=>{throw Te(ge,`${a.provider}/${a.id}`)}),V=W.clientId;return{refresh:W.refresh,access:W.access,expires:W.expires,...typeof V=="string"&&V?{clientId:V}:{}}})).access}const he=Ue(e);let N;if(l&&s)try{N=await Le({audience:s.base_url,sub:l.sub,grantee:l.grantee,initiating_app:l.grantee,scope:["crtr:llm"]},{signal:t})}catch(o){throw He(o)}const C=f||l?void 0:await g.getApiKeyAndHeaders(a);if(C&&!C.ok)continue;const p=`${a.provider}/${a.id}`,S=e.model??p;let A=!1,L,M=3e4,$;const B=[],X=[],D=[];let d,F;const T=u((o,_=null)=>({id:te,object:"chat.completion.chunk",created:Math.floor(v/1e3),model:p,served_model:p,requested_model:S,substituted:S!==p&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(S),choices:[{index:0,delta:o,finish_reason:_}]}),"chunk"),P=u(o=>{B.push(o),n?.(o)},"emit"),_e=we(a,he,{apiKey:N?.access_token??ne??(C?.ok?C.apiKey:void 0),...C?.ok?{headers:C.headers}:{},signal:t,reasoning:e.reasoning_effort??c.thinkingLevel,...e.temperature!==void 0?{temperature:e.temperature}:{},...e.max_tokens!==void 0?{maxTokens:e.max_tokens}:{},...e.top_p!==void 0?{samplingParams:{top_p:e.top_p}}:{},...e.tool_choice==="none"?{toolChoice:"none"}:{},onPayload:u(o=>{if(!o||typeof o!="object")return;const _=e.tool_choice,k=_==="required"?a.api==="anthropic-messages"?{type:"any"}:"required":typeof _=="object"&&_!==null?a.api==="anthropic-messages"?{type:"tool",name:_.function.name}:_:void 0;return{...o,...k?{tool_choice:k}:{},...e.stop!==void 0?{[a.api==="anthropic-messages"?"stop_sequences":"stop"]:typeof e.stop=="string"?[e.stop]:e.stop}:{},...e.seed!==void 0?{seed:e.seed}:{},...e.response_format!==void 0?{response_format:e.response_format}:{}}},"onPayload"),fetch:u(async(o,_)=>{const k=await fetch(o,_);return L=k.status,k.status===429&&(A=!0,$=k.headers,M=K(k.headers)??15e3),k},"fetch"),onResponse:u(o=>{o.status===429&&(A=!0,$=o.headers,M=K(o.headers)??15e3)},"onResponse")});try{for await(const o of _e)o.type==="text_delta"&&(X.push(o.delta),P(T({content:o.delta}))),o.type==="thinking_delta"&&(D.push(o.delta),P(T({reasoning_content:o.delta}))),o.type==="done"&&(d=o.message),o.type==="error"&&(d=o.error)}catch(o){const _=qe(o);$===void 0&&o&&typeof o=="object"&&"headers"in o&&Object.keys(Ce(o.headers)).length&&($=o.headers);const k=Y({status:o&&typeof o=="object"&&"status"in o?o.status:void 0,message:o instanceof Error?o.message:String(o)});if(l)F=o;else{if(!A&&k.kind!=="rate-limit")throw B.length?new i(503,"upstream_model_unavailable",o instanceof Error?o.message:String(o),void 0,{served_model:p}):o;A=!0,M=_??M}}if(l){if(L===401){if(N&&Ee(N.key),x===0)continue;throw new i(404,"model_unavailable",`${s.base_url} refuses this runtime's tokens`,void 0,{served_model:p})}if(A&&K($)===void 0)throw new i(503,"upstream_model_unavailable",`${p} was rate-limited without a retry-after`,void 0,{served_model:p});if(!A&&(F!==void 0||L!==void 0&&L>=500))throw new i(503,"upstream_model_unavailable",F instanceof Error?F.message:d?.errorMessage??"inference endpoint failed",void 0,{served_model:p})}if(!A&&d?.stopReason==="error"&&Y({message:d.errorMessage}).kind==="rate-limit"&&(A=!0,M=15e3),A){const o=Ie($,a.id);if(K($)===void 0&&o.resetAt!==void 0&&(M=Math.max(M,o.resetAt-Date.now())),b={provider:m,model:a.id,...f?{account:f.label}:{},observation:o},console.error(`[llm] 429 from ${p}${f?` account "${f.label}"`:""}: scope=${ce(o.scope)} retry_after_ms=${M} headers=${JSON.stringify(o.headers)}`),f&&H(m)&&await je(m,f.label,M,v,Date.now(),o.scope),Date.now()+Math.min(M,de)<I&&(I=Date.now()+Math.min(M,de),z=p),X.length||D.length)throw new i(503,"service_unavailable","vendor rate limit after output began",void 0,{served_model:p});if(l)break;continue}const U=Se(d);if(L===400&&e.tool_choice!==void 0&&e.tool_choice!=="auto"&&e.tool_choice!=="none"&&/\btool[_ ]choice\b/i.test(d?.errorMessage??"")&&/not supported|does not support|unsupported|cannot|must be auto/i.test(d?.errorMessage??""))throw new i(400,"invalid_request",d.errorMessage,"tool_choice",{served_model:p});if(d?.stopReason==="error"){const o=ze(a.provider,d.errorMessage,p);if(o)throw o}if(!d||d.stopReason==="error"&&!U||d.stopReason==="aborted")throw new i(503,"upstream_model_unavailable",d?.errorMessage??"model request failed",void 0,{served_model:p});f&&H(m)&&Re(f,a.id)&&await Me(m,f.label,v,a.id);const G=d.content.filter(o=>o.type==="toolCall").map(o=>({id:o.id,type:"function",function:{name:o.name,arguments:JSON.stringify(o.arguments)}})),Z=U?"content_filter":d.stopReason==="toolUse"?"tool_calls":d.stopReason==="length"?"length":"stop",Q=d.responseModel?We(a,d.responseModel):void 0,O=Q?`${a.provider}/${Q.model}`:p,J={prompt_tokens:d.usage.input,completion_tokens:d.usage.output,total_tokens:d.usage.totalTokens,cache_read_tokens:d.usage.cacheRead,cache_write_tokens:d.usage.cacheWrite,usd_equivalent:Je(Q??a,d.usage.cost.total),served_model:O};l?ue(l.grantee,"app",O,d.usage,J.usd_equivalent):w&&ue(w.grantee,"user",O,d.usage,J.usd_equivalent);const ye={id:te,object:"chat.completion",created:Math.floor(v/1e3),model:O,served_model:O,requested_model:S,substituted:S!==O&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(S),choices:[{index:0,message:{role:"assistant",content:X.join("")||null,...D.length?{reasoning_content:D.join("")}:{},...G.length?{tool_calls:G}:{},...U?{refusal:d.errorMessage??"Content filtered"}:{}},finish_reason:Z}],usage:J,...e.metadata!==void 0?{metadata:e.metadata}:{}};for(const[o,_]of G.entries())P(T({tool_calls:[{index:o,..._}]}));return P({...T({},Z),...U?{choices:[{index:0,delta:{},finish_reason:Z,message:{refusal:d.errorMessage??"Content filtered"}}]}:{},usage:J}),{completion:ye,chunks:B}}}throw I!==1/0?new i(429,"all_routes_exhausted","all eligible model routes are rate-limited",void 0,{retry_after_s:Math.max(1,Math.ceil((I-Date.now())/1e3)),served_model:b?`${b.provider}/${b.model}`:z,...b?{rate_limit:{provider:b.provider,model:b.model,...b.account?{account:b.account}:{},scope:ce(b.observation.scope),...b.observation.claim?{claim:b.observation.claim}:{},headers:b.observation.headers}}:{}},void 0,!0):e.model_policy==="exact"?new i(400,"substitution_refused","the requested model is unavailable"):new i(404,"model_unavailable","no usable model route is available")}u(ut,"runLlm");export{ct as llmCallerOf,lt as parseLlmRequest,ut as runLlm};
|
|
@@ -61,14 +61,12 @@ export declare class FaultRetry {
|
|
|
61
61
|
private providerFallbackInFlight;
|
|
62
62
|
private notFoundFallbackInFlight;
|
|
63
63
|
private stagedCapacityFailure;
|
|
64
|
-
private
|
|
64
|
+
private agentStarts;
|
|
65
65
|
constructor(deps: FaultRetryDeps);
|
|
66
66
|
clearTimer(): void;
|
|
67
67
|
reset(): void;
|
|
68
68
|
/** No recovery turn will follow the settled turn: a run node writes its held-back turn end now. */
|
|
69
69
|
abandonTurnEnd(): void;
|
|
70
|
-
/** A failed daemon-backed persona gate is local evidence, not a provider fault. */
|
|
71
|
-
notePersonaGateFailure(): void;
|
|
72
70
|
private state;
|
|
73
71
|
private recordFault;
|
|
74
72
|
private clearFault;
|
|
@@ -77,7 +75,15 @@ export declare class FaultRetry {
|
|
|
77
75
|
onEvent(event: BrokerToClient): void;
|
|
78
76
|
isActiveAutoFault(fault: RecoveryFaultDTO | null): fault is RecoveryFaultDTO;
|
|
79
77
|
isActiveAutoFault(fault: Fault | null): fault is Fault;
|
|
78
|
+
/** Record the settled turn's outcome with the daemon. The staged outcome is
|
|
79
|
+
* taken once; the daemon writes are then retried until the daemon answers,
|
|
80
|
+
* because a turn that ended on a daemon-call failure (the machine just woke)
|
|
81
|
+
* must still leave its fault behind — an unrecorded fault lets the
|
|
82
|
+
* unattended check release the node. Retrying stops when a rebind replaces
|
|
83
|
+
* this generation, since the replacement owns recovery from then on, and when
|
|
84
|
+
* another turn starts, since a stale fault would re-drive from the old anchor. */
|
|
80
85
|
publishSettledProviderFault(generation: SubscriptionGeneration): Promise<void>;
|
|
86
|
+
private recordStagedOutcome;
|
|
81
87
|
/** Startup re-drive reads the durable episode surviving from the process this
|
|
82
88
|
* replaces. Revive deliberately clears the ordinary fault marker before this
|
|
83
89
|
* boundary, so the episode is the recovery authority. A `pending` episode
|