@tbox.cn/tboxcode-dsh-sdk 0.1.0-rc.3 → 0.1.0-rc.5
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/lib/index.d.ts +10 -7
- package/lib/index.js +4 -4
- package/package.json +3 -3
package/lib/index.d.ts
CHANGED
|
@@ -59,6 +59,8 @@ declare class Supervisor {
|
|
|
59
59
|
constructor(options?: SupervisorOptions, spawner?: SupervisorSpawner, exchange?: (port: number, token: string) => Promise<string>);
|
|
60
60
|
phase(): SupervisorPhase;
|
|
61
61
|
onPhaseChange(listener: (phase: SupervisorPhase) => void): () => void;
|
|
62
|
+
/** live stderr tap(已脱敏;box 接日志/诊断面)。 */
|
|
63
|
+
onStderrLine(listener: (line: string) => void): () => void;
|
|
62
64
|
/** 启动(spawn → standby → start 释放 → ready)。失败(永久 / 偏斜 / 退避耗尽)抛部署错误。 */
|
|
63
65
|
start(): Promise<void>;
|
|
64
66
|
/**
|
|
@@ -131,9 +133,14 @@ interface WireAssistantStreamBaseline {
|
|
|
131
133
|
}
|
|
132
134
|
/** assistant-stream live 帧(dsh agent runtime-types 呈现帧的 wire 子集)。 */
|
|
133
135
|
interface WireAssistantStreamFrame {
|
|
136
|
+
/** 上游帧判别(start 携带 durable turn/step,为 durable 配对键);历史合成帧可缺席。 */
|
|
137
|
+
readonly type?: 'start' | 'chunk' | 'end';
|
|
134
138
|
readonly attemptId: string;
|
|
135
|
-
readonly index
|
|
139
|
+
readonly index?: number;
|
|
136
140
|
readonly revision: number;
|
|
141
|
+
/** start 帧携带的 durable turn/step(durable `assistant/message` 配对键)。 */
|
|
142
|
+
readonly turn?: number;
|
|
143
|
+
readonly step?: number;
|
|
137
144
|
readonly chunk?: {
|
|
138
145
|
readonly type: string;
|
|
139
146
|
readonly text?: string;
|
|
@@ -491,12 +498,8 @@ declare class RpcSessionDeps implements SessionDeps {
|
|
|
491
498
|
}) => Promise<Array<{
|
|
492
499
|
header: PersistedHeader;
|
|
493
500
|
}>>;
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
}) => Promise<{
|
|
497
|
-
read(opts?: {
|
|
498
|
-
signal?: AbortSignal;
|
|
499
|
-
}): Promise<{
|
|
501
|
+
openHistoryRead: (sessionId: string, signal?: AbortSignal) => Promise<{
|
|
502
|
+
read(readSignal?: AbortSignal): Promise<{
|
|
500
503
|
events: readonly never[];
|
|
501
504
|
}>;
|
|
502
505
|
close(): Promise<void>;
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{spawn as e}from"node:child_process";import{randomUUID as t}from"node:crypto";import n,{WebSocketServer as r}from"ws";import{MODE_TABLE as i,classify as a,isIgnorable as o}from"@tbox.cn/dsh-acp-bridge-core";var s=class extends Error{kind;report;constructor(e,t,n){super(t),this.name=`SupervisorDeploymentError`,this.kind=e,this.report=n}};function c(e){let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=`object`||!t||Array.isArray(t))return null;let n=t;return n.v===1&&(n.event===`standby`||n.event===`ready`&&typeof n.port==`number`&&typeof n.token==`string`)?t:null}async function l(e,t){let n=await fetch(`http://127.0.0.1:${e}/connect?token=${encodeURIComponent(t)}&interactions=answer`,{redirect:`manual`});if(n.status!==302)throw Error(`/connect 凭据交换期待 302,实得 ${n.status}(port ${e})`);let r=n.headers.get(`set-cookie`);if(r===null)throw Error(`/connect 凭据交换缺 Set-Cookie`);let i=r.split(`;`)[0]??``;if(i===``)throw Error(`/connect 凭据交换缺 Set-Cookie`);return i}
|
|
2
|
-
`)}async dispose(){if(this.#
|
|
3
|
-
`);if(t<0)break;let r=e.slice(0,t);e=e.slice(t+1),n.forEach(e=>e(r))}return e};return r.stdout?.on(`data`,e=>{i=l(i,e.toString(),o)}),r.stderr?.on(`data`,e=>{a=l(a,e.toString(),s)}),r.on(`close`,e=>{i!==``&&o.forEach(e=>e(i)),a!==``&&s.forEach(e=>e(a)),c.forEach(t=>t(e))}),{writeStdin:e=>r.stdin?.write(e),onStdoutLine:e=>o.push(e),onStderrLine:e=>s.push(e),onExit:e=>c.push(e),kill:e=>r.kill(e??`SIGTERM`)}}}function f(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function p(e){return!f(e)||typeof e.type!=`string`||e.type===``||typeof e.seq!=`number`||!Number.isInteger(e.seq)||typeof e.time!=`number`||!(`data`in e)?null:e}function m(e){if(!f(e)||e.type!==`event`)return null;let t=p(e.event);return t===null?null:{type:`event`,event:t}}function h(e){if(!f(e))return null;if(e.type===`snapshot`){let t=f(e.header)?e.header:null;if(t===null||typeof e.cursor!=`number`||typeof e.hasMore!=`boolean`)return null;let n=[];if(Array.isArray(e.records))for(let t of e.records){let e=m(t);if(e===null)return null;n.push(e)}else return null;return{type:`snapshot`,header:t,cursor:e.cursor,records:n,hasMore:e.hasMore,projections:e.projections,...f(e.assistantStream)?{assistantStream:e.assistantStream}:{}}}return e.type===`assistant-stream`?f(e.frame)?{type:`assistant-stream`,frame:e.frame}:null:m(e)}function g(e){if(!f(e)||typeof e.hasMore!=`boolean`||!Array.isArray(e.records))return null;let t=[];for(let n of e.records){let e=m(n);if(e===null)return null;t.push(e)}return{records:t,hasMore:e.hasMore}}function _(e){return f(e)&&(e.type===`ready`&&typeof e.clientId==`string`&&f(e.host)||e.type===`emit`&&typeof e.event==`string`&&Array.isArray(e.args)||e.type===`waterfall`&&typeof e.eventId==`string`&&typeof e.agentId==`string`&&typeof e.event==`string`&&f(e.request)||e.type===`cancel`&&typeof e.eventId==`string`)?e:null}var v=class extends Error{code;details;constructor(e){super(e.message),this.name=`CarrierRpcError`,this.code=e.code,this.details=e.details}},y=class extends Error{constructor(e){super(e),this.name=`CarrierTransportError`}},b=class{#e;#t;#n;#r;#i;#a;#o=!1;#s=!1;constructor(e){this.#e=e.baseUrl.replace(/\/$/,``),this.#t=e.cookie,this.#n=e.refreshCredentials}async unary(e,t){this.#p();try{return await this.#c(e,t)}catch(n){if(!(n instanceof y&&n.message.endsWith(`HTTP 401`))||this.#n===void 0)throw n;return await this.#f(),this.#c(e,t)}}async#c(e,n){let r=t(),i;try{i=await fetch(`${this.#e}/api/${e}`,{method:`POST`,headers:{"content-type":`application/json`,cookie:this.#t},body:JSON.stringify({type:`client-request`,rpcId:r,method:e,payload:{args:n}}),signal:AbortSignal.timeout(6e4)})}catch(t){throw t instanceof Error&&t.name===`TimeoutError`?new y(`unary ${e} 超时(上游 60s 无响应)`):t}if(i.status!==200)throw new y(`unary ${e} HTTP ${i.status}`);let a=await i.json();if(a.type!==`server-response`||a.rpcId!==r)throw new y(`unary ${e} envelope 畸形(type/rpcId 失配)`);if(a.result.ok)return a.result.value;throw new v(a.result.error)}openStream(e,r,i){this.#p();let a=t(),o=!1,s={canceled:!1,onFrame:e=>{e.type===`item`?i.onItem(e.value):e.type===`end`?(s.canceled=!0,i.onEnd?.()):e.type===`error`&&(s.canceled=!0,i.onError?.(e.error??{code:`gateway/internal`,message:`stream error 帧缺 error 字段`}))},onDown:e=>{s.canceled||(s.canceled=!0,e&&i.onError?.({code:`carrier/mux-closed`,message:`mux 插座意外关闭`}),i.onClose?.(e))}};return this.#l().then(t=>{if(o||s.canceled){process.stderr.write(`[carrier] open ABORTED (canceled=${String(o)} entry=${String(s.canceled)}) ${e}\n`);return}t.streams.set(a,s),t.socket.readyState===n.OPEN?(t.socket.send(JSON.stringify({type:`open`,streamId:a,endpoint:e,payload:{args:r}})),process.env.CARRIER_WIRE_DEBUG===`1`&&process.stderr.write(`[carrier] open sent ${e} streamId=${a.slice(0,8)}\n`)):process.stderr.write(`[carrier] open SKIPPED (readyState ${t.socket.readyState}) ${e}\n`)}).catch(e=>{o||s.canceled||(s.canceled=!0,i.onError?.({code:`carrier/mux-open`,message:e.message}),i.onClose?.(!0))}),{cancel:()=>{o=!0,s.canceled=!0;let e=this.#r;e!==void 0&&e.streams.delete(a)&&e.socket.readyState===n.OPEN&&e.socket.send(JSON.stringify({type:`cancel`,streamId:a}))}}}async#l(){let e=this.#r;if(e!==void 0&&e.socket.readyState===n.OPEN)return e;if(this.#i!==void 0)return this.#i;let t=this.#u().finally(()=>{this.#i===t&&(this.#i=void 0)});return this.#i=t,t}async#u(){this.#p(),this.#o&&this.#n!==void 0&&await this.#f();let e=new n(`${x(this.#e)}/api/remote.mux`,{headers:{cookie:this.#t}});await new Promise((t,n)=>{let r=setTimeout(()=>n(new y(`mux 插座打开超时`)),15e3);r.unref(),e.once(`open`,()=>{clearTimeout(r),t()}),e.once(`error`,e=>{clearTimeout(r),n(new y(`mux 插座打开失败: ${e.message}`))}),e.once(`unexpected-response`,(e,t)=>{clearTimeout(r),n(new y(`mux 升级被拒 HTTP ${t.statusCode??`?`}`))})});let t={socket:e,streams:new Map};e.on(`message`,e=>{let n;try{n=JSON.parse(String(e))}catch{return}typeof n.streamId==`string`&&t.streams.get(n.streamId)?.onFrame(n)});let r=!1;return e.on(`close`,()=>this.#d(t,r)),e.on(`error`,()=>{r=!0}),this.#r=t,this.#o=!0,t}#d(e,t){if(this.#r===e){this.#r=void 0;for(let n of e.streams.values())n.onDown(t);e.streams.clear()}}#f(){if(this.#a!==void 0)return this.#a;let e=(async()=>{let e=this.#n;if(e===void 0)return;let t=await e();this.#t=t.cookie,this.#e=t.baseUrl.replace(/\/$/,``)})().finally(()=>{this.#a===e&&(this.#a=void 0)});return this.#a=e,e}openEvents(e){let t,n=n=>{switch(n.type){case`ready`:t=n.clientId,e.onReady(n);return;case`emit`:e.onEmit(n);return;case`waterfall`:e.onWaterfall(n);return;case`cancel`:e.onCancel(n);return}},r=this.openStream(`$events`,{},{onItem:t=>{let i=_(t);if(i===null){e.onClose?.(!1),r.cancel();return}n(i)},onClose:t=>e.onClose?.(t)});return{respond:async(e,n)=>{if(t===void 0)throw new y(`waterfall 应答先于 ready 帧(clientId 缺席)`);await this.unary(`$events/result`,{clientId:t,eventId:e,outcome:n})},close:()=>r.cancel()}}dispose(){this.#s=!0,this.#r?.socket.close(),this.#r=void 0}#p(){if(this.#s)throw new y(`carrier 已释放`)}};function x(e){if(e.startsWith(`https://`))return`wss://${e.slice(8)}`;if(e.startsWith(`http://`))return`ws://${e.slice(7)}`;throw new y(`baseUrl 非法(期待 http(s)://,实得 ${e})`)}function S(e,t){let n=p(e);if(n===null)return t!==void 0&&(t.invalid+=1),null;if(a(n.type)===`project`)return typeof n.data!=`object`||n.data===null||Array.isArray(n.data)?(t!==void 0&&(t.opaqueWarn+=1),{kind:`opaque`,event:n,level:`warn`}):(t!==void 0&&(t.consumable+=1),{kind:`consumable`,event:n});let r=o(n)?`debug`:`warn`;return r===`debug`?t!==void 0&&(t.opaqueDebug+=1):t!==void 0&&(t.opaqueWarn+=1),{kind:`opaque`,event:n,level:r}}var C=class{#e;#t;#n={invalid:0,opaqueDebug:0,opaqueWarn:0,consumable:0};#r=new Map;#i=0;constructor(e,t){this.#e=e,this.#t=t?.reopenBaseMs??1e3}open(e,t){let n=this.#r.get(e);if(n!==void 0&&!n.closed)return n.handlers=t,{close:()=>this.close(e)};let r={sessionId:e,handlers:t,handle:void 0,cursor:void 0,baseline:void 0,streamSeenRevision:!1,reopening:!1,backoffMs:this.#t,closed:!1,pending:[]};return this.#r.set(e,r),this.#a(r),{close:()=>this.close(e)}}close(e){let t=this.#r.get(e);t!==void 0&&(t.closed=!0,t.handle?.cancel(),this.#r.delete(e))}stats(){let e=0,t=0;for(let n of this.#r.values())n.closed||(n.reopening||n.cursor===void 0?t++:e++);return{live:e,reopening:t,decoded:{...this.#n},gapsRepaired:this.#i}}#a(e){e.closed||(e.reopening=e.cursor!==void 0,e.handle=this.#e.openStream(`session/follow`,{request:{address:{kind:`session`,sessionId:e.sessionId},assistantStream:!0}},{onItem:t=>this.#s(e,t),onEnd:()=>this.#o(e,`stream end`),onError:t=>this.#o(e,`${t.code}: ${t.message}`),onClose:t=>{t&&this.#o(e,`socket error`)}}))}#o(e,t){if(e.closed)return;e.handle=void 0,e.handlers.onDown(t);let n=e.backoffMs;e.backoffMs=Math.min(e.backoffMs*2,3e4),e.baseline=void 0,e.streamSeenRevision=!1,e.reopening=!0,setTimeout(()=>{e.closed||this.#a(e)},n)}#s(e,t){if(t.type===`snapshot`){this.#c(e,t);return}if(e.cursor!==void 0){if(e.reopening){e.pending.push(t);return}this.#d(e,t)}}#c(e,t){let n=e.cursor;if(n!==void 0&&t.cursor<n){e.handlers.onDown(`cursor 回退:${String(t.cursor)} < ${String(n)}`);return}e.baseline=t.assistantStream,e.streamSeenRevision=!1,e.reopening=!0,e.handlers.onSnapshot(t.header,t.cursor,t.projections,t.assistantStream),this.#l(e,t,n)}async#l(e,t,n){try{let r=[];if(n!==void 0&&t.records.length>0){let i=t.records[0]?.event.seq??t.cursor;i>n+1&&(r.push(...await this.#u(e,n+1,i)),this.#i+=r.length)}for(let e of t.records)r.push(e.event);for(let t of r)this.#f(e,t);let i=e.pending;e.pending=[],e.reopening=!1,e.cursor=t.cursor,e.backoffMs=this.#t;for(let t of i)this.#d(e,t)}catch(t){e.handlers.onDown(`backlog 补齐失败:${String(t)}`)}}async#u(e,t,n){let r=[],i=n;for(;i>t;){let n=g(await this.#e.unary(`session/page`,{request:{address:{kind:`session`,sessionId:e.sessionId},throughSeq:i-1,beforeSeq:t,maxMessages:200}}));if(n===null)throw new y(`session/page 帧畸形(records/hasMore 缺失)`);for(let e of n.records)r.push(e.event);let a=n.records[0]?.event.seq;if(a===void 0||a<=t||(i=a,!n.hasMore))break}return r.sort((e,t)=>e.seq-t.seq),r}#d(e,t){if(t.type===`assistant-stream`){if(!e.streamSeenRevision){e.streamSeenRevision=!0;let n=(e.baseline?.revision??-1)+1;if(e.baseline!==void 0&&t.frame.revision!==n){e.handlers.onDown(`assistant-stream 衔接断裂:revision ${String(t.frame.revision)} ≠ ${String(n)}`);return}}e.handlers.onAssistantStream(t.frame);return}t.type===`event`&&this.#f(e,t.event)}#f(e,t){let n=S(t,this.#n);n!==null&&n.kind===`consumable`&&e.handlers.onEvent(n.event)}async readAll(e){return await new Promise((t,n)=>{let r=new Map,i,a,o=!1,s=this.#e.openStream(`session/follow`,{request:{address:{kind:`session`,sessionId:e},assistantStream:!1}},{onItem:c=>{o||c.type===`snapshot`&&(o=!0,i=c.header,a=c.projections,s.cancel(),this.#p(e,c,r).then(e=>t({header:i,events:e,projections:a}),e=>n(e)))},onEnd:()=>{o||(o=!0,n(new y(`session/follow 在 snapshot 前关闭`)))},onError:e=>{o||(o=!0,n(new v(e)))}})})}async#p(e,t,n){let r=[];for(let e of t.records)r.push(e.event);let i=t.records.length>0?t.records[0]?.event.seq:void 0;for(;t.hasMore===!0;){let n=g(await this.#e.unary(`session/page`,{request:{address:{kind:`session`,sessionId:e},throughSeq:t.cursor,...i===void 0?{}:{beforeSeq:i},maxMessages:200}}));if(n===null)throw new y(`session/page 帧畸形(records/hasMore 缺失)`);for(let e of n.records)r.push(e.event);if(!n.hasMore||n.records.length===0)break;let a=n.records[0]?.event.seq;if(a===void 0||a===0)break;i=a}let a=new Map;for(let e of r)a.set(e.seq,e);let o=[...a.values()].sort((e,t)=>e.seq-t.seq);for(let e=0;e<o.length;e++){let t=o[e];if(t?.seq!==e)throw new v({code:`gateway/internal`,message:`journal 连续性断裂:位置 ${String(e)} 实得 seq ${String(t?.seq)}`});let r=S(t,this.#n);r?.kind===`consumable`&&n.set(t.seq,r.event)}return[...n.values()]}},w=class{#e=new Map;#t=new Map;#n=new Map;#r=new Map;#i;#a;#o=0;#s=0;constructor(e,t){this.#i=e,this.#a=t}attachConnection(e,t,n){this.#e.set(e,{connId:e,send:t,ctx:n})}detachConnection(e){this.#e.delete(e);for(let[t,n]of this.#t)n.delete(e),n.size===0&&this.#t.delete(t),this.#a?.onSessionUnbind?.(e,t);for(let[t,n]of this.#n)n===e&&this.#n.delete(t)}bind(e,t){let n=this.#t.get(t);n===void 0&&(n=new Set,this.#t.set(t,n)),n.add(e),this.#a?.onSessionBind?.(e,t)}unbind(e,t){this.#t.get(t)?.delete(e),this.#a?.onSessionUnbind?.(e,t)}boundConnIds(e){return[...this.#t.get(e)??[]]}ctxOf(e){return this.#e.get(e)?.ctx}routeResolved(e,t,n){this.routeExt({method:e,payload:t},n===void 0?void 0:{excludeConnId:n})}beginReplayCount(e){this.#r.set(e,0)}takeReplayCount(e){let t=this.#r.get(e);return this.#r.delete(e),t}setTurnOrigin(e,t){this.#n.set(e,t)}clearTurnOrigin(e){this.#n.delete(e)}route(e){let t=e.sessionId,n;if(t===void 0)n=[...this.#e.keys()];else{let r=this.#n.get(t),i=e.update?.sessionUpdate===`user_message_chunk`;n=[...this.#t.get(t)??[]],r!==void 0&&i&&(n=n.filter(e=>e!==r),this.#s++);let a=this.#a?.fanout===void 0?void 0:T(this.#i,`fanout`,()=>this.#a?.fanout?.(e,n));if(a!==void 0&&(n=[...a]),n.length===0){this.#o++;return}}for(let t of n){let n=this.#e.get(t);if(n===void 0)continue;let r=e;if(this.#a?.transformOutbound!==void 0){let t=T(this.#i,`transformOutbound`,()=>this.#a?.transformOutbound?.(e,n.ctx));if(t===null)continue;t!==void 0&&(r=t)}n.send({jsonrpc:`2.0`,method:`session/update`,params:r});let i=this.#r.get(t);i!==void 0&&this.#r.set(t,i+1)}}routeExt(e,t){let n=typeof e.payload.sessionId==`string`?e.payload.sessionId:void 0,r=n===void 0?[...this.#e.keys()]:[...this.#t.get(n)??[]];t?.excludeConnId!==void 0&&(r=r.filter(e=>e!==t.excludeConnId));for(let t of r)this.#e.get(t)?.send({jsonrpc:`2.0`,method:e.method,params:e.payload})}stats(){return{connections:this.#e.size,dropped:this.#o,suppressed:this.#s}}};function T(e,t,n){try{return n()}catch(n){e.warn(`gateway hook ${t} failed (fail-open): ${String(n)}`);return}}const E=1e3,D=3e4;function O(e){return{id:e.id,get header(){let t=e.header;return{...t?.cwd===void 0?{}:{cwd:t.cwd},...t?.origin===void 0?{}:{origin:t.origin},...t?.parentSession===void 0?{}:{parentSession:t.parentSession},...t?.createdAt===void 0?{}:{createdAt:t.createdAt}}},requestHeader(){let t=e.projections?.modelSelection,n=t?.pending??t?.lastUsed;if(!(n==null||typeof n.provider!=`string`||typeof n.model!=`string`))return{config:{provider:n.provider,model:n.model,...typeof n.reasoningEffort==`string`?{reasoningEffort:n.reasoningEffort}:{}}}}}}function k(e,t,n){return{id:e.id,session:e.session,cancel:async n=>{await t.unary(`session/cancel`,{request:{sessionId:e.id}})},followup:t=>{n(e,t)}}}var A=class{logger;#e;#t;#n;#r=new Map;#i=new Set;#a=new Set;#o=new Set;#s=new Set;#c=new Set;#l;#u=E;#d;#f=E;#p;#m={groups:[],failures:[]};#h=0;#g;constructor(e){this.#e=e.carrier,this.#t=e.pool,this.#n=e.logger,this.logger=e.logger,this.#S(),this.#w(),this.#E()}async createAgent(e){return await this.#_(e)}async resumeAgent(e){return await this.#_(e)}async#_(e){let t=(await this.#e.unary(`session/create`,{request:{sessionId:e.sessionId,cwd:e.cwd}})).sessionId,n=this.#r.get(t);if(n!==void 0)return await e.configureScope?.(this.#y(n),n.agent),{agent:n.agent,dispose:async()=>this.#v(t)};let r={id:t,header:{version:1,id:t,createdAt:0,cwd:e.cwd,isSeeded:!1},projections:{},selectionProbe:void 0,lastPushedSelection:void 0,promptInflight:!1};r.session=O(r),r.agent=k(r,this.#e,(e,t)=>this.#b(e,t));let i=r;return this.#r.set(t,i),await e.configureScope?.(this.#y(i),i.agent),this.#t.open(t,this.#C(i)),{agent:i.agent,dispose:async()=>this.#v(t)}}#v(e){return this.#t.close(e),this.#r.delete(e),Promise.resolve()}#y(e){return{on:(t,n)=>(t===`agent/request`&&(e.selectionProbe=n),()=>{}),tools:{restrict:e=>void 0}}}async#b(e,t){if(e.promptInflight=!0,e.selectionProbe!==void 0)try{let t=await e.selectionProbe(void 0,async()=>({}));if(typeof t.provider==`string`&&typeof t.model==`string`){let n=JSON.stringify([t.provider,t.model,t.reasoningEffort]);n!==e.lastPushedSelection&&(await this.#e.unary(`session/selectModel`,{request:{sessionId:e.id,provider:t.provider,model:t.model,...typeof t.reasoningEffort==`string`?{reasoningEffort:t.reasoningEffort}:{}}}),e.lastPushedSelection=n)}}catch(e){this.#n.debug(`selection probe failed: ${String(e)}`)}await this.#e.unary(`session/prompt`,{request:{requestId:t.id,sessionId:e.id,mode:`steer`,content:t.content}})}persistence={stat:async(e,t)=>{let n=await this.#e.unary(`tboxcode/sessions.stat`,{request:{sessionId:e}});if(n!==null)return{header:n.header}},list:async e=>(await this.#e.unary(`session/list`,{_request:{}})).items.map(e=>({header:{id:e.sessionId,...e.cwd===void 0?{}:{cwd:e.cwd},...e.origin===void 0?{}:{origin:e.origin},...e.parentSessionId===void 0?{}:{parentSession:e.parentSessionId},createdAt:e.updatedAt}})),open:async(e,t)=>{let n=await this.#t.readAll(e);return{read:async()=>({events:n.events}),close:async()=>{}}}};sessionStore={get:e=>this.#r.get(e)?.session,flush:async e=>{await this.#e.unary(`tboxcode/sessions.flush`,{request:{sessionId:e.id}})}};llm={listProviders:()=>this.#x().groups.map(e=>({id:e.id,name:e.name})),listModels:async e=>(this.#x().groups.find(t=>t.id===e)?.models??[]).map(e=>({id:String(e.id),name:String(e.name),...e.description===void 0?{}:{description:String(e.description)}})),resolveModelInfo:async(e,t)=>{let n=this.#x().groups.find(t=>t.id===e)?.models.find(e=>e.id===t)?.reasoning;return{reasoning:{defaultEffort:n?.defaultEffort,efforts:n?.efforts??[]}}},resolveCallConfig:async e=>e};#x(){return Date.now()-this.#h>3e4&&this.#S(),this.#m}async#S(){try{this.#m=await this.#e.unary(`session/modelCatalog`,{}),this.#h=Date.now();let e=await this.#e.unary(`tboxcode/selection.default`,{});this.#g=typeof e.provider==`string`&&typeof e.model==`string`?{provider:e.provider,model:e.model,...e.reasoningEffort===void 0?{}:{reasoningEffort:e.reasoningEffort}}:void 0}catch(e){this.#n.warn(`catalog warm failed: ${String(e)}`)}}applyModeKnobs(e,t,n){let r=Object.entries(i).find(([,e])=>e.sandbox===n.sandbox&&e.approval===n.approval)?.[0];if(r===void 0)throw Error(`tboxcode: mode knobs 无对位(${String(n.sandbox)}/${String(n.approval)}——MODE_TABLE 外组合)`);return this.#e.unary(`tboxcode/mode`,{request:{agentId:e.id,mode:r}}).then(()=>void 0)}defaultSelection(){return this.#g}async executeCommand(e,t,n){let r=await this.#e.unary(`tboxcode/commands.execute`,{request:{agentId:e.id,line:t}});return r?.commandId===void 0?void 0:{commandId:r.commandId}}async listCommands(e){return await this.#e.unary(`tboxcode/commands.list`,{request:{agentId:e.id}})}async listUserInvocableSkills(e){return await this.#e.unary(`tboxcode/skills.userInvocable`,{request:{agentId:e.id}})}onSessionEvent(e){let t=e;return this.#i.add(t),()=>this.#i.delete(t)}onAssistantStream(e){return this.#a.add(e),()=>this.#a.delete(e)}onInboxClaimed(e){return this.#o.add(e),()=>this.#o.delete(e)}onAgentError(e){return this.#s.add(e),()=>this.#s.delete(e)}sessionToolDenies(){return[]}onCommandSurfaceChanged(e){return this.#c.add(e),()=>this.#c.delete(e)}sessionIds(){return[...this.#r.keys()]}hasInflightPrompt(e){return this.#r.get(e)?.promptInflight===!0}poolLive(){return this.#t.stats().live>0}poolEntries(){return this.#r.size}settlePrompt(e,t){let n=this.#r.get(e);if(!(n===void 0||!n.promptInflight)){n.promptInflight=!1;for(let e of this.#s)e({agent:n.agent,turn:0,error:t})}}#C(e){return{onSnapshot:(t,n,r)=>{e.header=t,e.projections=r},onEvent:t=>{t.type===`turn/end`&&(e.promptInflight=!1);for(let n of this.#i)n(e.session,t)},onAssistantStream:t=>{let n={type:t.finish===void 0?t.index===0?`start`:`chunk`:`end`,attemptId:t.attemptId,...t.chunk===void 0?{}:{chunk:t.chunk}};for(let t of this.#a)t({agent:e.agent,frame:n})},onDown:t=>this.#n.warn(`follow pool down (${e.id}): ${t}`)}}#w(){this.#l=this.#e.openStream(`tboxcode/agent.watch`,{},{onItem:e=>{this.#n.debug(`agent.watch item: ${JSON.stringify(e).slice(0,160)} states=${[...this.#r.keys()].join(`,`)}`);let t=this.#r.get(e.sessionId);if(t!==void 0){if(e.kind===`inboxClaimed`)for(let n of this.#o)n({agent:t.agent,message:{...e.messageId===void 0?{}:{id:e.messageId}},turn:e.turn??0});else if(e.kind===`error`)for(let n of this.#s)n({agent:t.agent,turn:0,error:e.error??`unknown agent error`})}},onError:e=>{this.#n.warn(`agent.watch stream error: ${JSON.stringify(e).slice(0,200)}`),this.#T()},onClose:e=>{e&&(this.#n.warn(`agent.watch stream closed`),this.#T())}})}#T(){let e=this.#u;this.#u=Math.min(this.#u*2,D),setTimeout(()=>{this.#w(),this.#u=E},e)}#E(){let e=()=>{for(let e of this.#c)e()};this.#d=j(this.#e,e,this.#n),this.#p=this.#e.openStream(`tboxcode/skills.watch`,{},{onItem:()=>e(),onError:()=>this.#D(),onClose:e=>{e&&this.#D()}})}#D(){let e=this.#f;this.#f=Math.min(this.#f*2,D),setTimeout(()=>{this.#E(),this.#f=E},e)}dispose(){this.#l?.cancel(),this.#d?.close(),this.#p?.cancel()}};function j(e,t,n){return e.openEvents({onReady:()=>n.debug(`commands/change $events ready`),onEmit:e=>{e.event===`commands/change`&&t()},onWaterfall:()=>{},onCancel:()=>{},onClose:e=>{e&&n.warn(`commands/change $events closed with error`)}})}var M=class{#e;#t;#n;#r;#i;#a;#o=!1;#s;constructor(e,t){this.#e=e,this.#t=t?.timeoutMs??12e4,this.#n=t?.tickMs??1e3,this.#r=t?.now??Date.now,this.#i=t?.logger??{warn:()=>{},info:()=>{},debug:()=>{}}}start(){this.#s=setInterval(()=>this.tick(),this.#n)}stop(){this.#s!==void 0&&clearInterval(this.#s),this.#s=void 0}tick(){if(!(this.#e.poolEntries()>0&&!this.#e.poolLive())){this.#a=void 0,this.#o=!1;return}if(this.#a===void 0){this.#a=this.#r();return}if(this.#o||this.#r()-this.#a<this.#t)return;this.#o=!0;let e=this.#r()-this.#a;for(let t of this.#e.sessionIds())this.#e.hasInflightPrompt(t)&&(this.#i.warn(`carrier timeout settle (${t}): downMs=${String(e)}`),this.#e.settle(t,Error(`tboxcode carrier-timeout (downMs=${String(e)})`)))}snapshot(){return{down:this.#a!==void 0,downSince:this.#a,settled:this.#o}}};const N=6e4,P=36e5,F=3e4,I=-32001;var L=class{#e=new Map;#t;constructor(e){this.#t=e}get size(){return this.#e.size}pendingOf(e){for(let t of this.#e.values())if(t.sessionId===e)return t}begin(e){let t=e.event===`user-questions/request`?`elicitation`:e.event===`approval/request`?`permission`:void 0;if(t===void 0||this.#e.has(e.eventId))return;let n=this.#t.sessionIdOfAgent(e.agentId);if(n===void 0){this.#l(e.eventId,{kind:`rejected`,error:{code:`gateway/agent-not-found`,message:`agent ${e.agentId} not managed by gateway`}});return}let r={kind:t,sessionId:n,eventId:e.eventId,frame:e,asked:new Map,state:`active`,budgetStartedAt:this.#t.now()};this.#e.set(e.eventId,r),this.#n(r),this.#s(r)}cancel(e){let t=this.#e.get(e.eventId);t===void 0||t.state===`settled`||this.#c(t,{kind:`result`,value:`cancelled`},`turn`)}attach(e,t){for(let n of this.#e.values()){if(n.sessionId!==t||n.state!==`grace`)continue;let r=n.graceTimer;n.graceTimer=void 0,r!==void 0&&this.#t.timers.clear(r),n.state=`active`,this.#t.logger.info(`answerer: grace broken by attach (${n.eventId} conn=${e})`),this.#n(n)}}switchBack(e,t){this.attach(e,t)}disconnect(e){for(let t of this.#e.values())t.asked.delete(e)&&t.state===`active`&&t.asked.size===0&&this.#o(t,`member disconnected`)}dispose(){for(let e of[...this.#e.values()])e.state!==`settled`&&this.#c(e,{kind:`result`,value:`cancelled`},`dispose`);this.#e.clear()}#n(e){let t=this.#t.eligibleConns(e.sessionId).filter(t=>!e.asked.has(t)).filter(t=>e.kind===`permission`||this.#t.capsOf(t));if(t.length===0){this.#o(e,`no eligible connections`);return}for(let n of t){let t={connId:n};e.kind===`permission`&&(t.timer=this.#t.timers.set(()=>{e.state!==`active`||!e.asked.has(n)||(e.asked.delete(n),this.#t.logger.info(`answerer: member timeout (${e.eventId} conn=${n})`),e.asked.size===0&&this.#o(e,`all members timed out`))},F)),e.asked.set(n,t),this.#r(e,n)}}async#r(e,t){let n=e.kind===`elicitation`?this.#t.buildQuestionParams(e.sessionId,e.frame):{callId:e.frame.request.callId};try{let r=await this.#t.dispatch(t,e.kind,n);if(e.state===`settled`||!e.asked.has(t))return;let i=this.#i(e,r);if(i.abstain){this.#a(e,t,`abstained`);return}this.#c(e,i.outcome,t)}catch(n){if(e.state===`settled`||!e.asked.has(t))return;if(n.code===I){this.#a(e,t,`abstained`);return}this.#t.logger.warn(`answerer: dispatch failed (${e.eventId} conn=${t}): ${n instanceof Error?n.message:String(n)}`),this.#a(e,t,`dispatch failed`)}}#i(e,t){if(e.kind===`permission`){let e=t?.outcome;return e?.outcome===`cancelled`?{abstain:!1,outcome:{kind:`result`,value:`cancelled`}}:{abstain:!1,outcome:{kind:`result`,value:e?.optionId===`allow-once`?`allowed-once`:`rejected`}}}let n=t;return n?.action===`accept`?{abstain:!1,outcome:{kind:`result`,value:n.content??{}}}:{abstain:!1,outcome:{kind:`rejected`,error:{code:n?.action===`decline`?`ASK_DECLINED`:`ASK_ABORTED`,message:`ask_user_question ${n?.action===`decline`?`declined`:`cancelled`} by client`}}}}#a(e,t,n){let r=e.asked.get(t);r?.timer!==void 0&&this.#t.timers.clear(r.timer),e.asked.delete(t),this.#t.logger.debug(`answerer: member dropped (${e.eventId} conn=${t} ${n})`),e.state===`active`&&e.asked.size===0&&this.#o(e,`all members out (${n})`)}#o(e,t){e.state===`active`&&(e.state=`grace`,e.graceTimer=this.#t.timers.set(()=>{this.#c(e,e.kind===`elicitation`?{kind:`rejected`,error:{code:`ASK_ABORTED`,message:`ask_user_question grace window expired`}}:{kind:`result`,value:`cancelled`},`grace`)},N),this.#t.logger.info(`answerer: grace entered (${e.eventId} ${t})`))}#s(e){let t=P-(this.#t.now()-e.budgetStartedAt);if(t<=0){this.#c(e,e.kind===`elicitation`?{kind:`rejected`,error:{code:`ASK_ABORTED`,message:`ask_user_question form budget exhausted`}}:{kind:`result`,value:`cancelled`},`budget`);return}this.#t.timers.set(()=>{e.state!==`settled`&&(this.#t.logger.warn(`answerer: form budget exhausted (${e.eventId})`),this.#c(e,e.kind===`elicitation`?{kind:`rejected`,error:{code:`ASK_ABORTED`,message:`ask_user_question form budget exhausted`}}:{kind:`result`,value:`cancelled`},`budget`))},t)}#c(e,t,n){if(e.state!==`settled`){e.state=`settled`,e.settledOutcome=t,e.respondedBy=n,e.graceTimer!==void 0&&(this.#t.timers.clear(e.graceTimer),e.graceTimer=void 0);for(let t of e.asked.values())t.timer!==void 0&&this.#t.timers.clear(t.timer);e.asked.clear(),this.#l(e.eventId,t),this.#t.resolvedNotify(e.kind,{sessionId:e.sessionId,eventId:e.eventId,outcome:t,respondedBy:n},typeof n==`string`&&n!==`grace`&&n!==`turn`&&n!==`dispose`&&n!==`budget`?n:void 0),this.#t.logger.info(`answerer: settled (${e.eventId} by=${n} kind=${t.kind})`)}}async#l(e,t){try{await this.#t.respond(e,t)}catch(t){this.#t.logger.warn(`answerer: respond failed (${e}): ${t instanceof Error?t.message:String(t)}`)}}};function R(e,t,n){let{core:i,hooks:a,authenticate:o,logger:s}=n,c=new w(s,a),l=new r({noServer:!0}),u=new Set;return i.io.notify=async e=>{c.route(e)},i.io.extNotify=async e=>{c.routeExt(e)},e.on(`upgrade`,(e,n,r)=>{new URL(e.url??`/`,`http://localhost`).pathname===t&&(async()=>{if(!(o===void 0||await z(o,e,s))){n.write(`HTTP/1.1 401 Unauthorized\r
|
|
1
|
+
import{spawn as e}from"node:child_process";import{randomUUID as t}from"node:crypto";import n,{WebSocketServer as r}from"ws";import{MODE_TABLE as i,classify as a,isIgnorable as o}from"@tbox.cn/dsh-acp-bridge-core";var s=class extends Error{kind;report;constructor(e,t,n){super(t),this.name=`SupervisorDeploymentError`,this.kind=e,this.report=n}};function c(e){let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=`object`||!t||Array.isArray(t))return null;let n=t;return n.v===1&&(n.event===`standby`||n.event===`ready`&&typeof n.port==`number`&&typeof n.token==`string`)?t:null}async function l(e,t){let n=await fetch(`http://127.0.0.1:${e}/connect?token=${encodeURIComponent(t)}&interactions=answer`,{redirect:`manual`});if(n.status!==302)throw Error(`/connect 凭据交换期待 302,实得 ${n.status}(port ${e})`);let r=n.headers.get(`set-cookie`);if(r===null)throw Error(`/connect 凭据交换缺 Set-Cookie`);let i=r.split(`;`)[0]??``;if(i===``)throw Error(`/connect 凭据交换缺 Set-Cookie`);return i}function u(e){return e.replace(/((?:token|access_token|refresh_token|cookie|authorization)=)[^&\s]+/gi,`$1[REDACTED]`).replace(/((?:authorization|cookie):\s*)[^\n]+/gi,`$1[REDACTED]`)}var d=class{#e;#t;#n;#r;#i=`idle`;#a=[];#o;#s=!1;#c=!1;#l=0;#u=[];#d=[];#f=[];#p=[];#m;#h=0;#g=[];#_=!1;#v;constructor(e={},t,n){this.#e={startMode:`immediate`,readyTimeoutMs:12e4,backoffBaseMs:1e3,backoffMaxMs:5e3,maxRestartAttempts:3,ringBufferLines:1e3,...e},this.#t=t??f(e),this.#n=n??l,this.#r=e.log??(()=>{})}phase(){return this.#i}onPhaseChange(e){return this.#a.push(e),()=>{this.#a=this.#a.filter(t=>t!==e)}}onStderrLine(e){return this.#p.push(e),()=>{this.#p=this.#p.filter(t=>t!==e)}}async start(){if(this.#i!==`idle`)throw Error(`Supervisor.start 仅 idle 态可调(当前 ${this.#i})`);this.#T(),await this.#S()}async connect(){this.#b(),this.#s=!0,this.#i===`standby`&&!this.#c&&this.#e.startMode===`on-first-connection`&&this.#O(),this.#i!==`ready`&&await this.#S();let e=this.#m;if(e!==void 0&&e.generation===this.#h)return e;let t=this.#y;if(t===void 0)throw Error(`ready 凭据缺席(状态机时序违例)`);let n=await this.#n(t.port,t.token),r={baseUrl:`http://127.0.0.1:${t.port}`,cookie:n,port:t.port,generation:this.#h};return this.#m=r,this.#r(`凭据交换完成(generation ${this.#h},port ${t.port})`),r}async reconnect(){this.#b(),this.#i!==`ready`&&await this.#S();let e=this.#y;if(e===void 0)throw Error(`ready 凭据缺席(状态机时序违例)`);let t=await this.#n(e.port,e.token),n={baseUrl:`http://127.0.0.1:${e.port}`,cookie:t,port:e.port,generation:this.#h};return this.#m=n,this.#r(`凭据再交换完成(generation ${this.#h},port ${e.port})`),n}crashReport(){return[`phase=${this.#i} restarts=${this.#l} generation=${this.#h}`,`exitCodes=${JSON.stringify(this.#u)}`,`phaseHistory=${this.#d.join(` → `)}`,`stderr(环形缓冲尾部 ${this.#f.length} 行):`,...this.#f.map(e=>` ${e}`)].join(`
|
|
2
|
+
`)}async dispose(){if(this.#_)return;this.#_=!0,this.#v=void 0;let e=this.#o;e!==void 0&&(e.kill(`SIGTERM`),await new Promise(t=>{let n=setTimeout(()=>{e.kill(`SIGKILL`),t()},3e3);e.onExit(()=>{clearTimeout(n),t()})})),this.#w(Error(`Supervisor 已停机`)),this.#x(`disposed`)}#y;#b(){if(this.#_)throw Error(`Supervisor 已停机`);if(this.#i===`idle`)throw Error(`先调用 start()(connect 挂靠 spawn 生命周期)`);if(this.#v!==void 0)throw this.#v.error;if(this.#i===`failed-permanent`||this.#i===`failed-protocol`)throw new s(this.#i===`failed-permanent`?`permanent`:`protocol`,`Supervisor 终态 ${this.#i}`,this.crashReport())}#x(e){this.#i=e,this.#d.push(`${e}@${Date.now()}`),this.#a.forEach(t=>t(e))}#S(){return this.#i===`ready`?Promise.resolve():new Promise((e,t)=>{this.#g.push({generation:this.#h,resolve:e,reject:t})})}#C(){this.#g.splice(0).forEach(e=>e.resolve())}#w(e){this.#g.splice(0).forEach(t=>t.reject(e))}async#T(){for(;;){if(this.#_)return;if(await this.#D(),this.#v!==void 0){this.#x(this.#v.kind===`protocol`?`failed-protocol`:`failed-permanent`);return}return}}#E(e){if(this.#_)return;if(this.#l+=1,this.#l>this.#e.maxRestartAttempts){this.#v={kind:`permanent`,error:new s(`exhausted`,`崩溃退避序列耗尽(${this.#e.maxRestartAttempts} 次)——最后原因:${e}`,this.crashReport())},this.#x(`failed-permanent`),this.#w(this.#v.error);return}let t=Math.min(this.#e.backoffBaseMs*2**(this.#l-1),this.#e.backoffMaxMs);this.#x(`restarting`),this.#r(`瞬时失败(${e})——${t}ms 后第 ${this.#l} 次重启`),setTimeout(()=>{this.#_||this.#D().then(()=>{this.#v!==void 0&&(this.#x(this.#v.kind===`protocol`?`failed-protocol`:`failed-permanent`),this.#w(this.#v.error))})},t)}async#D(){this.#h+=1,this.#m=void 0,this.#c=!1,this.#y=void 0;let e=this.#h;this.#x(`booting`);let t=this.#e.command??[`tboxcode-dsh`],n=this.#t([...t,`server`]);this.#o=n;let r=!1,i;clearTimeout(i),i=setTimeout(()=>{this.#h!==e||this.#i===`ready`||(this.#r(`就绪确认超时——kill 子进程(瞬时面)`),n.kill(`SIGKILL`))},this.#e.readyTimeoutMs),n.onStdoutLine(t=>{if(this.#h!==e)return;let a=c(t);if(!r){if(a===null||a.event!==`standby`){this.#v={kind:`protocol`,error:new s(`protocol`,`首行校验失败(期待 standby 信封,实得 "${t.slice(0,80)}")`,this.crashReport())},this.#x(`failed-protocol`),this.#w(this.#v.error),n.kill(`SIGKILL`);return}r=!0,this.#x(`standby`),(this.#e.startMode===`immediate`||this.#s)&&this.#O();return}if(a===null){this.#i===`ready`&&this.#r(`stdout 违约(ready 后非静默): ${t.slice(0,120)}`),this.#k(`[stdout] ${t}`);return}a.event!==`standby`&&this.#i!==`ready`&&(this.#y=a,this.#x(`ready`),clearTimeout(i),this.#C())}),n.onStderrLine(t=>{if(this.#h!==e)return;let n=u(t);this.#k(n);for(let e of this.#p)try{e(n)}catch{}}),n.onExit(t=>{if(this.#h===e&&(clearTimeout(i),this.#u.push(t),!this.#_&&this.#v===void 0)){if(t===2){this.#v={kind:`permanent`,error:new s(`permanent`,`server 永久失败(退出码 2——config 非法 / 未设 model / profile 损坏)`,this.crashReport())},this.#x(`failed-permanent`),this.#w(this.#v.error);return}if(t===3){this.#v={kind:`protocol`,error:new s(`protocol`,`server 协议版本偏斜(退出码 3——部署错误最显眼信号)`,this.crashReport())},this.#x(`failed-protocol`),this.#w(this.#v.error);return}this.#E(`退出码 ${t??`signal`}`)}})}#O(){this.#c||this.#o===void 0||(this.#c=!0,this.#x(`starting`),this.#o.writeStdin(`${JSON.stringify({v:1,cmd:`start`})}\n`),this.#r(`start 已释放`))}#k(e){this.#f.push(`${Date.now()} ${e}`),this.#f.length>this.#e.ringBufferLines&&this.#f.splice(0,this.#f.length-this.#e.ringBufferLines)}};function f(t){return n=>{let r=e(n[0],n.slice(1),{stdio:[`pipe`,`pipe`,`pipe`],env:{...process.env,...t.env??{}}}),i=``,a=``,o=[],s=[],c=[],l=(e,t,n)=>{for(e+=t.toString();;){let t=e.indexOf(`
|
|
3
|
+
`);if(t<0)break;let r=e.slice(0,t);e=e.slice(t+1),n.forEach(e=>e(r))}return e};return r.stdout?.on(`data`,e=>{i=l(i,e.toString(),o)}),r.stderr?.on(`data`,e=>{a=l(a,e.toString(),s)}),r.on(`close`,e=>{i!==``&&o.forEach(e=>e(i)),a!==``&&s.forEach(e=>e(a)),c.forEach(t=>t(e))}),{writeStdin:e=>r.stdin?.write(e),onStdoutLine:e=>o.push(e),onStderrLine:e=>s.push(e),onExit:e=>c.push(e),kill:e=>r.kill(e??`SIGTERM`)}}}function p(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function m(e){return!p(e)||typeof e.type!=`string`||e.type===``||typeof e.seq!=`number`||!Number.isInteger(e.seq)||typeof e.time!=`number`||!(`data`in e)?null:e}function h(e){if(!p(e)||e.type!==`event`)return null;let t=m(e.event);return t===null?null:{type:`event`,event:t}}function g(e){if(!p(e))return null;if(e.type===`snapshot`){let t=p(e.header)?e.header:null;if(t===null||typeof e.cursor!=`number`||typeof e.hasMore!=`boolean`)return null;let n=[];if(Array.isArray(e.records))for(let t of e.records){let e=h(t);if(e===null)return null;n.push(e)}else return null;return{type:`snapshot`,header:t,cursor:e.cursor,records:n,hasMore:e.hasMore,projections:e.projections,...p(e.assistantStream)?{assistantStream:e.assistantStream}:{}}}return e.type===`assistant-stream`?p(e.frame)?{type:`assistant-stream`,frame:e.frame}:null:h(e)}function _(e){if(!p(e)||typeof e.hasMore!=`boolean`||!Array.isArray(e.records))return null;let t=[];for(let n of e.records){let e=h(n);if(e===null)return null;t.push(e)}return{records:t,hasMore:e.hasMore}}function v(e){return p(e)&&(e.type===`ready`&&typeof e.clientId==`string`&&p(e.host)||e.type===`emit`&&typeof e.event==`string`&&Array.isArray(e.args)||e.type===`waterfall`&&typeof e.eventId==`string`&&typeof e.agentId==`string`&&typeof e.event==`string`&&p(e.request)||e.type===`cancel`&&typeof e.eventId==`string`)?e:null}var y=class extends Error{code;details;constructor(e){super(e.message),this.name=`CarrierRpcError`,this.code=e.code,this.details=e.details}},b=class extends Error{constructor(e){super(e),this.name=`CarrierTransportError`}},x=class{#e;#t;#n;#r;#i;#a;#o=!1;#s=!1;constructor(e){this.#e=e.baseUrl.replace(/\/$/,``),this.#t=e.cookie,this.#n=e.refreshCredentials}async unary(e,t){this.#p();try{return await this.#c(e,t)}catch(n){if(!(n instanceof b&&n.message.endsWith(`HTTP 401`))||this.#n===void 0)throw n;return await this.#f(),this.#c(e,t)}}async#c(e,n){let r=t(),i;try{i=await fetch(`${this.#e}/api/${e}`,{method:`POST`,headers:{"content-type":`application/json`,cookie:this.#t},body:JSON.stringify({type:`client-request`,rpcId:r,method:e,payload:{args:n}}),signal:AbortSignal.timeout(6e4)})}catch(t){throw t instanceof Error&&t.name===`TimeoutError`?new b(`unary ${e} 超时(上游 60s 无响应)`):t}if(i.status!==200)throw new b(`unary ${e} HTTP ${i.status}`);let a=await i.json();if(a.type!==`server-response`||a.rpcId!==r)throw new b(`unary ${e} envelope 畸形(type/rpcId 失配)`);if(a.result.ok)return a.result.value;throw new y(a.result.error)}openStream(e,r,i){this.#p();let a=t(),o=!1,s={canceled:!1,onFrame:e=>{e.type===`item`?i.onItem(e.value):e.type===`end`?(s.canceled=!0,i.onEnd?.()):e.type===`error`&&(s.canceled=!0,i.onError?.(e.error??{code:`gateway/internal`,message:`stream error 帧缺 error 字段`}))},onDown:e=>{s.canceled||(s.canceled=!0,e&&i.onError?.({code:`carrier/mux-closed`,message:`mux 插座意外关闭`}),i.onClose?.(e))}};return this.#l().then(t=>{if(o||s.canceled){process.stderr.write(`[carrier] open ABORTED (canceled=${String(o)} entry=${String(s.canceled)}) ${e}\n`);return}t.streams.set(a,s),t.socket.readyState===n.OPEN?(t.socket.send(JSON.stringify({type:`open`,streamId:a,endpoint:e,payload:{args:r}})),process.env.CARRIER_WIRE_DEBUG===`1`&&process.stderr.write(`[carrier] open sent ${e} streamId=${a.slice(0,8)}\n`)):process.stderr.write(`[carrier] open SKIPPED (readyState ${t.socket.readyState}) ${e}\n`)}).catch(e=>{o||s.canceled||(s.canceled=!0,i.onError?.({code:`carrier/mux-open`,message:e.message}),i.onClose?.(!0))}),{cancel:()=>{o=!0,s.canceled=!0;let e=this.#r;e!==void 0&&e.streams.delete(a)&&e.socket.readyState===n.OPEN&&e.socket.send(JSON.stringify({type:`cancel`,streamId:a}))}}}async#l(){let e=this.#r;if(e!==void 0&&e.socket.readyState===n.OPEN)return e;if(this.#i!==void 0)return this.#i;let t=this.#u().finally(()=>{this.#i===t&&(this.#i=void 0)});return this.#i=t,t}async#u(){this.#p(),this.#o&&this.#n!==void 0&&await this.#f();let e=new n(`${S(this.#e)}/api/remote.mux`,{headers:{cookie:this.#t}});await new Promise((t,n)=>{let r=setTimeout(()=>n(new b(`mux 插座打开超时`)),15e3);r.unref(),e.once(`open`,()=>{clearTimeout(r),t()}),e.once(`error`,e=>{clearTimeout(r),n(new b(`mux 插座打开失败: ${e.message}`))}),e.once(`unexpected-response`,(e,t)=>{clearTimeout(r),n(new b(`mux 升级被拒 HTTP ${t.statusCode??`?`}`))})});let t={socket:e,streams:new Map};e.on(`message`,e=>{let n;try{n=JSON.parse(String(e))}catch{return}typeof n.streamId==`string`&&t.streams.get(n.streamId)?.onFrame(n)});let r=!1;return e.on(`close`,()=>this.#d(t,r)),e.on(`error`,()=>{r=!0}),this.#r=t,this.#o=!0,t}#d(e,t){if(this.#r===e){this.#r=void 0;for(let n of e.streams.values())n.onDown(t);e.streams.clear()}}#f(){if(this.#a!==void 0)return this.#a;let e=(async()=>{let e=this.#n;if(e===void 0)return;let t=await e();this.#t=t.cookie,this.#e=t.baseUrl.replace(/\/$/,``)})().finally(()=>{this.#a===e&&(this.#a=void 0)});return this.#a=e,e}openEvents(e){let t,n=n=>{switch(n.type){case`ready`:t=n.clientId,e.onReady(n);return;case`emit`:e.onEmit(n);return;case`waterfall`:e.onWaterfall(n);return;case`cancel`:e.onCancel(n);return}},r=this.openStream(`$events`,{},{onItem:t=>{let i=v(t);if(i===null){e.onClose?.(!1),r.cancel();return}n(i)},onClose:t=>e.onClose?.(t)});return{respond:async(e,n)=>{if(t===void 0)throw new b(`waterfall 应答先于 ready 帧(clientId 缺席)`);await this.unary(`$events/result`,{clientId:t,eventId:e,outcome:n})},close:()=>r.cancel()}}dispose(){this.#s=!0,this.#r?.socket.close(),this.#r=void 0}#p(){if(this.#s)throw new b(`carrier 已释放`)}};function S(e){if(e.startsWith(`https://`))return`wss://${e.slice(8)}`;if(e.startsWith(`http://`))return`ws://${e.slice(7)}`;throw new b(`baseUrl 非法(期待 http(s)://,实得 ${e})`)}function C(e,t){let n=m(e);if(n===null)return t!==void 0&&(t.invalid+=1),null;if(a(n.type)===`project`)return typeof n.data!=`object`||n.data===null||Array.isArray(n.data)?(t!==void 0&&(t.opaqueWarn+=1),{kind:`opaque`,event:n,level:`warn`}):(t!==void 0&&(t.consumable+=1),{kind:`consumable`,event:n});let r=o(n)?`debug`:`warn`;return r===`debug`?t!==void 0&&(t.opaqueDebug+=1):t!==void 0&&(t.opaqueWarn+=1),{kind:`opaque`,event:n,level:r}}var w=class{#e;#t;#n={invalid:0,opaqueDebug:0,opaqueWarn:0,consumable:0};#r=new Map;#i=0;constructor(e,t){this.#e=e,this.#t=t?.reopenBaseMs??1e3}open(e,t){let n=this.#r.get(e);if(n!==void 0&&!n.closed)return n.handlers=t,{close:()=>this.close(e)};let r={sessionId:e,handlers:t,handle:void 0,cursor:void 0,baseline:void 0,streamSeenRevision:!1,reopening:!1,backoffMs:this.#t,closed:!1,pending:[]};return this.#r.set(e,r),this.#a(r),{close:()=>this.close(e)}}close(e){let t=this.#r.get(e);t!==void 0&&(t.closed=!0,t.handle?.cancel(),this.#r.delete(e))}stats(){let e=0,t=0;for(let n of this.#r.values())n.closed||(n.reopening||n.cursor===void 0?t++:e++);return{live:e,reopening:t,decoded:{...this.#n},gapsRepaired:this.#i}}#a(e){e.closed||(e.reopening=e.cursor!==void 0,e.handle=this.#e.openStream(`session/follow`,{request:{address:{kind:`session`,sessionId:e.sessionId},assistantStream:!0}},{onItem:t=>this.#s(e,t),onEnd:()=>this.#o(e,`stream end`),onError:t=>this.#o(e,`${t.code}: ${t.message}`),onClose:t=>{t&&this.#o(e,`socket error`)}}))}#o(e,t){if(e.closed)return;e.handle=void 0,e.handlers.onDown(t);let n=e.backoffMs;e.backoffMs=Math.min(e.backoffMs*2,3e4),e.baseline=void 0,e.streamSeenRevision=!1,e.reopening=!0,setTimeout(()=>{e.closed||this.#a(e)},n)}#s(e,t){if(t.type===`snapshot`){this.#c(e,t);return}if(e.cursor!==void 0){if(e.reopening){e.pending.push(t);return}this.#d(e,t)}}#c(e,t){let n=e.cursor;if(n!==void 0&&t.cursor<n){e.handlers.onDown(`cursor 回退:${String(t.cursor)} < ${String(n)}`);return}e.baseline=t.assistantStream,e.streamSeenRevision=!1,e.reopening=!0,e.handlers.onSnapshot(t.header,t.cursor,t.projections,t.assistantStream),this.#l(e,t,n)}async#l(e,t,n){try{let r=[];if(n!==void 0&&t.records.length>0){let i=t.records[0]?.event.seq??t.cursor;i>n+1&&(r.push(...await this.#u(e,n+1,i)),this.#i+=r.length)}for(let e of t.records)r.push(e.event);for(let t of r)this.#f(e,t);let i=e.pending;e.pending=[],e.reopening=!1,e.cursor=t.cursor,e.backoffMs=this.#t;for(let t of i)this.#d(e,t)}catch(t){e.handlers.onDown(`backlog 补齐失败:${String(t)}`)}}async#u(e,t,n){let r=[],i=n;for(;i>t;){let n=_(await this.#e.unary(`session/page`,{request:{address:{kind:`session`,sessionId:e.sessionId},throughSeq:i-1,beforeSeq:t,maxMessages:200}}));if(n===null)throw new b(`session/page 帧畸形(records/hasMore 缺失)`);for(let e of n.records)r.push(e.event);let a=n.records[0]?.event.seq;if(a===void 0||a<=t||(i=a,!n.hasMore))break}return r.sort((e,t)=>e.seq-t.seq),r}#d(e,t){if(t.type===`assistant-stream`){if(!e.streamSeenRevision){e.streamSeenRevision=!0;let n=(e.baseline?.revision??-1)+1;if(e.baseline!==void 0&&t.frame.revision!==n){e.handlers.onDown(`assistant-stream 衔接断裂:revision ${String(t.frame.revision)} ≠ ${String(n)}`);return}}e.handlers.onAssistantStream(t.frame);return}t.type===`event`&&this.#f(e,t.event)}#f(e,t){let n=C(t,this.#n);n!==null&&n.kind===`consumable`&&e.handlers.onEvent(n.event)}async readAll(e){return await new Promise((t,n)=>{let r=new Map,i,a,o=!1,s=this.#e.openStream(`session/follow`,{request:{address:{kind:`session`,sessionId:e},assistantStream:!1}},{onItem:c=>{o||c.type===`snapshot`&&(o=!0,i=c.header,a=c.projections,s.cancel(),this.#p(e,c,r).then(e=>t({header:i,events:e,projections:a}),e=>n(e)))},onEnd:()=>{o||(o=!0,n(new b(`session/follow 在 snapshot 前关闭`)))},onError:e=>{o||(o=!0,n(new y(e)))}})})}async#p(e,t,n){let r=[];for(let e of t.records)r.push(e.event);let i=t.records.length>0?t.records[0]?.event.seq:void 0;for(;t.hasMore===!0;){let n=_(await this.#e.unary(`session/page`,{request:{address:{kind:`session`,sessionId:e},throughSeq:t.cursor,...i===void 0?{}:{beforeSeq:i},maxMessages:200}}));if(n===null)throw new b(`session/page 帧畸形(records/hasMore 缺失)`);for(let e of n.records)r.push(e.event);if(!n.hasMore||n.records.length===0)break;let a=n.records[0]?.event.seq;if(a===void 0||a===0)break;i=a}let a=new Map;for(let e of r)a.set(e.seq,e);let o=[...a.values()].sort((e,t)=>e.seq-t.seq);for(let e=0;e<o.length;e++){let t=o[e];if(t?.seq!==e)throw new y({code:`gateway/internal`,message:`journal 连续性断裂:位置 ${String(e)} 实得 seq ${String(t?.seq)}`});let r=C(t,this.#n);r?.kind===`consumable`&&n.set(t.seq,r.event)}return[...n.values()]}},T=class{#e=new Map;#t=new Map;#n=new Map;#r=new Map;#i;#a;#o=0;#s=0;constructor(e,t){this.#i=e,this.#a=t}attachConnection(e,t,n){this.#e.set(e,{connId:e,send:t,ctx:n})}detachConnection(e){this.#e.delete(e);for(let[t,n]of this.#t)n.delete(e),n.size===0&&this.#t.delete(t),this.#a?.onSessionUnbind?.(e,t);for(let[t,n]of this.#n)n===e&&this.#n.delete(t)}bind(e,t){let n=this.#t.get(t);n===void 0&&(n=new Set,this.#t.set(t,n));let r=n.has(e);n.add(e),r||this.#a?.onSessionBind?.(e,t)}unbind(e,t){this.#t.get(t)?.delete(e),this.#a?.onSessionUnbind?.(e,t)}boundConnIds(e){return[...this.#t.get(e)??[]]}ctxOf(e){return this.#e.get(e)?.ctx}routeResolved(e,t,n){this.routeExt({method:e,payload:t},n===void 0?void 0:{excludeConnId:n})}beginReplayCount(e){this.#r.set(e,0)}takeReplayCount(e){let t=this.#r.get(e);return this.#r.delete(e),t}setTurnOrigin(e,t){this.#n.set(e,t)}clearTurnOrigin(e){this.#n.delete(e)}route(e){let t=e.sessionId,n;if(t===void 0)n=[...this.#e.keys()];else{let r=this.#n.get(t),i=e.update?.sessionUpdate===`user_message_chunk`;n=[...this.#t.get(t)??[]],r!==void 0&&i&&(n=n.filter(e=>e!==r),this.#s++);let a=this.#a?.fanout===void 0?void 0:E(this.#i,`fanout`,()=>this.#a?.fanout?.(e,n));if(a!==void 0&&(n=[...a]),n.length===0){this.#o++;return}}for(let t of n){let n=this.#e.get(t);if(n===void 0)continue;let r=e;if(this.#a?.transformOutbound!==void 0){let t=E(this.#i,`transformOutbound`,()=>this.#a?.transformOutbound?.(e,n.ctx));if(t===null)continue;t!==void 0&&(r=t)}n.send({jsonrpc:`2.0`,method:`session/update`,params:r});let i=this.#r.get(t);i!==void 0&&this.#r.set(t,i+1)}}routeExt(e,t){let n=typeof e.payload.sessionId==`string`?e.payload.sessionId:void 0,r=n===void 0?[...this.#e.keys()]:[...this.#t.get(n)??[]];t?.excludeConnId!==void 0&&(r=r.filter(e=>e!==t.excludeConnId));for(let t of r)this.#e.get(t)?.send({jsonrpc:`2.0`,method:e.method,params:e.payload})}stats(){return{connections:this.#e.size,dropped:this.#o,suppressed:this.#s}}};function E(e,t,n){try{return n()}catch(n){e.warn(`gateway hook ${t} failed (fail-open): ${String(n)}`);return}}const D=1e3,O=3e4;function k(e){return{id:e.id,get header(){let t=e.header;return{...t?.cwd===void 0?{}:{cwd:t.cwd},...t?.origin===void 0?{}:{origin:t.origin},...t?.parentSession===void 0?{}:{parentSession:t.parentSession},...t?.createdAt===void 0?{}:{createdAt:t.createdAt}}},requestHeader(){let t=e.projections?.modelSelection,n=t?.pending??t?.lastUsed;if(!(n==null||typeof n.provider!=`string`||typeof n.model!=`string`))return{config:{provider:n.provider,model:n.model,...typeof n.reasoningEffort==`string`?{reasoningEffort:n.reasoningEffort}:{}}}}}}function A(e,t,n){return{id:e.id,session:e.session,cancel:async n=>{await t.unary(`session/cancel`,{request:{sessionId:e.id}})},followup:t=>{n(e,t)}}}var j=class{logger;#e;#t;#n;#r=new Map;#i=new Set;#a=new Set;#o=new Set;#s=new Set;#c=new Set;#l;#u=D;#d;#f=D;#p;#m={groups:[],failures:[]};#h=0;#g;constructor(e){this.#e=e.carrier,this.#t=e.pool,this.#n=e.logger,this.logger=e.logger,this.#S(),this.#w(),this.#E()}async createAgent(e){return await this.#_(e)}async resumeAgent(e){return await this.#_(e)}async#_(e){let t=(await this.#e.unary(`session/create`,{request:{sessionId:e.sessionId,cwd:e.cwd}})).sessionId,n=this.#r.get(t);if(n!==void 0)return await e.configureScope?.(this.#y(n),n.agent),{agent:n.agent,dispose:async()=>this.#v(t)};let r={id:t,header:{version:1,id:t,createdAt:0,cwd:e.cwd,isSeeded:!1},projections:{},selectionProbe:void 0,lastPushedSelection:void 0,promptInflight:!1};r.session=k(r),r.agent=A(r,this.#e,(e,t)=>this.#b(e,t));let i=r;return this.#r.set(t,i),await e.configureScope?.(this.#y(i),i.agent),this.#t.open(t,this.#C(i)),{agent:i.agent,dispose:async()=>this.#v(t)}}#v(e){return this.#t.close(e),this.#r.delete(e),Promise.resolve()}#y(e){return{on:(t,n)=>(t===`agent/request`&&(e.selectionProbe=n),()=>{}),tools:{restrict:e=>void 0}}}async#b(e,t){if(e.promptInflight=!0,e.selectionProbe!==void 0)try{let t=await e.selectionProbe(void 0,async()=>({}));if(typeof t.provider==`string`&&typeof t.model==`string`){let n=JSON.stringify([t.provider,t.model,t.reasoningEffort]);n!==e.lastPushedSelection&&(await this.#e.unary(`session/selectModel`,{request:{sessionId:e.id,provider:t.provider,model:t.model,...typeof t.reasoningEffort==`string`?{reasoningEffort:t.reasoningEffort}:{}}}),e.lastPushedSelection=n)}}catch(e){this.#n.debug(`selection probe failed: ${String(e)}`)}await this.#e.unary(`session/prompt`,{request:{requestId:t.id,sessionId:e.id,mode:`steer`,content:t.content}})}persistence={stat:async(e,t)=>{let n=await this.#e.unary(`tboxcode/sessions.stat`,{request:{sessionId:e}});if(n!==null)return{header:n.header}},list:async e=>(await this.#e.unary(`session/list`,{_request:{}})).items.map(e=>({header:{id:e.sessionId,...e.cwd===void 0?{}:{cwd:e.cwd},...e.origin===void 0?{}:{origin:e.origin},...e.parentSessionId===void 0?{}:{parentSession:e.parentSessionId},createdAt:e.updatedAt}})),openHistoryRead:async(e,t)=>{let n=await this.#t.readAll(e);return{read:async()=>({events:n.events}),close:async()=>{}}}};sessionStore={get:e=>this.#r.get(e)?.session,flush:async e=>{await this.#e.unary(`tboxcode/sessions.flush`,{request:{sessionId:e.id}})}};llm={listProviders:()=>this.#x().groups.map(e=>({id:e.id,name:e.name})),listModels:async e=>(this.#x().groups.find(t=>t.id===e)?.models??[]).map(e=>({id:String(e.id),name:String(e.name),...e.description===void 0?{}:{description:String(e.description)}})),resolveModelInfo:async(e,t)=>{let n=this.#x().groups.find(t=>t.id===e)?.models.find(e=>e.id===t)?.reasoning;return{reasoning:{defaultEffort:n?.defaultEffort,efforts:n?.efforts??[]}}},resolveCallConfig:async e=>e};#x(){return Date.now()-this.#h>3e4&&this.#S(),this.#m}async#S(){try{this.#m=await this.#e.unary(`session/modelCatalog`,{}),this.#h=Date.now();let e=await this.#e.unary(`tboxcode/selection.default`,{});this.#g=typeof e.provider==`string`&&typeof e.model==`string`?{provider:e.provider,model:e.model,...e.reasoningEffort===void 0?{}:{reasoningEffort:e.reasoningEffort}}:void 0}catch(e){this.#n.warn(`catalog warm failed: ${String(e)}`)}}applyModeKnobs(e,t,n){let r=Object.entries(i).find(([,e])=>e.sandbox===n.sandbox&&e.approval===n.approval)?.[0];if(r===void 0)throw Error(`tboxcode: mode knobs 无对位(${String(n.sandbox)}/${String(n.approval)}——MODE_TABLE 外组合)`);return this.#e.unary(`tboxcode/mode`,{request:{agentId:e.id,mode:r}}).then(()=>void 0)}defaultSelection(){return this.#g}async executeCommand(e,t,n){let r=await this.#e.unary(`tboxcode/commands.execute`,{request:{agentId:e.id,line:t}});return r?.commandId===void 0?void 0:{commandId:r.commandId}}async listCommands(e){return await this.#e.unary(`tboxcode/commands.list`,{request:{agentId:e.id}})}async listUserInvocableSkills(e){return await this.#e.unary(`tboxcode/skills.userInvocable`,{request:{agentId:e.id}})}onSessionEvent(e){let t=e;return this.#i.add(t),()=>this.#i.delete(t)}onAssistantStream(e){return this.#a.add(e),()=>this.#a.delete(e)}onInboxClaimed(e){return this.#o.add(e),()=>this.#o.delete(e)}onAgentError(e){return this.#s.add(e),()=>this.#s.delete(e)}sessionToolDenies(){return[]}onCommandSurfaceChanged(e){return this.#c.add(e),()=>this.#c.delete(e)}sessionIds(){return[...this.#r.keys()]}hasInflightPrompt(e){return this.#r.get(e)?.promptInflight===!0}poolLive(){return this.#t.stats().live>0}poolEntries(){return this.#r.size}settlePrompt(e,t){let n=this.#r.get(e);if(!(n===void 0||!n.promptInflight)){n.promptInflight=!1;for(let e of this.#s)e({agent:n.agent,turn:0,error:t})}}#C(e){return{onSnapshot:(t,n,r)=>{e.header=t,e.projections=r},onEvent:t=>{t.type===`turn/end`&&(e.promptInflight=!1);for(let n of this.#i)n(e.session,t)},onAssistantStream:t=>{let n={type:t.type??(t.finish===void 0?t.index===0?`start`:`chunk`:`end`),attemptId:t.attemptId,...t.turn===void 0?{}:{turn:t.turn},...t.step===void 0?{}:{step:t.step},...t.chunk===void 0?{}:{chunk:t.chunk}};for(let t of this.#a)t({agent:e.agent,frame:n})},onDown:t=>this.#n.warn(`follow pool down (${e.id}): ${t}`)}}#w(){this.#l=this.#e.openStream(`tboxcode/agent.watch`,{},{onItem:e=>{this.#n.debug(`agent.watch item: ${JSON.stringify(e).slice(0,160)} states=${[...this.#r.keys()].join(`,`)}`);let t=this.#r.get(e.sessionId);if(t!==void 0){if(e.kind===`inboxClaimed`)for(let n of this.#o)n({agent:t.agent,message:{...e.messageId===void 0?{}:{id:e.messageId}},turn:e.turn??0});else if(e.kind===`error`)for(let n of this.#s)n({agent:t.agent,turn:0,error:e.error??`unknown agent error`})}},onError:e=>{this.#n.warn(`agent.watch stream error: ${JSON.stringify(e).slice(0,200)}`),this.#T()},onClose:e=>{e&&(this.#n.warn(`agent.watch stream closed`),this.#T())}})}#T(){let e=this.#u;this.#u=Math.min(this.#u*2,O),setTimeout(()=>{this.#w(),this.#u=D},e)}#E(){let e=()=>{for(let e of this.#c)e()};this.#d=M(this.#e,e,this.#n),this.#p=this.#e.openStream(`tboxcode/skills.watch`,{},{onItem:()=>e(),onError:()=>this.#D(),onClose:e=>{e&&this.#D()}})}#D(){let e=this.#f;this.#f=Math.min(this.#f*2,O),setTimeout(()=>{this.#E(),this.#f=D},e)}dispose(){this.#l?.cancel(),this.#d?.close(),this.#p?.cancel()}};function M(e,t,n){return e.openEvents({onReady:()=>n.debug(`commands/change $events ready`),onEmit:e=>{e.event===`commands/change`&&t()},onWaterfall:()=>{},onCancel:()=>{},onClose:e=>{e&&n.warn(`commands/change $events closed with error`)}})}var N=class{#e;#t;#n;#r;#i;#a;#o=!1;#s;constructor(e,t){this.#e=e,this.#t=t?.timeoutMs??12e4,this.#n=t?.tickMs??1e3,this.#r=t?.now??Date.now,this.#i=t?.logger??{warn:()=>{},info:()=>{},debug:()=>{}}}start(){this.#s=setInterval(()=>this.tick(),this.#n)}stop(){this.#s!==void 0&&clearInterval(this.#s),this.#s=void 0}tick(){if(!(this.#e.poolEntries()>0&&!this.#e.poolLive())){this.#a=void 0,this.#o=!1;return}if(this.#a===void 0){this.#a=this.#r();return}if(this.#o||this.#r()-this.#a<this.#t)return;this.#o=!0;let e=this.#r()-this.#a;for(let t of this.#e.sessionIds())this.#e.hasInflightPrompt(t)&&(this.#i.warn(`carrier timeout settle (${t}): downMs=${String(e)}`),this.#e.settle(t,Error(`tboxcode carrier-timeout (downMs=${String(e)})`)))}snapshot(){return{down:this.#a!==void 0,downSince:this.#a,settled:this.#o}}};const P=6e4,F=36e5,I=3e4,L=-32001;var R=class{#e=new Map;#t;constructor(e){this.#t=e}get size(){return this.#e.size}pendingOf(e){for(let t of this.#e.values())if(t.sessionId===e)return t}begin(e){let t=e.event===`user-questions/request`?`elicitation`:e.event===`approval/request`?`permission`:void 0;if(t===void 0||this.#e.has(e.eventId))return;let n=this.#t.sessionIdOfAgent(e.agentId);if(n===void 0){this.#l(e.eventId,{kind:`rejected`,error:{code:`gateway/agent-not-found`,message:`agent ${e.agentId} not managed by gateway`}});return}let r={kind:t,sessionId:n,eventId:e.eventId,frame:e,asked:new Map,state:`active`,budgetStartedAt:this.#t.now()};this.#e.set(e.eventId,r),this.#n(r),this.#s(r)}cancel(e){let t=this.#e.get(e.eventId);t===void 0||t.state===`settled`||this.#c(t,{kind:`result`,value:`cancelled`},`turn`)}attach(e,t){for(let n of this.#e.values()){if(n.sessionId!==t||n.state!==`grace`)continue;let r=n.graceTimer;n.graceTimer=void 0,r!==void 0&&this.#t.timers.clear(r),n.state=`active`,this.#t.logger.info(`answerer: grace broken by attach (${n.eventId} conn=${e})`),this.#n(n)}}switchBack(e,t){this.attach(e,t)}disconnect(e){for(let t of this.#e.values())t.asked.delete(e)&&t.state===`active`&&t.asked.size===0&&this.#o(t,`member disconnected`)}dispose(){for(let e of[...this.#e.values()])e.state!==`settled`&&this.#c(e,{kind:`result`,value:`cancelled`},`dispose`);this.#e.clear()}#n(e){let t=this.#t.eligibleConns(e.sessionId).filter(t=>!e.asked.has(t)).filter(t=>e.kind===`permission`||this.#t.capsOf(t));if(t.length===0){this.#o(e,`no eligible connections`);return}for(let n of t){let t={connId:n};e.kind===`permission`&&(t.timer=this.#t.timers.set(()=>{e.state!==`active`||!e.asked.has(n)||(e.asked.delete(n),this.#t.logger.info(`answerer: member timeout (${e.eventId} conn=${n})`),e.asked.size===0&&this.#o(e,`all members timed out`))},I)),e.asked.set(n,t),this.#r(e,n)}}async#r(e,t){let n=e.kind===`elicitation`?this.#t.buildQuestionParams(e.sessionId,e.frame):{callId:e.frame.request.callId};try{let r=await this.#t.dispatch(t,e.kind,n);if(e.state===`settled`||!e.asked.has(t))return;let i=this.#i(e,r);if(i.abstain){this.#a(e,t,`abstained`);return}this.#c(e,i.outcome,t)}catch(n){if(e.state===`settled`||!e.asked.has(t))return;if(n.code===L){this.#a(e,t,`abstained`);return}this.#t.logger.warn(`answerer: dispatch failed (${e.eventId} conn=${t}): ${n instanceof Error?n.message:String(n)}`),this.#a(e,t,`dispatch failed`)}}#i(e,t){if(e.kind===`permission`){let e=t?.outcome;return e?.outcome===`cancelled`?{abstain:!1,outcome:{kind:`result`,value:`cancelled`}}:{abstain:!1,outcome:{kind:`result`,value:e?.optionId===`allow-once`?`allowed-once`:`rejected`}}}let n=t;return n?.action===`accept`?{abstain:!1,outcome:{kind:`result`,value:n.content??{}}}:{abstain:!1,outcome:{kind:`rejected`,error:{code:n?.action===`decline`?`ASK_DECLINED`:`ASK_ABORTED`,message:`ask_user_question ${n?.action===`decline`?`declined`:`cancelled`} by client`}}}}#a(e,t,n){let r=e.asked.get(t);r?.timer!==void 0&&this.#t.timers.clear(r.timer),e.asked.delete(t),this.#t.logger.debug(`answerer: member dropped (${e.eventId} conn=${t} ${n})`),e.state===`active`&&e.asked.size===0&&this.#o(e,`all members out (${n})`)}#o(e,t){e.state===`active`&&(e.state=`grace`,e.graceTimer=this.#t.timers.set(()=>{this.#c(e,e.kind===`elicitation`?{kind:`rejected`,error:{code:`ASK_ABORTED`,message:`ask_user_question grace window expired`}}:{kind:`result`,value:`cancelled`},`grace`)},P),this.#t.logger.info(`answerer: grace entered (${e.eventId} ${t})`))}#s(e){let t=F-(this.#t.now()-e.budgetStartedAt);if(t<=0){this.#c(e,e.kind===`elicitation`?{kind:`rejected`,error:{code:`ASK_ABORTED`,message:`ask_user_question form budget exhausted`}}:{kind:`result`,value:`cancelled`},`budget`);return}this.#t.timers.set(()=>{e.state!==`settled`&&(this.#t.logger.warn(`answerer: form budget exhausted (${e.eventId})`),this.#c(e,e.kind===`elicitation`?{kind:`rejected`,error:{code:`ASK_ABORTED`,message:`ask_user_question form budget exhausted`}}:{kind:`result`,value:`cancelled`},`budget`))},t)}#c(e,t,n){if(e.state!==`settled`){e.state=`settled`,e.settledOutcome=t,e.respondedBy=n,e.graceTimer!==void 0&&(this.#t.timers.clear(e.graceTimer),e.graceTimer=void 0);for(let t of e.asked.values())t.timer!==void 0&&this.#t.timers.clear(t.timer);e.asked.clear(),this.#l(e.eventId,t),this.#t.resolvedNotify(e.kind,{sessionId:e.sessionId,eventId:e.eventId,outcome:t,respondedBy:n},typeof n==`string`&&n!==`grace`&&n!==`turn`&&n!==`dispose`&&n!==`budget`?n:void 0),this.#t.logger.info(`answerer: settled (${e.eventId} by=${n} kind=${t.kind})`)}}async#l(e,t){try{await this.#t.respond(e,t)}catch(t){this.#t.logger.warn(`answerer: respond failed (${e}): ${t instanceof Error?t.message:String(t)}`)}}};function z(e,t){e.gate.active||(e.gate.active=!0,e.gate.timer=setTimeout(()=>{e.gate.active&&(t.warn(`gateway load gate timeout (${e.connId})——释放缓存帧`),B(e,!0))},3e4),e.gate.timer.unref?.())}function B(e,t){if(!e.gate.active)return[];e.gate.active=!1,e.gate.timer!==void 0&&clearTimeout(e.gate.timer),e.gate.timer=void 0;let n=t?e.gate.frames.splice(0):[];return e.gate.frames.length=0,n}function V(e,t){e.socket.readyState===e.socket.OPEN&&e.socket.send(JSON.stringify(t))}function H(e,t,n){let{core:i,hooks:a,authenticate:o,logger:s}=n,c=new T(s,a),l=new r({noServer:!0}),u=new Set;return i.io.notify=async e=>{c.route(e)},i.io.extNotify=async e=>{c.routeExt(e)},e.on(`upgrade`,(e,n,r)=>{new URL(e.url??`/`,`http://localhost`).pathname===t&&(async()=>{if(!(o===void 0||await U(o,e,s))){n.write(`HTTP/1.1 401 Unauthorized\r
|
|
4
4
|
\r
|
|
5
|
-
`),n.destroy();return}l.handleUpgrade(e,n,r,e=>{
|
|
5
|
+
`),n.destroy();return}l.handleUpgrade(e,n,r,e=>{W(e,i,a,c,s,u)})})().catch(e=>{s.warn(`gateway upgrade failed: ${String(e)}`),n.destroy()})}),{close:()=>{for(let e of u)e.socket.close();l.close()},boundConnIds:e=>c.boundConnIds(e),ctxOf:e=>c.ctxOf(e),routeResolved:(e,t,n)=>c.routeResolved(e,t,n)}}async function U(e,t,n){try{return await e(t)}catch(e){return n.warn(`gateway authenticate failed: ${String(e)}`),!1}}function W(e,n,r,i,a,o){let s=t(),c={elicitation:!1},l={active:!1,frames:[],timer:void 0},u=t=>{if(l.active){l.frames.push(t);return}e.readyState===e.OPEN&&e.send(JSON.stringify(t))},d={connId:s,get caps(){return c},request:async(e,t)=>{throw Error(`tboxcode: server→client request 面直通由 attach 后覆写(answerer 切片消费)`)},notify:async(e,t)=>{u({jsonrpc:`2.0`,method:e,params:t})}};i.attachConnection(s,u,d);let f=new TransformStream,p=f.writable.getWriter(),m={writable:new WritableStream({write:e=>{G(e,g,i,u)}}),readable:f.readable},h=n.attachConnection(m,{beforePrompt:e=>i.setTurnOrigin(e,s),afterPrompt:e=>i.clearTurnOrigin(e)}),g={connId:s,socket:e,conn:h,ctx:d,pending:new Map,get caps(){return c},gate:l};d.request=(e,t)=>h.client.request(e,t),o.add(g),e.on(`message`,e=>{let t=typeof e==`string`?e:Buffer.isBuffer(e)?e.toString(`utf8`):void 0;if(t===void 0)return;let o;try{o=JSON.parse(t)}catch{u({jsonrpc:`2.0`,id:null,error:{code:-32700,message:`Parse error`}});return}K(o,g,p,n,r,i,a)}),e.on(`close`,()=>{o.delete(g),i.detachConnection(s),p.close().catch(()=>{}),a.debug(`gateway connection detached (${s})`)}),e.on(`error`,e=>{a.warn(`gateway socket error (${s}): ${String(e)}`)})}function G(e,t,n,r){if(e.method===void 0&&e.id!==void 0){let r=t.pending.get(String(e.id));if(r!==void 0){t.pending.delete(String(e.id));let i=r.method===`session/load`,a=e.error===void 0;if(a){let i=e.result?.sessionId??r.params?.sessionId;r.method===`session/close`?i!==void 0&&n.unbind(t.connId,i):i!==void 0&&n.bind(t.connId,i)}else if(r.prebound){let e=r.params?.sessionId;e!==void 0&&n.unbind(t.connId,e)}if(i){let n=B(t,a);if(V(t,e),a)for(let e of n)V(t,e);return}}}r(e)}async function K(e,t,n,r,i,a,o){let s=e.method;if(s===void 0){await n.write(e);return}if(s===`initialize`){let n=e.params?.clientCapabilities;t.caps.elicitation=n?.elicitation!=null}if(s.startsWith(`_tbox.cn/`)){let n=i?.methods?.[s];if(e.id===void 0)return;if(n===void 0){t.socket.send(JSON.stringify({jsonrpc:`2.0`,id:e.id,error:{code:-32601,message:`Method not found: ${s}`}}));return}try{let r=await n(e.params,t.ctx);t.socket.send(JSON.stringify({jsonrpc:`2.0`,id:e.id,result:r??{}}))}catch(n){t.socket.send(JSON.stringify({jsonrpc:`2.0`,id:e.id,error:{code:-32603,message:n instanceof Error?n.message:String(n)}}))}return}if(i?.transformInbound!==void 0&&e.id!==void 0){let n;try{n=await i.transformInbound(s,e.params,t.ctx)}catch(t){o.warn(`gateway hook transformInbound failed (fail-open): ${String(t)}`),n=e.params}if(n===null){t.socket.send(JSON.stringify({jsonrpc:`2.0`,id:e.id,error:{code:-32602,message:`Invalid params: ${s} rejected by gateway`}}));return}e.params=n}if(s===`session/load`&&e.id!==void 0){let n=e.params?.sessionId,s=e.params?.cwd;if(n!==void 0&&s!==void 0&&r.hasSession(n)){a.bind(t.connId,n),z(t,o);try{let a=await r.joinSession({sessionId:n,cwd:s});V(t,{jsonrpc:`2.0`,id:e.id,result:{configOptions:a.configOptions}});for(let e of a.updates){let r=e;if(i?.transformOutbound!==void 0){let n;try{n=i.transformOutbound(e,t.ctx)}catch(t){o.warn(`gateway hook transformOutbound failed (fail-open): ${String(t)}`),n=e}if(n===null)continue;r=n}V(t,{jsonrpc:`2.0`,method:`session/update`,params:{sessionId:n,update:r}})}V(t,{jsonrpc:`2.0`,method:`_tbox.cn/acp_replay_complete`,params:{sessionId:n,notificationCount:a.updates.length}});for(let e of B(t,!0))V(t,e)}catch(r){B(t,!1),a.unbind(t.connId,n),V(t,{jsonrpc:`2.0`,id:e.id,error:{code:-32603,message:r instanceof Error?r.message:String(r)}})}return}}if((s===`session/new`||s===`session/load`||s===`session/resume`||s===`session/close`)&&e.id!==void 0){let n=!1;if(s===`session/load`){let r=e.params?.sessionId;r!==void 0&&!a.boundConnIds(r).includes(t.connId)&&(a.bind(t.connId,r),n=!0),z(t,o),a.beginReplayCount(t.connId)}if(t.pending.set(String(e.id),{method:s,params:e.params,prebound:n}),s===`session/close`){let n=e.params?.sessionId;n!==void 0&&a.unbind(t.connId,n)}}if(await n.write(e),s===`session/close`&&e.id===void 0){let n=e.params?.sessionId;n!==void 0&&a.unbind(t.connId,n)}}async function q(e,t,n,r){try{return await n()}catch(n){return e.warn(`gateway hook ${t} failed (fail-open): ${String(n)}`),r}}const J=`@tbox.cn/tboxcode-dsh-sdk`;export{L as ABSTAIN_RPC_ERROR,y as CarrierRpcError,b as CarrierTransportError,x as DshCarrier,F as FORM_BUDGET_MS,T as FanoutRouter,w as FollowPool,P as GRACE_WINDOW_MS,R as InteractionRegistry,N as InterruptionMonitor,J as PACKAGE_NAME,I as PERMISSION_MEMBER_TIMEOUT_MS,j as RpcSessionDeps,d as Supervisor,s as SupervisorDeploymentError,H as attachAcpGateway,C as decodeWireEvent,l as exchangeCredentialsViaConnect,p as isRecord,M as openCommandsChangeEventStream,v as parseWireEventFrame,g as parseWireFollowFrame,h as parseWireHistoryRecord,_ as parseWirePage,m as parseWireSessionEvent,q as runHookOpen};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tbox.cn/tboxcode-dsh-sdk",
|
|
3
|
-
"version": "0.1.0-rc.
|
|
3
|
+
"version": "0.1.0-rc.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AcpGateway 扩展点 + Supervisor + 直连 RPC 面(薄 carrier:POST envelope + WS mux + /connect 凭据交换,运行时零 dsh 包依赖)+ 上链 ACP server 面 + wire 契约与 decodeWireEvent;agtcodingbox 唯一依赖面",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"ws": "^8.19.0",
|
|
19
|
-
"@tbox.cn/dsh-acp-bridge-core": "0.1.0-rc.
|
|
20
|
-
"@tbox.cn/dsh-acp-full": "0.1.0-rc.
|
|
19
|
+
"@tbox.cn/dsh-acp-bridge-core": "0.1.0-rc.5",
|
|
20
|
+
"@tbox.cn/dsh-acp-full": "0.1.0-rc.5"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@types/ws": "^8.18.1",
|